/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.openejb.cdi; import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.webbeans.annotation.InitializedLiteral; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.event.EventMetadataImpl; import org.apache.webbeans.spi.ContextsService; import org.apache.webbeans.web.context.WebContextsService; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; public class CdiAppContextsService extends WebContextsService implements ContextsService { public static final Object EJB_REQUEST_EVENT = new Object(); private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB.createChild("cdi"), CdiAppContextsService.class); private static final ThreadLocal<Collection<Runnable>> endRequestRunnables = new ThreadLocal<Collection<Runnable>>() { @Override protected Collection<Runnable> initialValue() { return new ArrayList<>(); } }; public CdiAppContextsService(final WebBeansContext wbc) { super(wbc); } private void runEndRequestTasks() { for (final Runnable r : endRequestRunnables.get()) { try { r.run(); } catch (final Exception e) { logger.error(e.getMessage(), e); } } endRequestRunnables.remove(); } public static void pushRequestReleasable(final Runnable runnable) { endRequestRunnables.get().add(runnable); } @Override // this method is called after the deployment (BeansDeployer) but need beans to be here to get events public void init(final Object initializeObject) { super.init(initializeObject); if (initializeObject != null) { Object event = initializeObject; if (StartupObject.class.isInstance(initializeObject)) { final StartupObject so = StartupObject.class.cast(initializeObject); if (so.isFromWebApp()) { // ear webapps event = so.getWebContext().getServletContext(); } else if (so.getAppInfo().webAppAlone) { event = SystemInstance.get().getComponent(ServletContext.class); } } else if (ServletContextEvent.class.isInstance(initializeObject)) { event = ServletContextEvent.class.cast(initializeObject).getServletContext(); } if (!FiredManually.class.isInstance(event)) { applicationStarted(event); } } } public void applicationStarted(final Object event) { Object appEvent = event != null ? event : applicationContext; webBeansContext.getBeanManagerImpl().fireEvent( appEvent, new EventMetadataImpl(null, ServletContext.class.isInstance(appEvent) ? ServletContext.class : Object.class, null, new Annotation[]{InitializedLiteral.INSTANCE_APPLICATION_SCOPED}, webBeansContext), false); } public void destroy(final Object destroyObject) { super.destroy(destroyObject); removeThreadLocals(); } @Override protected void destroyRequestContext(Object requestEvent) { // execute endrequest tasks runEndRequestTasks(); super.destroyRequestContext(requestEvent); } public interface FiredManually {} }