You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2011/02/18 01:56:08 UTC

svn commit: r1071849 - in /myfaces/extensions/cdi/trunk: core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/ jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/ jee-modules/jpa-module/impl/src/main...

Author: gpetracek
Date: Fri Feb 18 00:56:07 2011
New Revision: 1071849

URL: http://svn.apache.org/viewvc?rev=1071849&view=rev
Log:
EXTCDI-138 pluggable interceptor implementations

Added:
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/InterceptorStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/DefaultTransactionalInterceptorStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/PersistenceStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/DefaultViewControllerStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/ViewControllerStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/DefaultCloseConversationGroupStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/spi/CloseConversationGroupStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/SecurityStrategy.java
Modified:
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/TransactionalInterceptor.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/ViewControllerInterceptor.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/CloseConversationGroupInterceptor.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityInterceptor.java

Added: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/InterceptorStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/InterceptorStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/InterceptorStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/spi/InterceptorStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,32 @@
+/*
+ * 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.myfaces.extensions.cdi.core.impl.spi;
+
+import javax.interceptor.InvocationContext;
+import java.io.Serializable;
+
+/**
+ * Base interface for all interceptor strategies which allow to provide custom implementations for CODI interceptors.
+ *
+ * @author Gerhard Petracek
+ */
+public interface InterceptorStrategy extends Serializable
+{
+    Object execute(InvocationContext invocationContext) throws Exception;
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/DefaultTransactionalInterceptorStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/DefaultTransactionalInterceptorStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/DefaultTransactionalInterceptorStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/DefaultTransactionalInterceptorStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,417 @@
+/*
+ * 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.myfaces.extensions.cdi.jpa.impl;
+
+import org.apache.myfaces.extensions.cdi.jpa.impl.spi.PersistenceStrategy;
+import org.apache.myfaces.extensions.cdi.jpa.api.Transactional;
+import org.apache.myfaces.extensions.cdi.core.impl.util.AnyLiteral;
+import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+
+import javax.inject.Inject;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.Default;
+import javax.enterprise.context.Dependent;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.interceptor.InvocationContext;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+/**
+ * @author Mark Struberg
+ * @author Gerhard Petracek
+ */
+@Dependent
+public class DefaultTransactionalInterceptorStrategy implements PersistenceStrategy
+{
+    private static final long serialVersionUID = -1432802805095533499L;
+
+    //don't use final in interceptors
+    private static String noFieldMarker = TransactionalInterceptor.class.getName() + ":DEFAULT_FIELD";
+
+    @Inject
+    private BeanManager beanManager;
+
+    private static transient ThreadLocal<AtomicInteger> refCount = new ThreadLocal<AtomicInteger>();
+
+    protected final Logger logger = Logger.getLogger(TransactionalInterceptor.class.getName());
+
+    /** key=qualifier name, value= EntityManager */
+    private static transient ThreadLocal<HashMap<String, EntityManager>> entityManagerMap =
+            new ThreadLocal<HashMap<String, EntityManager>>();
+
+    private static transient Map<ClassLoader, Map<String, PersistenceContextMetaEntry>> persistenceContextMetaEntries =
+            new ConcurrentHashMap<ClassLoader, Map<String, PersistenceContextMetaEntry>>();
+
+    /** 1 ms  in nanoTime ticks */
+    final static long LONG_MILLISECOND = 1000000L;
+    final static long LONG_RUNNING_THRESHOLD = 300L * LONG_MILLISECOND;
+
+    public Object execute(InvocationContext context) throws Exception
+    {
+        Transactional transactionalAnnotation = context.getMethod().getAnnotation(Transactional.class);
+
+        if (transactionalAnnotation == null)
+        {
+            transactionalAnnotation = context.getTarget().getClass().getAnnotation(Transactional.class);
+        }
+
+        Class<? extends Annotation> qualifierClass = Default.class;
+        if (transactionalAnnotation != null)
+        {
+            qualifierClass = transactionalAnnotation.qualifier();
+        }
+
+        Set<Bean<?>> entityManagerBeans = beanManager.getBeans(EntityManager.class, new AnyLiteral());
+        if (entityManagerBeans == null)
+        {
+            entityManagerBeans = new HashSet<Bean<?>>();
+        }
+        Bean<EntityManager> entityManagerBean = null;
+
+        it:
+        for (Bean<?> currentEntityManagerBean : entityManagerBeans)
+        {
+            Set<Annotation> foundQualifierAnnotations = currentEntityManagerBean.getQualifiers();
+
+            for (Annotation currentQualifierAnnotation : foundQualifierAnnotations)
+            {
+                if (currentQualifierAnnotation.annotationType().equals(qualifierClass))
+                {
+                    entityManagerBean = (Bean<EntityManager>) currentEntityManagerBean;
+                    break it;
+                }
+            }
+        }
+
+        EntityManagerEntry entityManagerEntry = null;
+        EntityManager entityManager;
+
+        String entityManagerId = qualifierClass.getName();
+        if (entityManagerBean == null)
+        {
+            //support for special add-ons which introduce backward compatibility - resolves the injected entity manager
+            entityManagerEntry = tryToFindEntityManagerEntryInTarget(context.getTarget());
+
+            if(entityManagerEntry == null)
+            {
+                throw unsupportedUsage(context);
+            }
+
+            entityManager = entityManagerEntry.getEntityManager();
+            entityManagerId = entityManagerEntry.getPersistenceContextEntry().getUnitName();
+
+            //might happen due to special add-ons - don't change it!
+            if(entityManager == null)
+            {
+                //TODO log warning in project stage dev.
+                return context.proceed();
+            }
+        }
+        else
+        {
+            entityManager = (EntityManager) this.beanManager.getReference(entityManagerBean, EntityManager.class,
+                    this.beanManager.createCreationalContext(entityManagerBean));
+        }
+
+        if (entityManagerMap.get() == null)
+        {
+            entityManagerMap.set(new HashMap<String, EntityManager>());
+        }
+        entityManagerMap.get().put(entityManagerId, entityManager);
+        // log.info("growing: " + ems.get().size());
+
+        if (refCount.get() == null)
+        {
+            refCount.set(new AtomicInteger(0));
+        }
+
+        EntityTransaction transaction = entityManager.getTransaction();
+
+        if(entityManagerEntry != null)
+        {
+            //only in case of add-ons synchronize
+            //-> nested calls (across beans) which share the same entity manager aren't supported
+            //noinspection SynchronizationOnLocalVariableOrMethodParameter
+            synchronized (entityManager)
+            {
+                return proceedMethodInTransaction(context,
+                                                  entityManagerEntry,
+                                                  entityManager,
+                                                  transaction);
+            }
+        }
+        //we don't have a shared entity manager
+        return proceedMethodInTransaction(context,
+                                          entityManagerEntry,
+                                          entityManager,
+                                          transaction);
+
+    }
+
+    private Object proceedMethodInTransaction(InvocationContext context,
+                                              EntityManagerEntry entityManagerEntry,
+                                              EntityManager entityManager,
+                                              EntityTransaction transaction)
+            throws Exception
+    {
+        // used to store any exception we get from the services
+        Exception firstException = null;
+
+        try
+        {
+            if(!transaction.isActive())
+            {
+                transaction.begin();
+            }
+            refCount.get().incrementAndGet();
+
+            return context.proceed();
+
+        }
+        catch(Exception e)
+        {
+            firstException = e;
+
+            // we only cleanup and rollback all open transactions in the outermost interceptor!
+            // this way, we allow inner functions to catch and handle exceptions properly.
+            if (refCount.get().intValue() == 1)
+            {
+                for (EntityManager currentEntityManager : entityManagerMap.get().values())
+                {
+                    transaction = currentEntityManager.getTransaction();
+                    if (transaction != null && transaction.isActive())
+                    {
+                        try
+                        {
+                            transaction.rollback();
+                        }
+                        catch (Exception eRollback)
+                        {
+                            logger.log(Level.SEVERE, "Got additional Exception while subsequently " +
+                                    "rolling back other SQL transactions", eRollback);
+                        }
+
+                    }
+                }
+
+                refCount.remove();
+
+                // drop all EntityManagers from the ThreadLocal
+                entityManagerMap.remove();
+            }
+
+            // rethrow the exception
+            throw e;
+
+        }
+        finally
+        {
+            if (refCount.get() != null)
+            {
+                refCount.get().decrementAndGet();
+
+
+                // will get set if we got an Exception while committing
+                // in this case, we rollback all later transactions too.
+                boolean commitFailed = false;
+
+                // commit all open transactions in the outermost interceptor!
+                // this is a 'JTA for poor men' only, and will not guaranty
+                // commit stability over various databases!
+                if (refCount.get().intValue() == 0)
+                {
+
+                    // only commit all transactions if we didn't rollback
+                    // them already
+                    if (firstException == null)
+                    {
+                        for (EntityManager currentEntityManager : entityManagerMap.get().values())
+                        {
+                            transaction = currentEntityManager.getTransaction();
+                            if(transaction != null && transaction.isActive())
+                            {
+                                try
+                                {
+                                    if (!commitFailed)
+                                    {
+                                        transaction.commit();
+                                    }
+                                    else
+                                    {
+                                        transaction.rollback();
+                                    }
+                                }
+                                catch (Exception e)
+                                {
+                                    firstException = e;
+                                    commitFailed = true;
+                                }
+                            }
+                        }
+                    }
+
+                    // finally remove all ThreadLocals
+                    refCount.remove();
+                    entityManagerMap.remove();
+                    if (commitFailed)
+                    {
+                        //noinspection ThrowFromFinallyBlock
+                        throw firstException;
+                    }
+                    else
+                    {
+                        //commit was successful and entity manager of bean was used
+                        //(and not an entity manager of a producer) which isn't of type extended
+                        if(entityManagerEntry != null && entityManager != null && entityManager.isOpen() &&
+                                !entityManagerEntry.getPersistenceContextEntry().isExtended())
+                        {
+                            entityManager.clear();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * needed for special add-ons - don't change it!
+     */
+    private EntityManagerEntry tryToFindEntityManagerEntryInTarget(Object target)
+    {
+        Map<String, PersistenceContextMetaEntry> mapping = persistenceContextMetaEntries.get(getClassLoader());
+
+        mapping = initMapping(mapping);
+
+        String key = target.getClass().getName();
+        PersistenceContextMetaEntry persistenceContextEntry = mapping.get(key);
+
+        if( persistenceContextEntry != null && noFieldMarker.equals(persistenceContextEntry.getFieldName()))
+        {
+            return null;
+        }
+
+        if(persistenceContextEntry == null)
+        {
+            persistenceContextEntry = findPersistenceContextEntry(target.getClass());
+
+            if(persistenceContextEntry == null)
+            {
+                mapping.put(key, new PersistenceContextMetaEntry(
+                        Object.class, noFieldMarker, Default.class.getName(), false));
+                return null;
+            }
+
+            mapping.put(key, persistenceContextEntry);
+        }
+
+        Field entityManagerField;
+        try
+        {
+            entityManagerField = persistenceContextEntry.getSourceClass()
+                    .getDeclaredField(persistenceContextEntry.getFieldName());
+        }
+        catch (NoSuchFieldException e)
+        {
+            //TODO add logging in case of project stage dev.
+            return null;
+        }
+
+        entityManagerField.setAccessible(true);
+        try
+        {
+            EntityManager entityManager = (EntityManager)entityManagerField.get(target);
+            return new EntityManagerEntry(entityManager, persistenceContextEntry);
+        }
+        catch (IllegalAccessException e)
+        {
+            //TODO add logging in case of project stage dev.
+            return null;
+        }
+    }
+
+    private synchronized Map<String, PersistenceContextMetaEntry> initMapping(
+            Map<String, PersistenceContextMetaEntry> mapping)
+    {
+        if(mapping == null)
+        {
+            mapping = new ConcurrentHashMap<String, PersistenceContextMetaEntry>();
+            persistenceContextMetaEntries.put(getClassLoader(), mapping);
+        }
+        return mapping;
+    }
+
+    private PersistenceContextMetaEntry findPersistenceContextEntry(Class target)
+    {
+        //TODO support other injection types
+        Class currentParamClass = target;
+        PersistenceContext persistenceContext;
+        while (currentParamClass != null && !Object.class.getName().equals(currentParamClass.getName()))
+        {
+            for(Field currentField : currentParamClass.getDeclaredFields())
+            {
+                persistenceContext = currentField.getAnnotation(PersistenceContext.class);
+                if(persistenceContext != null)
+                {
+                    return new PersistenceContextMetaEntry(
+                                   currentParamClass,
+                                   currentField.getName(),
+                                   persistenceContext.unitName(),
+                                   PersistenceContextType.EXTENDED.equals(persistenceContext.type()));
+                }
+            }
+            currentParamClass = currentParamClass.getSuperclass();
+        }
+
+        return null;
+    }
+
+    private ClassLoader getClassLoader()
+    {
+        return ClassUtils.getClassLoader(null);
+    }
+
+    private IllegalStateException unsupportedUsage(InvocationContext context)
+    {
+        String target;
+
+        target = context.getTarget().getClass().getName();
+        if (context.getMethod().isAnnotationPresent(Transactional.class))
+        {
+            target += "." + context.getMethod().getName();
+        }
+
+        return new IllegalStateException("Please check your implementation! " +
+                "There is no @Transactional or @Transactional(MyQualifier.class) or @PersistenceContext at "
+                + target + " Please check the documentation for the correct usage or contact the mailing list. " +
+                "Hint: @Transactional just allows one qualifier -> using multiple Entity-Managers " +
+                "(-> different qualifiers) within ONE intercepted method isn't supported.");
+    }
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/TransactionalInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/TransactionalInterceptor.java?rev=1071849&r1=1071848&r2=1071849&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/TransactionalInterceptor.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/TransactionalInterceptor.java Fri Feb 18 00:56:07 2011
@@ -19,36 +19,18 @@
 package org.apache.myfaces.extensions.cdi.jpa.impl;
 
 import org.apache.myfaces.extensions.cdi.jpa.api.Transactional;
-import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
-import org.apache.myfaces.extensions.cdi.core.impl.util.AnyLiteral;
+import org.apache.myfaces.extensions.cdi.jpa.impl.spi.PersistenceStrategy;
 
-import javax.enterprise.inject.Default;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
 import javax.inject.Inject;
 import javax.interceptor.AroundInvoke;
 import javax.interceptor.Interceptor;
 import javax.interceptor.InvocationContext;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
 import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.Map;
-import java.util.HashSet;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * Interceptor for wrapping transactional database requests.
  *
- * @author Mark Struberg
+ * @author Gerhard Petracek
  */
 @Interceptor
 @Transactional
@@ -56,365 +38,12 @@ public class TransactionalInterceptor im
 {
     private static final long serialVersionUID = -812054233068559930L;
 
-    //don't use final in interceptors
-    private static String noFieldMarker = TransactionalInterceptor.class.getName() + ":DEFAULT_FIELD";
-
     @Inject
-    private BeanManager beanManager;
-
-    private static transient ThreadLocal<AtomicInteger> refCount = new ThreadLocal<AtomicInteger>();
-
-    protected final Logger logger = Logger.getLogger(TransactionalInterceptor.class.getName());
-
-    /** key=qualifier name, value= EntityManager */
-    private static transient ThreadLocal<HashMap<String, EntityManager>> entityManagerMap =
-            new ThreadLocal<HashMap<String, EntityManager>>();
-
-    private static transient Map<ClassLoader, Map<String, PersistenceContextMetaEntry>> persistenceContextMetaEntries =
-            new ConcurrentHashMap<ClassLoader, Map<String, PersistenceContextMetaEntry>>();
-
-    /** 1 ms  in nanoTime ticks */
-    final static long LONG_MILLISECOND = 1000000L;
-    final static long LONG_RUNNING_THRESHOLD = 300L * LONG_MILLISECOND;
+    private PersistenceStrategy persistenceStrategy;
 
     @AroundInvoke
     public Object invoke(InvocationContext context) throws Exception
     {
-        Transactional transactionalAnnotation = context.getMethod().getAnnotation(Transactional.class);
-
-        if (transactionalAnnotation == null)
-        {
-            transactionalAnnotation = context.getTarget().getClass().getAnnotation(Transactional.class);
-        }
-
-        Class<? extends Annotation> qualifierClass = Default.class;
-        if (transactionalAnnotation != null)
-        {
-            qualifierClass = transactionalAnnotation.qualifier();
-        }
-
-        Set<Bean<?>> entityManagerBeans = beanManager.getBeans(EntityManager.class, new AnyLiteral());
-        if (entityManagerBeans == null)
-        {
-            entityManagerBeans = new HashSet<Bean<?>>();
-        }
-        Bean<EntityManager> entityManagerBean = null;
-
-        it:
-        for (Bean<?> currentEntityManagerBean : entityManagerBeans)
-        {
-            Set<Annotation> foundQualifierAnnotations = currentEntityManagerBean.getQualifiers();
-
-            for (Annotation currentQualifierAnnotation : foundQualifierAnnotations)
-            {
-                if (currentQualifierAnnotation.annotationType().equals(qualifierClass))
-                {
-                    entityManagerBean = (Bean<EntityManager>) currentEntityManagerBean;
-                    break it;
-                }
-            }
-        }
-
-        EntityManagerEntry entityManagerEntry = null;
-        EntityManager entityManager;
-
-        String entityManagerId = qualifierClass.getName();
-        if (entityManagerBean == null)
-        {
-            //support for special add-ons which introduce backward compatibility - resolves the injected entity manager
-            entityManagerEntry = tryToFindEntityManagerEntryInTarget(context.getTarget());
-
-            if(entityManagerEntry == null)
-            {
-                throw unsupportedUsage(context);
-            }
-
-            entityManager = entityManagerEntry.getEntityManager();
-            entityManagerId = entityManagerEntry.getPersistenceContextEntry().getUnitName();
-
-            //might happen due to special add-ons - don't change it!
-            if(entityManager == null)
-            {
-                //TODO log warning in project stage dev.
-                return context.proceed();
-            }
-        }
-        else
-        {
-            entityManager = (EntityManager) this.beanManager.getReference(entityManagerBean, EntityManager.class,
-                    this.beanManager.createCreationalContext(entityManagerBean));
-        }
-
-        if (entityManagerMap.get() == null)
-        {
-            entityManagerMap.set(new HashMap<String, EntityManager>());
-        }
-        entityManagerMap.get().put(entityManagerId, entityManager);
-        // log.info("growing: " + ems.get().size());
-
-        if (refCount.get() == null)
-        {
-            refCount.set(new AtomicInteger(0));
-        }
-
-        EntityTransaction transaction = entityManager.getTransaction();
-
-        if(entityManagerEntry != null)
-        {
-            //only in case of add-ons synchronize
-            //-> nested calls (across beans) which share the same entity manager aren't supported
-            //noinspection SynchronizationOnLocalVariableOrMethodParameter
-            synchronized (entityManager)
-            {
-                return proceedMethodInTransaction(context,
-                                                  entityManagerEntry,
-                                                  entityManager,
-                                                  transaction);
-            }
-        }
-        //we don't have a shared entity manager
-        return proceedMethodInTransaction(context,
-                                          entityManagerEntry,
-                                          entityManager,
-                                          transaction);
-    }
-
-    private Object proceedMethodInTransaction(InvocationContext context,
-                                              EntityManagerEntry entityManagerEntry,
-                                              EntityManager entityManager,
-                                              EntityTransaction transaction)
-            throws Exception
-    {
-        // used to store any exception we get from the services
-        Exception firstException = null;
-
-        try
-        {
-            if(!transaction.isActive())
-            {
-                transaction.begin();
-            }
-            refCount.get().incrementAndGet();
-
-            return context.proceed();
-
-        }
-        catch(Exception e)
-        {
-            firstException = e;
-
-            // we only cleanup and rollback all open transactions in the outermost interceptor!
-            // this way, we allow inner functions to catch and handle exceptions properly.
-            if (refCount.get().intValue() == 1)
-            {
-                for (EntityManager currentEntityManager : entityManagerMap.get().values())
-                {
-                    transaction = currentEntityManager.getTransaction();
-                    if (transaction != null && transaction.isActive())
-                    {
-                        try
-                        {
-                            transaction.rollback();
-                        }
-                        catch (Exception eRollback)
-                        {
-                            logger.log(Level.SEVERE, "Got additional Exception while subsequently " +
-                                    "rolling back other SQL transactions", eRollback);
-                        }
-
-                    }
-                }
-
-                refCount.remove();
-
-                // drop all EntityManagers from the ThreadLocal
-                entityManagerMap.remove();
-            }
-
-            // rethrow the exception
-            throw e;
-
-        }
-        finally
-        {
-            if (refCount.get() != null)
-            {
-                refCount.get().decrementAndGet();
-
-
-                // will get set if we got an Exception while committing
-                // in this case, we rollback all later transactions too.
-                boolean commitFailed = false;
-
-                // commit all open transactions in the outermost interceptor!
-                // this is a 'JTA for poor men' only, and will not guaranty
-                // commit stability over various databases!
-                if (refCount.get().intValue() == 0)
-                {
-
-                    // only commit all transactions if we didn't rollback
-                    // them already
-                    if (firstException == null)
-                    {
-                        for (EntityManager currentEntityManager : entityManagerMap.get().values())
-                        {
-                            transaction = currentEntityManager.getTransaction();
-                            if(transaction != null && transaction.isActive())
-                            {
-                                try
-                                {
-                                    if (!commitFailed)
-                                    {
-                                        transaction.commit();
-                                    }
-                                    else
-                                    {
-                                        transaction.rollback();
-                                    }
-                                }
-                                catch (Exception e)
-                                {
-                                    firstException = e;
-                                    commitFailed = true;
-                                }
-                            }
-                        }
-                    }
-
-                    // finally remove all ThreadLocals
-                    refCount.remove();
-                    entityManagerMap.remove();
-                    if (commitFailed)
-                    {
-                        //noinspection ThrowFromFinallyBlock
-                        throw firstException;
-                    }
-                    else
-                    {
-                        //commit was successful and entity manager of bean was used
-                        //(and not an entity manager of a producer) which isn't of type extended
-                        if(entityManagerEntry != null && entityManager != null && entityManager.isOpen() &&
-                                !entityManagerEntry.getPersistenceContextEntry().isExtended())
-                        {
-                            entityManager.clear();
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /*
-     * needed for special add-ons - don't change it!
-     */
-    private EntityManagerEntry tryToFindEntityManagerEntryInTarget(Object target)
-    {
-        Map<String, PersistenceContextMetaEntry> mapping = persistenceContextMetaEntries.get(getClassLoader());
-
-        mapping = initMapping(mapping);
-
-        String key = target.getClass().getName();
-        PersistenceContextMetaEntry persistenceContextEntry = mapping.get(key);
-
-        if( persistenceContextEntry != null && noFieldMarker.equals(persistenceContextEntry.getFieldName()))
-        {
-            return null;
-        }
-
-        if(persistenceContextEntry == null)
-        {
-            persistenceContextEntry = findPersistenceContextEntry(target.getClass());
-
-            if(persistenceContextEntry == null)
-            {
-                mapping.put(key, new PersistenceContextMetaEntry(
-                        Object.class, noFieldMarker, Default.class.getName(), false));
-                return null;
-            }
-
-            mapping.put(key, persistenceContextEntry);
-        }
-
-        Field entityManagerField;
-        try
-        {
-            entityManagerField = persistenceContextEntry.getSourceClass()
-                    .getDeclaredField(persistenceContextEntry.getFieldName());
-        }
-        catch (NoSuchFieldException e)
-        {
-            //TODO add logging in case of project stage dev.
-            return null;
-        }
-
-        entityManagerField.setAccessible(true);
-        try
-        {
-            EntityManager entityManager = (EntityManager)entityManagerField.get(target);
-            return new EntityManagerEntry(entityManager, persistenceContextEntry);
-        }
-        catch (IllegalAccessException e)
-        {
-            //TODO add logging in case of project stage dev.
-            return null;
-        }
-    }
-
-    private synchronized Map<String, PersistenceContextMetaEntry> initMapping(
-            Map<String, PersistenceContextMetaEntry> mapping)
-    {
-        if(mapping == null)
-        {
-            mapping = new ConcurrentHashMap<String, PersistenceContextMetaEntry>();
-            persistenceContextMetaEntries.put(getClassLoader(), mapping);
-        }
-        return mapping;
-    }
-
-    private PersistenceContextMetaEntry findPersistenceContextEntry(Class target)
-    {
-        //TODO support other injection types
-        Class currentParamClass = target;
-        PersistenceContext persistenceContext;
-        while (currentParamClass != null && !Object.class.getName().equals(currentParamClass.getName()))
-        {
-            for(Field currentField : currentParamClass.getDeclaredFields())
-            {
-                persistenceContext = currentField.getAnnotation(PersistenceContext.class);
-                if(persistenceContext != null)
-                {
-                    return new PersistenceContextMetaEntry(
-                                   currentParamClass,
-                                   currentField.getName(),
-                                   persistenceContext.unitName(),
-                                   PersistenceContextType.EXTENDED.equals(persistenceContext.type()));
-                }
-            }
-            currentParamClass = currentParamClass.getSuperclass();
-        }
-
-        return null;
-    }
-
-    private ClassLoader getClassLoader()
-    {
-        return ClassUtils.getClassLoader(null);
-    }
-
-    private IllegalStateException unsupportedUsage(InvocationContext context)
-    {
-        String target;
-
-        target = context.getTarget().getClass().getName();
-        if (context.getMethod().isAnnotationPresent(Transactional.class))
-        {
-            target += "." + context.getMethod().getName();
-        }
-
-        return new IllegalStateException("Please check your implementation! " +
-                "There is no @Transactional or @Transactional(MyQualifier.class) or @PersistenceContext at "
-                + target + " Please check the documentation for the correct usage or contact the mailing list. " +
-                "Hint: @Transactional just allows one qualifier -> using multiple Entity-Managers " +
-                "(-> different qualifiers) within ONE intercepted method isn't supported.");
+        return this.persistenceStrategy.execute(context);
     }
 }

Added: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/PersistenceStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/PersistenceStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/PersistenceStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/spi/PersistenceStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,30 @@
+/*
+ * 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.myfaces.extensions.cdi.jpa.impl.spi;
+
+import org.apache.myfaces.extensions.cdi.core.impl.spi.InterceptorStrategy;
+
+/**
+ * Marker interface for a pluggable strategy for {@link org.apache.myfaces.extensions.cdi.jpa.api.Transactional}
+ *
+ * @author Gerhard Petracek
+ */
+public interface PersistenceStrategy extends InterceptorStrategy
+{
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/DefaultViewControllerStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/DefaultViewControllerStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/DefaultViewControllerStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/DefaultViewControllerStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,131 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.listener.phase;
+
+import org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.spi.ViewControllerStrategy;
+import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewConfigCache;
+import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.BeforePhase;
+import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.AfterPhase;
+import org.apache.myfaces.extensions.cdi.core.api.config.view.ViewConfig;
+import org.apache.myfaces.extensions.cdi.core.api.config.view.View;
+
+import javax.interceptor.InvocationContext;
+import javax.faces.context.FacesContext;
+import javax.enterprise.context.Dependent;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Dependent
+public class DefaultViewControllerStrategy implements ViewControllerStrategy
+{
+    private static final long serialVersionUID = -4380864019324445036L;
+
+    public Object execute(InvocationContext invocationContext) throws Exception
+    {
+        Object result = null;
+
+        if(invokeListenerMethod(invocationContext))
+        {
+            result = invocationContext.proceed();
+        }
+
+        return result;
+    }
+
+    private boolean invokeListenerMethod(InvocationContext invocationContext)
+    {
+        if(!isObserverMethod(invocationContext))
+        {
+            return true;
+        }
+
+        View view = getViewAnnotation(invocationContext);
+
+        String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
+
+        if(view.inline().length > 1 || !"".equals(view.inline()[0]))
+        {
+            return isMethodBoundToView(view.inline(), viewId);
+        }
+        return isMethodBoundToViewDefinition(view.value(), viewId);
+    }
+
+    private boolean isObserverMethod(InvocationContext invocationContext)
+    {
+        for(Annotation[] annotations : invocationContext.getMethod().getParameterAnnotations())
+        {
+            for(Annotation annotation : annotations)
+            {
+                if(BeforePhase.class.isAssignableFrom(annotation.annotationType()) ||
+                        AfterPhase.class.isAssignableFrom(annotation.annotationType()))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private View getViewAnnotation(InvocationContext invocationContext)
+    {
+        View view;
+        Method method = invocationContext.getMethod();
+        if(method.isAnnotationPresent(View.class))
+        {
+            view = method.getAnnotation(View.class);
+        }
+        else
+        {
+            view = method.getDeclaringClass().getAnnotation(View.class);
+        }
+        return view;
+    }
+
+    private boolean isMethodBoundToView(String[] viewIds, String viewId)
+    {
+        for(String current : viewIds)
+        {
+            if(current.equals(viewId))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isMethodBoundToViewDefinition (Class<? extends ViewConfig>[] viewDefinitions, String viewId)
+    {
+        for(Class<? extends ViewConfig> viewDefinition : viewDefinitions)
+        {
+            if(resolveViewId(viewDefinition).equals(viewId))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String resolveViewId(Class<? extends ViewConfig> viewDefinitionClass)
+    {
+        return ViewConfigCache.getViewDefinition(viewDefinitionClass).getViewId();
+    }
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/ViewControllerInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/ViewControllerInterceptor.java?rev=1071849&r1=1071848&r2=1071849&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/ViewControllerInterceptor.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/ViewControllerInterceptor.java Fri Feb 18 00:56:07 2011
@@ -20,16 +20,12 @@ package org.apache.myfaces.extensions.cd
 
 import org.apache.myfaces.extensions.cdi.core.api.config.view.View;
 import org.apache.myfaces.extensions.cdi.core.api.config.view.ViewConfig;
-import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.BeforePhase;
-import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.AfterPhase;
-import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewConfigCache;
+import org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.spi.ViewControllerStrategy;
 
-import javax.interceptor.Interceptor;
+import javax.inject.Inject;
 import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
 import javax.interceptor.InvocationContext;
-import javax.faces.context.FacesContext;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
 import java.io.Serializable;
 
 /**
@@ -42,96 +38,14 @@ public class ViewControllerInterceptor i
 {
     private static final long serialVersionUID = -1562171889458823736L;
 
-    interface PlaceHolderConfig extends ViewConfig {}
+    interface PlaceHolderConfig extends ViewConfig{}
+
+    @Inject
+    private ViewControllerStrategy viewControllerStrategy;
 
     @AroundInvoke
     public Object filterPhaseListenerMethods(InvocationContext invocationContext) throws Exception
     {
-        Object result = null;
-
-        if(invokeListenerMethod(invocationContext))
-        {
-            result = invocationContext.proceed();
-        }
-
-        return result;
-    }
-
-    private boolean invokeListenerMethod(InvocationContext invocationContext)
-    {
-        if(!isObserverMethod(invocationContext))
-        {
-            return true;
-        }
-
-        View view = getViewAnnotation(invocationContext);
-
-        String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
-
-        if(view.inline().length > 1 || !"".equals(view.inline()[0]))
-        {
-            return isMethodBoundToView(view.inline(), viewId);
-        }
-        return isMethodBoundToViewDefinition(view.value(), viewId);
-    }
-
-    private boolean isObserverMethod(InvocationContext invocationContext)
-    {
-        for(Annotation[] annotations : invocationContext.getMethod().getParameterAnnotations())
-        {
-            for(Annotation annotation : annotations)
-            {
-                if(BeforePhase.class.isAssignableFrom(annotation.annotationType()) ||
-                        AfterPhase.class.isAssignableFrom(annotation.annotationType()))
-                {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private View getViewAnnotation(InvocationContext invocationContext)
-    {
-        View view;
-        Method method = invocationContext.getMethod();
-        if(method.isAnnotationPresent(View.class))
-        {
-            view = method.getAnnotation(View.class);
-        }
-        else
-        {
-            view = method.getDeclaringClass().getAnnotation(View.class);
-        }
-        return view;
-    }
-
-    private boolean isMethodBoundToView(String[] viewIds, String viewId)
-    {
-        for(String current : viewIds)
-        {
-            if(current.equals(viewId))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isMethodBoundToViewDefinition (Class<? extends ViewConfig>[] viewDefinitions, String viewId)
-    {
-        for(Class<? extends ViewConfig> viewDefinition : viewDefinitions)
-        {
-            if(resolveViewId(viewDefinition).equals(viewId))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private String resolveViewId(Class<? extends ViewConfig> viewDefinitionClass)
-    {
-        return ViewConfigCache.getViewDefinition(viewDefinitionClass).getViewId();
+        return this.viewControllerStrategy.execute(invocationContext);
     }
 }

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/ViewControllerStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/ViewControllerStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/ViewControllerStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/listener/phase/spi/ViewControllerStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,30 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.listener.phase.spi;
+
+import org.apache.myfaces.extensions.cdi.core.impl.spi.InterceptorStrategy;
+
+/**
+ * Marker interface for a pluggable strategy for {@link org.apache.myfaces.extensions.cdi.core.api.config.view.View}
+ *
+ * @author Gerhard Petracek
+ */
+public interface ViewControllerStrategy extends InterceptorStrategy
+{
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/CloseConversationGroupInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/CloseConversationGroupInterceptor.java?rev=1071849&r1=1071848&r2=1071849&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/CloseConversationGroupInterceptor.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/CloseConversationGroupInterceptor.java Fri Feb 18 00:56:07 2011
@@ -19,13 +19,12 @@
 package org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation;
 
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.CloseConversationGroup;
-import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
+import org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi.CloseConversationGroupStrategy;
 
-import javax.interceptor.Interceptor;
+import javax.inject.Inject;
 import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
 import javax.interceptor.InvocationContext;
-import javax.inject.Inject;
-import java.lang.reflect.Method;
 import java.io.Serializable;
 
 /**
@@ -43,67 +42,11 @@ public class CloseConversationGroupInter
     private static final long serialVersionUID = -2440058119479555994L;
 
     @Inject
-    private WindowContext windowContext;
+    private CloseConversationGroupStrategy closeConversationGroupStrategy;
 
     @AroundInvoke
     public Object handleCloseConversation(InvocationContext invocationContext) throws Exception
     {
-        Object result = null;
-
-        CloseConversationGroup closeConversationGroup = getCloseConversationGroupAnnotation(invocationContext);
-
-        RuntimeException catchedException = null;
-
-        try
-        {
-            result = invocationContext.proceed();
-        }
-        catch (RuntimeException exception)
-        {
-            catchedException = exception;
-        }
-
-        if(isDefaultExceptionValue(closeConversationGroup) ||
-                (catchedException != null && checkExceptionToCatch(catchedException, closeConversationGroup.on())))
-        {
-            Class conversationGroup = getConversationGroup(invocationContext, closeConversationGroup);
-
-            this.windowContext.closeConversation(conversationGroup);
-        }
-        return result;
-    }
-
-    private Class getConversationGroup(InvocationContext invocationContext,
-                                       CloseConversationGroup closeConversationGroup)
-    {
-        Class conversationGroup = closeConversationGroup.group();
-
-        if(CloseConversationGroup.class.isAssignableFrom(conversationGroup))
-        {
-            conversationGroup = invocationContext.getMethod().getDeclaringClass();
-            //TODO support more use-cases
-        }
-        return conversationGroup;
-    }
-
-    private boolean checkExceptionToCatch(RuntimeException catchedException,
-                                          Class<? extends RuntimeException> specifiedException)
-    {
-        if(specifiedException.isAssignableFrom(catchedException.getClass()))
-        {
-            return true;
-        }
-        throw catchedException;
-    }
-
-    private CloseConversationGroup getCloseConversationGroupAnnotation(InvocationContext invocationContext)
-    {
-        Method method = invocationContext.getMethod();
-        return method.getAnnotation(CloseConversationGroup.class);
-    }
-
-    private boolean isDefaultExceptionValue(CloseConversationGroup closeConversationGroup)
-    {
-        return RuntimeException.class.getName().equals(closeConversationGroup.on().getName());
+        return this.closeConversationGroupStrategy.execute(invocationContext);
     }
 }

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/DefaultCloseConversationGroupStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/DefaultCloseConversationGroupStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/DefaultCloseConversationGroupStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/DefaultCloseConversationGroupStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,101 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi.CloseConversationGroupStrategy;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.CloseConversationGroup;
+
+import javax.interceptor.InvocationContext;
+import javax.enterprise.context.Dependent;
+import javax.inject.Inject;
+import java.lang.reflect.Method;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Dependent
+public class DefaultCloseConversationGroupStrategy implements CloseConversationGroupStrategy
+{
+    private static final long serialVersionUID = 3781434188201702757L;
+
+    @Inject
+    private WindowContext windowContext;
+
+    public Object execute(InvocationContext invocationContext) throws Exception
+    {
+        Object result = null;
+
+        CloseConversationGroup closeConversationGroup = getCloseConversationGroupAnnotation(invocationContext);
+
+        RuntimeException catchedException = null;
+
+        try
+        {
+            result = invocationContext.proceed();
+        }
+        catch (RuntimeException exception)
+        {
+            catchedException = exception;
+        }
+
+        if(isDefaultExceptionValue(closeConversationGroup) ||
+                (catchedException != null && checkExceptionToCatch(catchedException, closeConversationGroup.on())))
+        {
+            Class conversationGroup = getConversationGroup(invocationContext, closeConversationGroup);
+
+            this.windowContext.closeConversation(conversationGroup);
+        }
+        return result;
+    }
+
+    private Class getConversationGroup(InvocationContext invocationContext,
+                                       CloseConversationGroup closeConversationGroup)
+    {
+        Class conversationGroup = closeConversationGroup.group();
+
+        if(CloseConversationGroup.class.isAssignableFrom(conversationGroup))
+        {
+            conversationGroup = invocationContext.getMethod().getDeclaringClass();
+            //TODO support more use-cases
+        }
+        return conversationGroup;
+    }
+
+    private boolean checkExceptionToCatch(RuntimeException catchedException,
+                                          Class<? extends RuntimeException> specifiedException)
+    {
+        if(specifiedException.isAssignableFrom(catchedException.getClass()))
+        {
+            return true;
+        }
+        throw catchedException;
+    }
+
+    private CloseConversationGroup getCloseConversationGroupAnnotation(InvocationContext invocationContext)
+    {
+        Method method = invocationContext.getMethod();
+        return method.getAnnotation(CloseConversationGroup.class);
+    }
+
+    private boolean isDefaultExceptionValue(CloseConversationGroup closeConversationGroup)
+    {
+        return RuntimeException.class.getName().equals(closeConversationGroup.on().getName());
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/spi/CloseConversationGroupStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/spi/CloseConversationGroupStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/spi/CloseConversationGroupStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/scope/conversation/spi/CloseConversationGroupStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,31 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi;
+
+import org.apache.myfaces.extensions.cdi.core.impl.spi.InterceptorStrategy;
+
+/**
+ * Marker interface for a pluggable strategy for
+ * {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.CloseConversationGroup}
+ *
+ * @author Gerhard Petracek
+ */
+public interface CloseConversationGroupStrategy extends InterceptorStrategy
+{
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,71 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.security;
+
+import org.apache.myfaces.extensions.cdi.jsf.impl.security.spi.SecurityStrategy;
+import org.apache.myfaces.extensions.cdi.core.api.security.Secured;
+import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoter;
+import static org.apache.myfaces.extensions.cdi.core.impl.util.SecurityUtils.invokeVoters;
+
+import javax.inject.Inject;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.context.Dependent;
+import javax.interceptor.InvocationContext;
+import java.util.Arrays;
+import java.lang.reflect.Method;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Dependent
+public class DefaultSecurityStrategy implements SecurityStrategy
+{
+    private static final long serialVersionUID = -7999599690398948059L;
+
+    @Inject
+    private BeanManager beanManager;
+
+    public Object execute(InvocationContext invocationContext) throws Exception
+    {
+        Secured secured = getSecuredAnnotation(invocationContext);
+
+        Class<? extends AccessDecisionVoter>[] voterClasses = secured.value();
+
+        invokeVoters(invocationContext, this.beanManager, Arrays.asList(voterClasses), secured.errorView());
+
+        return invocationContext.proceed();
+    }
+
+    //TODO refactor it to a generic impl. and move it to an util class
+    private Secured getSecuredAnnotation(InvocationContext invocationContext)
+    {
+        Secured secured;
+        Method method = invocationContext.getMethod();
+
+        if(method.isAnnotationPresent(Secured.class))
+        {
+            secured = method.getAnnotation(Secured.class);
+        }
+        else
+        {
+            secured = method.getDeclaringClass().getAnnotation(Secured.class);
+        }
+        return secured;
+    }
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityInterceptor.java?rev=1071849&r1=1071848&r2=1071849&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityInterceptor.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityInterceptor.java Fri Feb 18 00:56:07 2011
@@ -18,18 +18,15 @@
  */
 package org.apache.myfaces.extensions.cdi.jsf.impl.security;
 
-import org.apache.myfaces.extensions.cdi.core.api.security.Secured;
 import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoter;
-import static org.apache.myfaces.extensions.cdi.core.impl.util.SecurityUtils.invokeVoters;
+import org.apache.myfaces.extensions.cdi.core.api.security.Secured;
+import org.apache.myfaces.extensions.cdi.jsf.impl.security.spi.SecurityStrategy;
 
+import javax.inject.Inject;
 import javax.interceptor.AroundInvoke;
-import javax.interceptor.InvocationContext;
 import javax.interceptor.Interceptor;
-import javax.inject.Inject;
-import javax.enterprise.inject.spi.BeanManager;
-import java.lang.reflect.Method;
+import javax.interceptor.InvocationContext;
 import java.io.Serializable;
-import java.util.Arrays;
 
 /**
  * @author Gerhard Petracek
@@ -40,39 +37,14 @@ public class SecurityInterceptor impleme
 {
     private static final long serialVersionUID = -7094673146532371976L;
 
-    @Inject
-    private BeanManager beanManager;
+    interface PlaceHolderVoter extends AccessDecisionVoter {}
 
-    interface PlaceHolderVoter extends AccessDecisionVoter
-    {
-    }
+    @Inject
+    private SecurityStrategy securityStrategy;
 
     @AroundInvoke
     public Object filterDeniedInvocations(InvocationContext invocationContext) throws Exception
     {
-        Secured secured = getSecuredAnnotation(invocationContext);
-
-        Class<? extends AccessDecisionVoter>[] voterClasses = secured.value();
-
-        invokeVoters(invocationContext, this.beanManager, Arrays.asList(voterClasses), secured.errorView());
-
-        return invocationContext.proceed();
-    }
-
-    //TODO refactor it to a generic impl. and move it to an util class
-    private Secured getSecuredAnnotation(InvocationContext invocationContext)
-    {
-        Secured secured;
-        Method method = invocationContext.getMethod();
-
-        if(method.isAnnotationPresent(Secured.class))
-        {
-            secured = method.getAnnotation(Secured.class);
-        }
-        else
-        {
-            secured = method.getDeclaringClass().getAnnotation(Secured.class);
-        }
-        return secured;
+        return this.securityStrategy.execute(invocationContext);
     }
 }

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/SecurityStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/SecurityStrategy.java?rev=1071849&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/SecurityStrategy.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/spi/SecurityStrategy.java Fri Feb 18 00:56:07 2011
@@ -0,0 +1,30 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf.impl.security.spi;
+
+import org.apache.myfaces.extensions.cdi.core.impl.spi.InterceptorStrategy;
+
+/**
+ * Marker interface for a pluggable strategy for {@link org.apache.myfaces.extensions.cdi.core.api.security.Secured}
+ *
+ * @author Gerhard Petracek
+ */
+public interface SecurityStrategy extends InterceptorStrategy
+{
+}