1 package jfun.yan.spring; 2 3 import java.util.Properties ; 4 5 import org.springframework.beans.factory.BeanFactoryAware; 6 import org.springframework.beans.factory.BeanNameAware; 7 import org.springframework.beans.factory.DisposableBean; 8 import org.springframework.beans.factory.FactoryBean; 9 import org.springframework.beans.factory.InitializingBean; 10 import org.springframework.beans.factory.config.BeanPostProcessor; 11 import org.springframework.context.ApplicationContext; 12 import org.springframework.context.ApplicationContextAware; 13 import org.springframework.context.ApplicationEventPublisherAware; 14 import org.springframework.context.MessageSourceAware; 15 import org.springframework.context.ResourceLoaderAware; 16 import org.springframework.transaction.PlatformTransactionManager; 17 import org.springframework.transaction.interceptor.TransactionProxyFactoryBean; 18 19 import jfun.yan.Component; 20 import jfun.yan.Components; 21 import jfun.yan.Container; 22 import jfun.yan.Map; 23 import jfun.yan.Map3; 24 import jfun.yan.Monad; 25 import jfun.yan.Mutation; 26 import jfun.yan.factory.ThreadLocalScope; 27 import jfun.yan.xml.NutsUtils; 28 import jfun.yan.xml.SingletonMode; 29 30 31 32 38 public class SpringAdapter { 39 40 private static Object injectFactoryBeanResult(final SpringContext ctxt, Object obj) 41 throws ClassNotFoundException , Exception { 42 if(obj instanceof FactoryBean){ 44 obj = ((FactoryBean)obj).getObject(); 45 } 48 return obj; 49 } 50 private static Map3 getFactoryBeanMap3(final SpringContext ctxt, 51 final String [] itfs){ 52 return new Map3(){ 53 public Object map(Object tx, Object attrs, Object obj) 54 throws Exception { 55 final PlatformTransactionManager man =(PlatformTransactionManager)tx; 56 final Properties tattrs = (Properties )attrs; 57 final Object r = injectFactoryBeanResult(ctxt, obj); 58 return proxyTransaction(r, ctxt, man, tattrs, itfs); 59 } 60 }; 61 } 62 63 private static Map getFactoryBeanMap(final SpringContext ctxt){ 64 return new Map(){ 65 public Object map(Object obj) 66 throws Exception { 67 return injectFactoryBeanResult(ctxt, obj); 68 } 69 }; 70 } 71 private static Mutation getBeanMutation(final SpringContext ctxt){ 72 return new Mutation(){ 73 public void mutate(Object obj) 74 throws Exception { 75 injectBasicBean(obj, ctxt); 76 } 77 }; 78 } 79 96 public static Object injectBean(Object obj, SpringContext ctxt, 97 PlatformTransactionManager transaction_manager, 98 Properties transaction_attributes, String [] interfaces) 99 throws Exception { 100 injectBasicBean(obj, ctxt); 101 return proxyTransaction(obj, ctxt, 102 transaction_manager, transaction_attributes, interfaces); 103 } 104 private static void injectApplicationContext(Object obj, ApplicationContext actxt){ 105 if(obj instanceof ApplicationContextAware){ 106 ((ApplicationContextAware)obj).setApplicationContext(actxt); 107 } 108 else{ 109 if(obj instanceof BeanFactoryAware){ 110 ((BeanFactoryAware)obj).setBeanFactory(actxt); 111 } 112 113 if(obj instanceof ResourceLoaderAware){ 114 ((ResourceLoaderAware)obj).setResourceLoader(actxt); 115 } 116 if(obj instanceof ApplicationEventPublisherAware){ 117 ((ApplicationEventPublisherAware)obj).setApplicationEventPublisher(actxt); 118 } 119 if(obj instanceof MessageSourceAware){ 120 ((MessageSourceAware)obj).setMessageSource(actxt); 121 } 122 } 123 } 124 136 private static void injectBasicBean(Object obj, SpringContext ctxt) 137 throws Exception { 138 if(ctxt.isGloballyDefined()){ 139 final String id = ctxt.getId(); 141 if(id!=null && obj instanceof BeanNameAware){ 142 ((BeanNameAware)obj).setBeanName(id); 143 } 144 } 145 injectApplicationContext(obj, ctxt.getApplicationContext()); 146 147 initBean(obj, ctxt); 148 } 149 private static void initBean(Object obj, SpringContext ctxt) 150 throws Exception { 151 final Object original = obj; 152 if(obj instanceof InitializingBean){ 154 ((InitializingBean)obj).afterPropertiesSet(); 155 } 156 if(original instanceof DisposableBean){ 159 final DisposableBean db = (DisposableBean)original; 160 ctxt.manageDisposableBean(db); 161 } 162 } 163 private static final Component autowire_txman = 164 Components.useType(PlatformTransactionManager.class); 165 181 public static Component adapt(Component c, 182 SpringContext ctxt, Component transaction_manager, 183 Component transaction_attributes, String [] interfaces){ 184 if(transaction_attributes!=null && transaction_manager==null){ 185 transaction_manager = 186 ctxt.cast(PlatformTransactionManager.class, 187 autowire_txman 188 ).label("transaction manager auto detection"); 189 } 190 final Class type = c.getType(); 191 192 final Component r = createSpringBeanComponent(c, ctxt, transaction_manager, transaction_attributes, interfaces); 193 if(type!=null && BeanPostProcessor.class.isAssignableFrom(type)){ 194 ctxt.addBeanPostProcessor(ctxt.getTagName(), c); 196 } 197 if(type!=null && FactoryBean.class.isAssignableFrom(type)){ 198 return r; 200 } 201 if(transaction_attributes!=null){ 202 return r; 204 } 205 if(r.getType()==null && type!=null) 206 return ctxt.cast(type, r); 207 else return r; 208 } 209 private static Component createSpringBeanComponent(Component c, SpringContext ctxt, 210 Component transaction_manager, Component transaction_attributes, 211 String [] interfaces) { 212 final Class type = c.getType(); 213 c = c.mutate(getBeanMutation(ctxt)); 214 if(type!=null && SpringUtils.isSpringInfrastructureClass(type)){ 215 return c; } 218 final boolean isfactorybean = type!=null && FactoryBean.class.isAssignableFrom(type); 219 if(isfactorybean){ 220 if(ctxt.isSingletonAttributeSet()){ 221 final SingletonMode mode = ctxt.getSingleton(); 222 if(mode!=null) 223 c = mode.decorate(c); 224 } 225 else{ 226 c = c.singleton(new ThreadLocalScope()); 228 } 229 } 230 if(transaction_attributes==null){ 231 if(type==null || isfactorybean){ 233 return singletonedFactoryBean(isfactorybean,c, 234 c.map(getFactoryBeanMap(ctxt))); 235 } 236 else{ 237 return c; 238 } 239 } 240 else{ 241 return singletonedFactoryBean(isfactorybean, c, 242 Monad.map(transaction_manager, transaction_attributes, c, getFactoryBeanMap3(ctxt, interfaces))); 243 } 244 } 245 private static Component singletonedFactoryBean(boolean factorybean, 246 Component original_cc, Component c){ 247 if(factorybean){ 248 return decorateFactoryBean(new NonSingletonComponent(c), original_cc); 249 } 250 else{ 251 return c; 252 } 253 } 254 private static Object proxyTransaction(Object target, SpringContext ctxt, 255 PlatformTransactionManager tx, Properties attrs, String [] itfs) 256 throws Exception { 257 if(tx==null){ 258 if(attrs==null) 259 return target; 260 else 261 throw new IllegalArgumentException ("transaction manager is missing to perform declarative transaction"); 262 } 263 final TransactionProxyFactoryBean tpfb = new TransactionProxyFactoryBean(); 264 tpfb.setTarget(target); 266 tpfb.setTransactionManager(tx); 267 if(itfs!=null) 268 tpfb.setProxyInterfaces(itfs); 269 tpfb.setTransactionAttributes(attrs); 270 tpfb.setTarget(target); 272 tpfb.setTransactionManager(tx); 273 tpfb.setTransactionAttributes(attrs); 274 275 if(itfs!=null){ 276 tpfb.setProxyInterfaces(itfs); 277 } 278 injectBasicBean(tpfb, ctxt); 279 return tpfb.getObject(); 280 } 281 static final SpringKey factory_bean_key = new SpringKey("org.springframework.FactoryBean"); 282 static Component decorateFactoryBean(Component c, Component factorybean_cc){ 283 return NutsUtils.setState(c, factory_bean_key, factorybean_cc); 284 } 285 static boolean isFactoryBeanComponent(Component c){ 286 return getFactoryBeanComponent(c) != null; 287 } 288 static Component getFactoryBeanComponent(Component c){ 289 final Class type = c.getType(); 290 if(type!=null && FactoryBean.class.isAssignableFrom(type)){ 291 return c; 292 } 293 else{ 294 final Component fbc = (Component)NutsUtils.getState(c, factory_bean_key); 295 return fbc; 296 } 297 } 298 305 public static FactoryBean getFactoryBean(Container yan, Object key){ 306 final Component c = yan.getComponent(key); 307 if(c==null){ 308 return null; 309 } 310 final Component fbc = getFactoryBeanComponent(c); 311 if(fbc==null){ 312 return null; 313 } 314 return (FactoryBean)yan.instantiateComponent(fbc); 315 } 316 } 317 | Popular Tags |