Repository: deltaspike Updated Branches: refs/heads/master 3eae53c2d -> e1728f0a1
DELTASPIKE-745 fix ContextControl for Weld Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/e1728f0a Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/e1728f0a Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/e1728f0a Branch: refs/heads/master Commit: e1728f0a12864cf1d0b2507677cbff644aed25f0 Parents: c4f1bdb Author: Mark Struberg <[email protected]> Authored: Thu Oct 30 00:22:58 2014 +0100 Committer: Mark Struberg <[email protected]> Committed: Thu Oct 30 00:23:29 2014 +0100 ---------------------------------------------------------------------- .../cdise/owb/OpenWebBeansContextControl.java | 57 ++---- .../apache/deltaspike/cdise/owb/OwbHelper.java | 4 +- .../cdise/weld/ContextController.java | 201 ------------------- .../cdise/weld/WeldContextControl.java | 174 +++++++++++----- 4 files changed, 144 insertions(+), 292 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e1728f0a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java ---------------------------------------------------------------------- diff --git a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java b/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java index a0001cb..1a211d4 100644 --- a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java +++ b/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java @@ -26,8 +26,6 @@ import javax.enterprise.context.SessionScoped; import javax.inject.Singleton; import java.lang.annotation.Annotation; -import java.util.WeakHashMap; -import java.util.concurrent.atomic.AtomicInteger; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.webbeans.config.WebBeansContext; @@ -41,8 +39,13 @@ import org.apache.webbeans.spi.ContextsService; public class OpenWebBeansContextControl implements ContextControl { - private static WeakHashMap<ContextsService, AtomicInteger> sessionRefCounters - = new WeakHashMap<ContextsService, AtomicInteger>(); + /** + * we cannot directly link to MockHttpSession as this would lead to + * NoClassDefFound errors for cases where no servlet-api is on the classpath. + * E.g in pure SE environments. + */ + private static ThreadLocal<Object> mockSessions = new ThreadLocal<Object>(); + @Override public void startContexts() @@ -153,9 +156,14 @@ public class OpenWebBeansContextControl implements ContextControl Object mockSession = null; if (isServletApiAvailable()) { - mockSession = OwbHelper.getMockSession(); + mockSession = mockSessions.get(); + if (mockSession == null) + { + // we simply use the ThreadName as 'sessionId' + mockSession = OwbHelper.getMockSession(Thread.currentThread().getName()); + mockSessions.set(mockSession); + } } - incrementSessionRefCount(contextsService); contextsService.startContext(SessionScoped.class, mockSession); } @@ -208,12 +216,11 @@ public class OpenWebBeansContextControl implements ContextControl Object mockSession = null; if (isServletApiAvailable()) { - mockSession = OwbHelper.getMockSession(); - } - if (decrementSessionRefCount(contextsService)) - { - contextsService.endContext(SessionScoped.class, mockSession); + mockSession = mockSessions.get(); + mockSessions.set(null); + mockSessions.remove(); } + contextsService.endContext(SessionScoped.class, mockSession); } private void stopRequestScope() @@ -237,32 +244,4 @@ public class OpenWebBeansContextControl implements ContextControl } - private synchronized void incrementSessionRefCount(ContextsService contextsService) - { - AtomicInteger sessionRefCounter = sessionRefCounters.get(contextsService); - if (sessionRefCounter == null) - { - sessionRefCounter = new AtomicInteger(1); - sessionRefCounters.put(contextsService, sessionRefCounter); - } - else - { - sessionRefCounter.incrementAndGet(); - } - } - - /** - * @return true if the refCounter is back to zero - */ - private synchronized boolean decrementSessionRefCount(ContextsService contextsService) - { - AtomicInteger sessionRefCounter = sessionRefCounters.get(contextsService); - if (sessionRefCounter == null) - { - return false; - } - - return sessionRefCounter.decrementAndGet() <= 0; - } - } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e1728f0a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java ---------------------------------------------------------------------- diff --git a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java b/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java index f543ba7..b2e1252 100644 --- a/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java +++ b/deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java @@ -30,9 +30,9 @@ public class OwbHelper // just to prevent initialisation } - public static Object getMockSession() + public static Object getMockSession(String sessionId) { - return new MockHttpSession("mockSession1"); + return new MockHttpSession(sessionId); } public static Object getMockServletContextEvent() http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e1728f0a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/ContextController.java ---------------------------------------------------------------------- diff --git a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/ContextController.java b/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/ContextController.java deleted file mode 100644 index 99a87db..0000000 --- a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/ContextController.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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.deltaspike.cdise.weld; - -import org.jboss.weld.context.AbstractSharedContext; -import org.jboss.weld.context.ApplicationContext; -import org.jboss.weld.context.bound.BoundConversationContext; -import org.jboss.weld.context.bound.BoundRequestContext; -import org.jboss.weld.context.bound.BoundSessionContext; -import org.jboss.weld.context.bound.MutableBoundRequest; - -import javax.enterprise.context.RequestScoped; -import javax.enterprise.inject.Instance; -import javax.enterprise.inject.Typed; -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Weld specific controller for all supported context implementations - */ -@Typed() -public class ContextController -{ - private static ThreadLocal<RequestContextHolder> requestContexts = new ThreadLocal<RequestContextHolder>(); - - @Inject - private ApplicationContext applicationContext; - - @Inject - private BoundSessionContext sessionContext; - - @Inject - private Instance<BoundRequestContext> requestContextFactory; - - @Inject - private BoundConversationContext conversationContext; - private Map<String, Object> sessionMap; - - private AtomicInteger sessionRefCounter = new AtomicInteger(0); - - private boolean singletonScopeStarted; - - void startApplicationScope() - { - // Welds ApplicationContext is always active - } - - void stopApplicationScope() - { - if (applicationContext.isActive()) - { - applicationContext.invalidate(); - - //needed for weld < v1.1.9 - if (applicationContext instanceof AbstractSharedContext) - { - ((AbstractSharedContext) applicationContext).getBeanStore().clear(); - } - } - } - - //X TODO check if we can remove it - void startSingletonScope() - { - if (singletonScopeStarted) - { - throw new IllegalStateException(Singleton.class.getName() + " started already"); - } - singletonScopeStarted = true; - } - - void stopSingletonScope() - { - singletonScopeStarted = false; - } - - synchronized void startSessionScope() - { - if (sessionMap == null) - { - sessionMap = new HashMap<String, Object>(); - } - - sessionRefCounter.incrementAndGet(); - sessionContext.associate(sessionMap); - sessionContext.activate(); - } - - synchronized void stopSessionScope() - { - if (sessionContext.isActive()) - { - sessionContext.invalidate(); - sessionContext.deactivate(); - sessionContext.dissociate(sessionMap); - if (sessionRefCounter.decrementAndGet() <= 0) - { - sessionMap = null; - } - } - } - - synchronized void startConversationScope(String cid) - { - RequestContextHolder rcHolder = requestContexts.get(); - if (rcHolder == null) - { - startRequestScope(); - rcHolder = requestContexts.get(); - } - conversationContext.associate(new MutableBoundRequest(rcHolder.requestMap, sessionMap)); - conversationContext.activate(cid); - } - - synchronized void stopConversationScope() - { - RequestContextHolder rcHolder = requestContexts.get(); - if (rcHolder == null) - { - startRequestScope(); - rcHolder = requestContexts.get(); - } - if (conversationContext.isActive()) - { - conversationContext.invalidate(); - conversationContext.deactivate(); - conversationContext.dissociate(new MutableBoundRequest(rcHolder.getRequestMap(), sessionMap)); - } - } - - synchronized void startRequestScope() - { - RequestContextHolder rcHolder = requestContexts.get(); - if (rcHolder == null) - { - rcHolder = new RequestContextHolder(requestContextFactory.get(), new HashMap<String, Object>()); - requestContexts.set(rcHolder); - } - else - { - throw new IllegalStateException(RequestScoped.class.getName() + " started already"); - } - - rcHolder.getBoundRequestContext().associate(rcHolder.getRequestMap()); - rcHolder.getBoundRequestContext().activate(); - } - - synchronized void stopRequestScope() - { - RequestContextHolder rcHolder = requestContexts.get(); - if (rcHolder != null && rcHolder.getBoundRequestContext().isActive()) - { - rcHolder.getBoundRequestContext().invalidate(); - rcHolder.getBoundRequestContext().deactivate(); - rcHolder.getBoundRequestContext().dissociate(rcHolder.getRequestMap()); - requestContexts.set(null); - requestContexts.remove(); - } - } - - private static class RequestContextHolder - { - private final BoundRequestContext boundRequestContext; - private final Map<String, Object> requestMap; - - private RequestContextHolder(BoundRequestContext boundRequestContext, Map<String, Object> requestMap) - { - this.boundRequestContext = boundRequestContext; - this.requestMap = requestMap; - } - - public BoundRequestContext getBoundRequestContext() - { - return boundRequestContext; - } - - public Map<String, Object> getRequestMap() - { - return requestMap; - } - } -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e1728f0a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java ---------------------------------------------------------------------- diff --git a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java b/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java index e3aff58..9a2cc36 100644 --- a/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java +++ b/deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java @@ -23,15 +23,19 @@ import javax.enterprise.context.ConversationScoped; import javax.enterprise.context.Dependent; import javax.enterprise.context.RequestScoped; import javax.enterprise.context.SessionScoped; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.AnnotatedType; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.InjectionTarget; +import javax.enterprise.inject.Instance; import javax.inject.Inject; -import javax.inject.Singleton; import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.Map; import org.apache.deltaspike.cdise.api.ContextControl; +import org.jboss.weld.context.AbstractSharedContext; +import org.jboss.weld.context.ApplicationContext; +import org.jboss.weld.context.bound.BoundConversationContext; +import org.jboss.weld.context.bound.BoundRequestContext; +import org.jboss.weld.context.bound.BoundSessionContext; +import org.jboss.weld.context.bound.MutableBoundRequest; /** * Weld specific impl of the {@link org.apache.deltaspike.cdise.api.ContextControl} @@ -40,10 +44,24 @@ import org.apache.deltaspike.cdise.api.ContextControl; @SuppressWarnings("UnusedDeclaration") public class WeldContextControl implements ContextControl { - private ContextController contextController; + private static ThreadLocal<RequestContextHolder> requestContexts = new ThreadLocal<RequestContextHolder>(); + private static ThreadLocal<Map<String, Object>> sessionMaps = new ThreadLocal<Map<String, Object>>(); + + + + @Inject + private ApplicationContext applicationContext; + + @Inject + private BoundSessionContext sessionContext; + + @Inject + private Instance<BoundRequestContext> requestContextFactory; @Inject - private BeanManager beanManager; + private BoundConversationContext conversationContext; + + @Override public void startContexts() @@ -51,7 +69,7 @@ public class WeldContextControl implements ContextControl startApplicationScope(); startSessionScope(); startRequestScope(); - startConversationScope(); + startConversationScope(null); } @Override @@ -71,7 +89,7 @@ public class WeldContextControl implements ContextControl } else if (scopeClass.isAssignableFrom(ConversationScoped.class)) { - startConversationScope(); + startConversationScope(null); } } @@ -87,7 +105,6 @@ public class WeldContextControl implements ContextControl stopRequestScope(); stopSessionScope(); stopApplicationScope(); //can't be done because of WELD-1072 - stopSingletonScope(); } @Override @@ -109,10 +126,6 @@ public class WeldContextControl implements ContextControl { stopConversationScope(); } - else if (scopeClass.isAssignableFrom(Singleton.class)) - { - stopSingletonScope(); - } } /* @@ -120,72 +133,133 @@ public class WeldContextControl implements ContextControl */ private void startApplicationScope() { - getContextController().startApplicationScope(); + // Welds ApplicationContext is always active + // No need to attach any ThreadLocals... } - private void startSessionScope() + private void stopApplicationScope() { - getContextController().startSessionScope(); + // Welds ApplicationContext gets cleaned at shutdown. + //X TODO if we really drop the context then we might trash EE + //X if we do not do it then we loose the ability to cleanup ApplicationScoped beans + if (applicationContext.isActive()) + { + applicationContext.invalidate(); + + //needed for weld < v1.1.9 + if (applicationContext instanceof AbstractSharedContext) + { + ((AbstractSharedContext) applicationContext).getBeanStore().clear(); + } + } } - private void startConversationScope() + void startRequestScope() { - getContextController().startConversationScope(null); + RequestContextHolder rcHolder = requestContexts.get(); + if (rcHolder == null) + { + rcHolder = new RequestContextHolder(requestContextFactory.get(), new HashMap<String, Object>()); + requestContexts.set(rcHolder); + } + else + { + throw new IllegalStateException(RequestScoped.class.getName() + " started already"); + } + + rcHolder.getBoundRequestContext().associate(rcHolder.getRequestMap()); + rcHolder.getBoundRequestContext().activate(); } - private void startRequestScope() + void stopRequestScope() { - getContextController().startRequestScope(); + RequestContextHolder rcHolder = requestContexts.get(); + if (rcHolder != null && rcHolder.getBoundRequestContext().isActive()) + { + rcHolder.getBoundRequestContext().invalidate(); + rcHolder.getBoundRequestContext().deactivate(); + rcHolder.getBoundRequestContext().dissociate(rcHolder.getRequestMap()); + requestContexts.set(null); + requestContexts.remove(); + } } - /* - * stop scopes - */ - - private void stopApplicationScope() + private void startSessionScope() { - getContextController().stopApplicationScope(); + Map<String, Object> sessionMap = sessionMaps.get(); + if (sessionMap == null) + { + sessionMap = new HashMap<String, Object>(); + sessionMaps.set(sessionMap); + } + + sessionContext.associate(sessionMap); + sessionContext.activate(); + } private void stopSessionScope() { - getContextController().stopSessionScope(); - } + if (sessionContext.isActive()) + { + sessionContext.invalidate(); + sessionContext.deactivate(); + sessionContext.dissociate(sessionMaps.get()); - private void stopConversationScope() - { - getContextController().stopConversationScope(); + sessionMaps.set(null); + sessionMaps.remove(); + } } - private void stopRequestScope() + void startConversationScope(String cid) { - getContextController().stopRequestScope(); + RequestContextHolder rcHolder = requestContexts.get(); + if (rcHolder == null) + { + startRequestScope(); + rcHolder = requestContexts.get(); + } + conversationContext.associate(new MutableBoundRequest(rcHolder.requestMap, sessionMaps.get())); + conversationContext.activate(cid); } - private void stopSingletonScope() + void stopConversationScope() { - getContextController().stopSingletonScope(); + RequestContextHolder rcHolder = requestContexts.get(); + if (rcHolder == null) + { + startRequestScope(); + rcHolder = requestContexts.get(); + } + if (conversationContext.isActive()) + { + conversationContext.invalidate(); + conversationContext.deactivate(); + conversationContext.dissociate(new MutableBoundRequest(rcHolder.getRequestMap(), sessionMaps.get())); + } } - private ContextController getContextController() + + private static class RequestContextHolder { - if (contextController != null) + private final BoundRequestContext boundRequestContext; + private final Map<String, Object> requestMap; + + private RequestContextHolder(BoundRequestContext boundRequestContext, Map<String, Object> requestMap) { - return contextController; + this.boundRequestContext = boundRequestContext; + this.requestMap = requestMap; } - contextController = new ContextController(); - return tryToInjectFields(contextController); - } - - private <T> T tryToInjectFields(T instance) - { - CreationalContext creationalContext = beanManager.createCreationalContext(null); + public BoundRequestContext getBoundRequestContext() + { + return boundRequestContext; + } - AnnotatedType annotatedType = beanManager.createAnnotatedType(instance.getClass()); - InjectionTarget injectionTarget = beanManager.createInjectionTarget(annotatedType); - injectionTarget.inject(instance, creationalContext); - return instance; + public Map<String, Object> getRequestMap() + { + return requestMap; + } } }
