package org.hotswap.agent.plugin.owb; import org.hotswap.agent.annotation.OnClassLoadEvent; import org.hotswap.agent.javassist.CannotCompileException; import org.hotswap.agent.javassist.ClassPool; import org.hotswap.agent.javassist.CtClass; import org.hotswap.agent.javassist.CtField; import org.hotswap.agent.javassist.CtMethod; import org.hotswap.agent.javassist.NotFoundException; import org.hotswap.agent.logging.AgentLogger; import org.hotswap.agent.plugin.owb.beans.ContextualReloadHelper; import org.hotswap.agent.plugin.owb.beans.OwbHotswapContext; /** * The Class CdiContextsTransformer. * * @author alpapad@gmail.com */ public class CdiContextsTransformer { private static AgentLogger LOGGER = AgentLogger.getLogger(CdiContextsTransformer.class); @OnClassLoadEvent(classNameRegexp = "(org.apache.webbeans.context.AbstractContext)|" + "(org.apache.myfaces.flow.cdi.FlowScopedContextImpl)|" + "(org.apache.myfaces.cdi.view.ViewScopeContextImpl)") public static void transformOwbContexts(CtClass clazz, ClassPool classPool, ClassLoader cl) throws NotFoundException, CannotCompileException { CtClass superClass = clazz.getSuperclass(); while (superClass != null) { if ("org.apache.webbeans.context.AbstractContext".equals(superClass.getName())) { return; } superClass = superClass.getSuperclass(); } LOGGER.debug("Adding interface {} to {}.", OwbHotswapContext.class.getName(), clazz.getName()); clazz.addInterface(classPool.get(OwbHotswapContext.class.getName())); CtField toReloadFld = CtField.make("public transient java.util.Set __toReloadOwb = null;", clazz); clazz.addField(toReloadFld); CtField reloadingFld = CtField.make("public transient boolean __reloadingOwb = false;", clazz); clazz.addField(reloadingFld); CtMethod addBeanToReload = CtMethod.make( "public void __addBeanToReloadOwb(javax.enterprise.context.spi.Contextual bean) {" + " if (__toReloadOwb == null)" + " __toReloadOwb = new java.util.HashSet();" + " __toReloadOwb.add(bean);" + "}", clazz ); clazz.addMethod(addBeanToReload); CtMethod getBeansToReload = CtMethod.make("public java.util.Set __getBeansToReloadOwb(){return __toReloadOwb;}", clazz); clazz.addMethod(getBeansToReload); CtMethod reload = CtMethod.make("public void __reloadOwb() {" + ContextualReloadHelper.class.getName() +".reload(this);}", clazz); clazz.addMethod(reload); CtMethod isActiveCopy = CtMethod.make("public boolean __isActiveOwb(){return false;}", clazz); isActiveCopy.setBody(clazz.getDeclaredMethod("isActive"), null); clazz.addMethod(isActiveCopy); CtMethod isActive = clazz.getDeclaredMethod("isActive"); isActive.setBody( "{ " + " boolean active = __isActiveOwb(); " + " if(active && !__reloadingOwb ) { " + " __reloadingOwb = true;" + " __reloadOwb();" + " __reloadingOwb = false;" + " }" + " return active;" + "}" ); //addDestroyMethod(clazz, classPool); LOGGER.debug("Class '{}' patched with hot-swapping support", clazz.getName() ); } /* static void addDestroyMethod(CtClass clazz, ClassPool classPool) { CtMethod destroy = null; try { destroy = clazz.getDeclaredMethod("destroy", new CtClass[] {classPool.get("javax.enterprise.context.spi.Contextual")}); } catch (NotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(destroy == null) { try { clazz.addMethod(CtMethod.make(// "public void destroy(javax.enterprise.context.spi.Contextual c) {\n"+// ContextualReloadHelper.class.getName() +".reinitialize(this, c);\n"+ "}\n", clazz)); } catch (CannotCompileException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } */ }