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
+{
+}