package org.hotswap.agent.plugin.weld;
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.weld.beans.ContextualReloadHelper;
import org.hotswap.agent.plugin.weld.beans.WeldHotswapContext;
/**
* The Class CdiContextsTransformer.
*
* @author alpapad@gmail.com
*/
public class CdiContextsTransformer {
private static AgentLogger LOGGER = AgentLogger.getLogger(CdiContextsTransformer.class);
/**
* Add context reloading functionality to base contexts classes
*
* @param clazz the clazz
* @param classPool the class pool
* @param cl the class loader
* @throws NotFoundException the not found exception
* @throws CannotCompileException the cannot compile exception
*/
@OnClassLoadEvent(classNameRegexp = "(org.jboss.weld.context.AbstractManagedContext)|" +
"(org.jboss.weld.context.AbstractSharedContext)|" +
"(org.jboss.weld.context.unbound.DependentContextImpl)|" +
"(org.jboss.weld.util.ForwardingContext)|" +
"(org.apache.myfaces.flow.cdi.FlowScopedContextImpl)|" +
"(org.apache.myfaces.cdi.view.ViewScopeContextImpl)"
)
public static void transformReloadingWeldContexts(CtClass clazz, ClassPool classPool, ClassLoader cl) throws NotFoundException, CannotCompileException {
LOGGER.debug("Adding interface {} to {}.", WeldHotswapContext.class.getName(), clazz.getName());
clazz.addInterface(classPool.get(WeldHotswapContext.class.getName()));
CtField toReloadFld = CtField.make("public transient java.util.Set __toReloadWeld = null;", clazz);
clazz.addField(toReloadFld);
CtField reloadingFld = CtField.make("public transient boolean __reloadingWeld = false;", clazz);
clazz.addField(reloadingFld);
CtMethod addBeanToReload = CtMethod.make(
"public void __addBeanToReloadWeld(javax.enterprise.context.spi.Contextual bean) {" +
" if (__toReloadWeld == null)" +
" __toReloadWeld = new java.util.HashSet();" +
" __toReloadWeld.add(bean);" +
"}",
clazz
);
clazz.addMethod(addBeanToReload);
CtMethod getBeansToReload = CtMethod.make("public java.util.Set __getBeansToReloadWeld(){return __toReloadWeld;}", clazz);
clazz.addMethod(getBeansToReload);
CtMethod reload = CtMethod.make("public void __reloadWeld() {" + ContextualReloadHelper.class.getName() +".reload(this);}", clazz);
clazz.addMethod(reload);
CtMethod isActiveCopy = CtMethod.make("public boolean __isActiveWeld(){return false;}", clazz);
isActiveCopy.setBody(clazz.getDeclaredMethod("isActive"), null);
clazz.addMethod(isActiveCopy);
CtMethod isActive = clazz.getDeclaredMethod("isActive");
isActive.setBody(
"{ " +
" boolean active = __isActiveWeld(); " +
" if(active && !__reloadingWeld ) { " +
" __reloadingWeld = true;" +
" __reloadWeld();" +
" __reloadingWeld = false;" +
" }" +
" return active;" +
"}"
);
//addDestroyMethod(clazz, classPool);
LOGGER.debug("Class '{}' patched with hot-swapping support", clazz.getName() );
}
@OnClassLoadEvent(classNameRegexp = "org.jboss.weld.context.beanstore.http.LazySessionBeanStore")
public static void transformLazySessionBeanStore(CtClass clazz, ClassPool classPool, ClassLoader cl) throws NotFoundException, CannotCompileException {
CtMethod getSessionCopy = CtMethod.make("public javax.servlet.http.HttpSession __getSession(boolean create) {return null;}", clazz);
getSessionCopy.setBody(clazz.getDeclaredMethod("getSession"), null);
clazz.addMethod(getSessionCopy);
CtMethod getSession = clazz.getDeclaredMethod("getSession");
getSession.setBody(
"{ " +
" boolean sessionExists = $1 && (getSessionIfExists()!=null); " +
" javax.servlet.http.HttpSession session = __getSession($1);" +
" if(!sessionExists && session!=null) {" +
" org.hotswap.agent.plugin.weld.command.HttpSessionsRegistry.addSeenSession(session);" +
" }" +
" return session;" +
"}"
);
}
}