@SuppressWarnings({"UnusedDeclaration"}) public class OpenEJBNamingContextListener implements LifecycleListener, PropertyChangeListener { private static final Logger logger = Logger.getInstance( LogCategory.OPENEJB.createChild("tomcat"), "org.apache.openejb.util.resources"); /** Associated standardServer. */ private final StandardServer standardServer; /** Has the listener been started? */ private boolean running = false; /** Associated naming resources. */ private final NamingResources namingResources; public OpenEJBNamingContextListener(StandardServer standardServer) { this.standardServer = standardServer; namingResources = standardServer.getGlobalNamingResources(); } public void lifecycleEvent(LifecycleEvent event) { if (event.getLifecycle() != standardServer) { return; } if (Lifecycle.START_EVENT.equals(event.getType())) { start(); } else if (Lifecycle.STOP_EVENT.equals(event.getType())) { stop(); } } public boolean isRunning() { return running; } public void start() { if (running) return; namingResources.addPropertyChangeListener(this); processInitialNamingResources(); running = true; } public void stop() { if (!running) return; namingResources.removePropertyChangeListener(this); running = false; } public void propertyChange(PropertyChangeEvent event) { if (!running) return; Object source = event.getSource(); if (source == namingResources) { processGlobalResourcesChange( event.getPropertyName(), event.getOldValue(), event.getNewValue()); } } /** * Process a property change on the global naming resources, by making the corresponding addition * or removal to OpenEJB. * * @param name Property name of the change to be processed * @param oldValue The old value (or <code>null</code> if adding) * @param newValue The new value (or <code>null</code> if removing) */ private void processGlobalResourcesChange(String name, Object oldValue, Object newValue) { // NOTE - It seems that the Context for global JNDI resources // is left in read-write mode, so we do not have to change it here if (name.equals("ejb")) { if (oldValue != null) { ContextEjb ejb = (ContextEjb) oldValue; if (ejb.getName() != null) { removeEjb(ejb.getName()); } } if (newValue != null) { ContextEjb ejb = (ContextEjb) newValue; if (ejb.getName() != null) { addEjb(ejb); } } } else if (name.equals("environment")) { if (oldValue != null) { ContextEnvironment env = (ContextEnvironment) oldValue; if (env.getName() != null) { removeEnvironment(env.getName()); } } if (newValue != null) { ContextEnvironment env = (ContextEnvironment) newValue; if (env.getName() != null) { addEnvironment(env); } } } else if (name.equals("localEjb")) { if (oldValue != null) { ContextLocalEjb ejb = (ContextLocalEjb) oldValue; if (ejb.getName() != null) { removeLocalEjb(ejb.getName()); } } if (newValue != null) { ContextLocalEjb ejb = (ContextLocalEjb) newValue; if (ejb.getName() != null) { addLocalEjb(ejb); } } } else if (name.equals("resource")) { if (oldValue != null) { ContextResource resource = (ContextResource) oldValue; if (resource.getName() != null) { removeResource(resource.getName()); } } if (newValue != null) { ContextResource resource = (ContextResource) newValue; if (resource.getName() != null) { addResource(resource); } } } else if (name.equals("resourceEnvRef")) { if (oldValue != null) { ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) oldValue; if (resourceEnvRef.getName() != null) { removeResourceEnvRef(resourceEnvRef.getName()); } } if (newValue != null) { ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) newValue; if (resourceEnvRef.getName() != null) { addResourceEnvRef(resourceEnvRef); } } } else if (name.equals("resourceLink")) { if (oldValue != null) { ContextResourceLink rl = (ContextResourceLink) oldValue; if (rl.getName() != null) { removeResourceLink(rl.getName()); } } if (newValue != null) { ContextResourceLink rl = (ContextResourceLink) newValue; if (rl.getName() != null) { addResourceLink(rl); } } } } private void processInitialNamingResources() { // Resource links ContextResourceLink[] resourceLinks = namingResources.findResourceLinks(); for (ContextResourceLink resourceLink : resourceLinks) { addResourceLink(resourceLink); } // Resources ContextResource[] resources = namingResources.findResources(); for (ContextResource resource : resources) { addResource(resource); } // Resources Env ContextResourceEnvRef[] resourceEnvRefs = namingResources.findResourceEnvRefs(); for (ContextResourceEnvRef resourceEnvRef : resourceEnvRefs) { addResourceEnvRef(resourceEnvRef); } // Environment entries ContextEnvironment[] contextEnvironments = namingResources.findEnvironments(); for (ContextEnvironment contextEnvironment : contextEnvironments) { addEnvironment(contextEnvironment); } // EJB references ContextEjb[] ejbs = namingResources.findEjbs(); for (ContextEjb ejb : ejbs) { addEjb(ejb); } } public void addEjb(ContextEjb ejb) {} public void addEnvironment(ContextEnvironment env) { bindResource(env); } public void addLocalEjb(ContextLocalEjb localEjb) {} public void addResource(ContextResource resource) { bindResource(resource); } public void addResourceEnvRef(ContextResourceEnvRef resourceEnvRef) { bindResource(resourceEnvRef); } private void bindResource(ResourceBase res) { try { Context globalNamingContext = standardServer.getGlobalNamingContext(); Object value = globalNamingContext.lookup(res.getName()); String type = res.getType(); bindResource(res.getName(), value, type); } catch (NamingException e) { logger.error("Unable to lookup Global Tomcat resource " + res.getName(), e); } } private void bindResource(final String name, final Object value, final String type) { Assembler assembler = (Assembler) SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class); try { assembler .getContainerSystem() .getJNDIContext() .lookup(Assembler.OPENEJB_RESOURCE_JNDI_PREFIX + name); return; } catch (NamingException ne) { // no-op: OK } final ResourceInfo resourceInfo = new ResourceInfo(); resourceInfo.id = name; resourceInfo.service = "Resource"; resourceInfo.types.add(type); PassthroughFactory.add(resourceInfo, value); logger.info( "Importing a Tomcat Resource with id '" + resourceInfo.id + "' of type '" + type + "'."); try { assembler.createResource(resourceInfo); } catch (OpenEJBException e) { logger.error("Unable to bind Global Tomcat resource " + name + " into OpenEJB", e); } } public void addResourceLink(ContextResourceLink resourceLink) {} public void removeEjb(String name) {} public void removeEnvironment(String name) {} public void removeLocalEjb(String name) {} public void removeResource(String name) { // there isn't any way to remove a resource yet } public void removeResourceEnvRef(String name) { // there isn't any way to remove a resource yet } public void removeResourceLink(String name) {} }
/** @version $Rev$ $Date$ */ public class OptimizedLoaderService implements LoaderService { private static final Logger log = Logger.getInstance(LogCategory.OPENEJB.createChild("cdi"), OptimizedLoaderService.class); public static final ThreadLocal<Collection<String>> ADDITIONAL_EXTENSIONS = new ThreadLocal<Collection<String>>(); private final LoaderService loaderService; public OptimizedLoaderService() { this(new DefaultLoaderService()); } public OptimizedLoaderService(final LoaderService loaderService) { this.loaderService = loaderService; } @Override public <T> List<T> load(final Class<T> serviceType) { return load(serviceType, Thread.currentThread().getContextClassLoader()); } @Override public <T> List<T> load(final Class<T> serviceType, final ClassLoader classLoader) { // ServiceLoader is expensive (can take up to a half second). This is an optimization if (OpenWebBeansPlugin.class.equals(serviceType)) { return (List<T>) loadWebBeansPlugins(classLoader); } // As far as we know, this only is reached for CDI Extension discovery if (Extension.class.equals(serviceType)) { return (List<T>) loadExtensions(classLoader); } return loaderService.load(serviceType, classLoader); } protected List<? extends Extension> loadExtensions(final ClassLoader classLoader) { final List<Extension> list = loaderService.load(Extension.class, classLoader); final Collection<String> additional = ADDITIONAL_EXTENSIONS.get(); if (additional != null) { for (final String name : additional) { try { list.add(Extension.class.cast(classLoader.loadClass(name).newInstance())); } catch (final Exception ignored) { // no-op } } } final Collection<Extension> extensionCopy = new ArrayList<>(list); final Iterator<Extension> it = list.iterator(); while (it.hasNext()) { if (it.hasNext()) { if (isFiltered(extensionCopy, it.next())) { it.remove(); } } } return list; } // mainly intended to avoid conflicts between internal and overrided spec extensions private boolean isFiltered(final Collection<Extension> extensions, final Extension next) { final ClassLoader containerLoader = ParentClassLoaderFinder.Helper.get(); final Class<? extends Extension> extClass = next.getClass(); if (extClass.getClassLoader() != containerLoader) { return false; } final String name = extClass.getName(); switch (name) { case "org.apache.bval.cdi.BValExtension": for (final Extension e : extensions) { final String en = e.getClass().getName(); // org.hibernate.validator.internal.cdi.ValidationExtension but allowing few evolutions of // packages if (en.startsWith("org.hibernate.validator.") && en.endsWith("ValidationExtension")) { log.info("Skipping BVal CDI integration cause hibernate was found in the application"); return true; } } break; case "org.apache.batchee.container.cdi.BatchCDIInjectionExtension": // see // org.apache.openejb.batchee.BatchEEServiceManager return "true" .equals(SystemInstance.get().getProperty("tomee.batchee.cdi.use-extension", "false")); case "org.apache.commons.jcs.jcache.cdi.MakeJCacheCDIInterceptorFriendly": final String spi = "META-INF/services/javax.cache.spi.CachingProvider"; try { final Enumeration<URL> appResources = Thread.currentThread().getContextClassLoader().getResources(spi); if (appResources != null && appResources.hasMoreElements()) { final Collection<URL> containerResources = Collections.list(containerLoader.getResources(spi)); do { if (!containerResources.contains(appResources.nextElement())) { log.info( "Skipping JCS CDI integration cause another provide was found in the application"); return true; } } while (appResources.hasMoreElements()); } } catch (final Exception e) { // no-op } break; default: } return false; } private List<? extends OpenWebBeansPlugin> loadWebBeansPlugins(final ClassLoader loader) { final List<OpenWebBeansPlugin> list = new ArrayList<>(2); list.add(new CdiPlugin()); { final Class<?> clazz; try { clazz = loader.loadClass("org.apache.geronimo.openejb.cdi.GeronimoWebBeansPlugin"); try { list.add(OpenWebBeansPlugin.class.cast(clazz.newInstance())); } catch (final Exception e) { log.error("Unable to load OpenWebBeansPlugin: GeronimoWebBeansPlugin"); } } catch (final ClassNotFoundException e) { // ignore } } { final Class<?> clazz; try { clazz = loader.loadClass("org.apache.webbeans.jsf.plugin.OpenWebBeansJsfPlugin"); try { list.add( OpenWebBeansPlugin.class.cast( Proxy.newProxyInstance( loader, new Class<?>[] {OpenWebBeansPlugin.class}, new ClassLoaderAwareHandler( clazz.getSimpleName(), clazz.newInstance(), loader)))); } catch (final Exception e) { log.error("Unable to load OpenWebBeansPlugin: OpenWebBeansJsfPlugin"); } } catch (final ClassNotFoundException e) { // ignore } } return list; } }