1 17 18 package org.apache.geronimo.spring; 19 20 import java.lang.reflect.Method ; 21 import java.lang.reflect.Proxy ; 22 import java.net.URI ; 23 import java.net.URL ; 24 import java.net.URLClassLoader ; 25 import java.util.HashSet ; 26 import java.util.Hashtable ; 27 import java.util.Iterator ; 28 import java.util.Set ; 29 import javax.management.MalformedObjectNameException ; 30 import javax.management.ObjectName ; 31 32 import net.sf.cglib.proxy.InterfaceMaker; 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.apache.geronimo.gbean.GBeanData; 36 import org.apache.geronimo.gbean.GBeanInfo; 37 import org.apache.geronimo.gbean.GBeanInfoBuilder; 38 import org.apache.geronimo.gbean.GBeanLifecycle; 39 import org.apache.geronimo.kernel.Kernel; 40 import org.springframework.beans.BeansException; 41 import org.springframework.beans.factory.config.BeanPostProcessor; 42 import org.springframework.beans.factory.support.BeanDefinitionValidationException; 43 import org.springframework.beans.factory.support.DefaultListableBeanFactory; 44 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; 45 import org.springframework.core.io.ClassPathResource; 46 47 52 public class SpringGBean 53 implements GBeanLifecycle 54 { 55 protected static final Log _log = LogFactory.getLog(SpringGBean.class); 56 57 protected final Kernel _kernel; 59 protected final String _objectName; 60 protected final ClassLoader _classLoader; 61 protected final URI [] _classPath; 62 protected final URL _configurationBaseUrl; 63 protected final URI _configPath; 64 65 protected ClassLoader _appClassLoader; 66 protected ObjectName _jmxName; 67 protected DefaultListableBeanFactory _factory; 68 69 public static final GBeanInfo GBEAN_INFO; 71 72 static 73 { 74 GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder("Spring Application Context", SpringGBean.class); 75 76 infoBuilder.addAttribute("kernel" , Kernel.class , false); 77 infoBuilder.addAttribute("objectName" , String .class , false); 78 infoBuilder.addAttribute("classLoader" , ClassLoader .class , false); 79 infoBuilder.addAttribute("classPath" , URI [].class , true); 80 infoBuilder.addAttribute("configurationBaseUrl" , URL .class , true); 81 infoBuilder.addAttribute("configPath" , URI .class , true); 82 83 infoBuilder.setConstructor(new String []{ 84 "kernel", 85 "objectName", 86 "classLoader", 87 "classPath", 88 "configurationBaseUrl", 89 "configPath" 90 }); 91 92 GBEAN_INFO = infoBuilder.getBeanInfo(); 93 } 94 95 public static GBeanInfo getGBeanInfo() {return GBEAN_INFO;} 96 97 99 100 public 101 SpringGBean(Kernel kernel, String objectName, ClassLoader classLoader, URI [] classPath, URL configurationBaseUrl, URI configPath) 102 { 103 _kernel =kernel; 104 _objectName =objectName; 105 _configPath =configPath; 106 _classLoader =classLoader; 107 _classPath =classPath; 108 _configurationBaseUrl =configurationBaseUrl; 109 } 110 111 115 class GeronimoBeanFactory 116 extends DefaultListableBeanFactory 117 { 118 GeronimoBeanFactory(){super();} 119 } 120 121 public void 122 doStart() 123 throws Exception 124 { 125 _jmxName=new ObjectName (_objectName); 126 127 URI root = URI.create(_configurationBaseUrl.toString()); 129 130 URL [] urls=new URL [_classPath.length]; 131 132 for (int i=0; i<_classPath.length; i++) 133 { 134 URL url=root.resolve(_classPath[i]).toURL(); 135 _log.info("_classPath["+i+"]: "+url); 136 urls[i]=url; 137 } 138 139 _appClassLoader=new URLClassLoader (urls, _classLoader); 140 141 _factory=new GeronimoBeanFactory(); 143 XmlBeanDefinitionReader xbdr=new XmlBeanDefinitionReader(_factory); 144 xbdr.setBeanClassLoader(_appClassLoader); 145 xbdr.loadBeanDefinitions(new ClassPathResource(_configPath.toString(), _appClassLoader)); 146 147 _factory.addBeanPostProcessor(new BeanPostProcessor() { 149 public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException { 150 return beforeInitialization(bean, name); 151 } 152 153 public Object postProcessAfterInitialization(Object bean, String name) throws BeansException { 154 return afterInitialization(bean, name); 155 } 156 }); 157 158 String [] ids=_factory.getBeanDefinitionNames(); 160 int n=ids.length; 161 for (int i=n; i>0; i--) 162 _factory.getBean(ids[i-1]); 163 164 _log.info("Deployed: "+n+" POJO"+(n==1?"":"s")); 165 } 166 167 168 public void 169 doStop() 170 throws Exception 171 { 172 tidyUp(); 173 } 174 175 public void 176 doFail() 177 { 178 try 179 { 180 tidyUp(); 181 } 182 catch (Exception e) 183 { 184 _log.warn("problem decommissioning Spring module: "+_jmxName, e); 185 } 186 } 187 188 protected void 189 tidyUp() 190 throws Exception 191 { 192 String pattern=_jmxName.getDomain()+":J2EEApplication="+_jmxName.getKeyProperty("J2EEApplication")+",J2EEServer="+_jmxName.getKeyProperty("J2EEServer")+",SpringModule="+_jmxName.getKeyProperty("name")+",j2eeType=SpringBean,*"; 194 ObjectName on=new ObjectName (pattern); 195 196 204 Set peers=_kernel.listGBeans(on); 205 for (Iterator i=peers.iterator(); i.hasNext();) 206 { 207 ObjectName tmp=(ObjectName )i.next(); 208 try 209 { 210 _log.info("stopping: "+tmp); 211 _kernel.stopGBean(tmp); 212 _log.info("unloading: "+tmp); 213 _kernel.unloadGBean(tmp); 214 } 215 catch (Exception e) 216 { 217 _log.warn("problem decommissioning POJO peer GBean: "+tmp, e); 218 } 219 } 220 221 _factory.destroySingletons(); 222 } 223 224 228 231 protected Object 232 beforeInitialization(Object bean, String name) 233 { 234 return bean; 235 } 236 237 240 protected Object 241 afterInitialization(Object bean, String name) 242 throws BeansException 243 { 244 try 246 { 247 GBeanData gd=createPOJOGBeanData(bean, name); 248 if (gd==null) 249 _log.warn("No GBean available for name: " + name + " bean: " + bean); 250 else 251 { 252 _log.info("proxying: "+bean); 253 _log.info("loading: "+gd.getName()); 254 _kernel.loadGBean(gd, _appClassLoader); 256 _log.info("starting: "+gd.getName()); 257 _kernel.startGBean(gd.getName()); 258 } 259 } 260 catch (Exception e) 261 { 262 throw new BeanDefinitionValidationException("Could not load the GBean for name: " + name + " bean: " + bean + ". Reason: " + e, e); 263 } 264 return bean; 265 } 266 267 271 277 protected ObjectName 278 createObjectName(String name) 279 throws MalformedObjectNameException 280 { 281 Hashtable props =new Hashtable (_jmxName.getKeyPropertyList()); 282 props.put("SpringModule" , props.get("name")); 283 props.put("j2eeType" , "SpringBean"); 284 props.put("name" , name); 285 return new ObjectName (_jmxName.getDomain(), props); 286 } 287 288 protected int _count=0; 290 public static class InvocationHandler 291 implements java.lang.reflect.InvocationHandler , java.io.Serializable 292 { 293 protected Object _pojo; 294 295 public 296 InvocationHandler(Object pojo) {_pojo=pojo;} 297 298 public Object 299 invoke(Object proxy, Method method, Object [] args) 300 throws Throwable 301 { 302 return _pojo.getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(_pojo, args); 303 } 304 } 305 306 protected synchronized GBeanData 307 createPOJOGBeanData(Object bean, String name) 308 throws MalformedObjectNameException 309 { 310 Class c=createProxyClass(bean); 311 GBeanInfoBuilder gbif = new GBeanInfoBuilder(c, "POJO["+(_count++)+"]"); 312 313 gbif.addAttribute("invocationHandler", java.lang.reflect.InvocationHandler .class, true); 314 gbif.setConstructor(new String []{"invocationHandler"}); 315 Set pm=new HashSet (); 317 Method [] methods=c.getMethods(); 318 for (int i=0;i<methods.length;i++) 319 { 320 Method m=methods[i]; 321 String n=m.getName(); 322 Class [] pt=m.getParameterTypes(); 323 Class rt=m.getReturnType(); 324 325 if ((n.startsWith("get") && pt.length==0) || (n.startsWith("set") && pt.length==1 && rt==Void.TYPE)) 327 pm.add(n.substring(3,4).toLowerCase()+n.substring(4)); 328 } 329 330 gbif.addInterface(c, (String [])pm.toArray(new String [pm.size()])); 332 GBeanData gbd=new GBeanData(createObjectName(name), gbif.getBeanInfo()); 334 gbd.setAttribute("invocationHandler" , new InvocationHandler(bean)); 336 337 return gbd; 338 } 339 340 protected Class 348 createProxyClass(Object pojo) 349 { 350 InterfaceMaker im=new InterfaceMaker(); 351 im.add(pojo.getClass()); 353 356 Class c=im.create(); 357 return Proxy.getProxyClass(c.getClassLoader(), new Class [] {c}); 358 } 359 } 360 | Popular Tags |