package org.jboss.seam.security.external.virtualapplications; import java.lang.annotation.Annotation; import javax.enterprise.context.ContextNotActiveException; import javax.enterprise.context.spi.Context; import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; import javax.servlet.ServletContext; import org.jboss.seam.security.external.contexts.ContextualInstance; import org.jboss.seam.security.external.contexts.HashMapBeanStore; import org.jboss.seam.security.external.virtualapplications.api.VirtualApplicationScoped; /** * @author Marcel Kolsteren */ public class VirtualApplicationContext implements Context { private static final String BEAN_STORE_ATTRIBUTE_NAME_PREFIX = "virtualApplicationContextBeanStore"; private ServletContext servletContext; private final ThreadLocal<String> hostNameThreadLocal; public VirtualApplicationContext() { hostNameThreadLocal = new ThreadLocal<String>(); } protected HashMapBeanStore getBeanStore() { return getBeanStore(hostNameThreadLocal.get()); } private HashMapBeanStore getBeanStore(String hostName) { HashMapBeanStore beanStore = (HashMapBeanStore) servletContext.getAttribute(getAttributeName(hostName)); return beanStore; } private void createBeanStore(String hostName) { HashMapBeanStore beanStore = new HashMapBeanStore(); servletContext.setAttribute(getAttributeName(hostName), beanStore); } private void removeBeanStore(String hostName) { servletContext.removeAttribute(getAttributeName(hostName)); } private String getAttributeName(String hostName) { return BEAN_STORE_ATTRIBUTE_NAME_PREFIX + "_" + hostName; } public void initialize(ServletContext servletContext) { this.servletContext = servletContext; } public void destroy() { this.servletContext = null; } public void create(String hostName) { createBeanStore(hostName); attach(hostName); } public void remove() { getBeanStore().clear(); removeBeanStore(this.hostNameThreadLocal.get()); detach(); } public boolean isExistingVirtualApplication(String hostName) { return servletContext != null && getBeanStore(hostName) != null; } public void attach(String hostName) { this.hostNameThreadLocal.set(hostName); } public void detach() { this.hostNameThreadLocal.set(null); } public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) { if (!isActive()) { throw new ContextNotActiveException(); } ContextualInstance<T> beanInstance = getBeanStore().get(contextual); if (beanInstance != null) { return beanInstance.getInstance(); } else if (creationalContext != null) { T instance = contextual.create(creationalContext); if (instance != null) { beanInstance = new ContextualInstance<T>(contextual, creationalContext, instance); getBeanStore().put(contextual, beanInstance); } return instance; } else { return null; } } public <T> T get(Contextual<T> contextual) { return get(contextual, null); } public Class<? extends Annotation> getScope() { return VirtualApplicationScoped.class; } public boolean isActive() { return hostNameThreadLocal.get() != null; } }