[seam-commits] Seam SVN: r12333 - in modules/faces/trunk/src: main/java/org/jboss/seam/faces/context/conversation and 5 other directories.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Tue Mar 30 18:44:08 EDT 2010
Author: lincolnthree
Date: 2010-03-30 18:44:07 -0400 (Tue, 30 Mar 2010)
New Revision: 12333
Added:
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtension.java
modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtensionTest.java
modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/ImproperlyAnnotatedBean.java
Removed:
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/RetainsConversation.java
Modified:
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/Begin.java
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundary.java
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptor.java
modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/End.java
modules/faces/trunk/src/main/java/org/jboss/seam/faces/util/Annotations.java
modules/faces/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptorTest.java
modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationalBean.java
modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationTestObject.java
modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationsTest.java
Log:
* Major updates for @Begin(permit={...}) and @End(permit={...})
* Added the FacesAnnotationAdapterExtension to help ease migration from legacy (DOA) JSF2 bean annotations.
* Added the Annotations utility class and Tests
* Tests tests tests!
Added: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtension.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtension.java (rev 0)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtension.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -0,0 +1,152 @@
+package org.jboss.seam.faces.context;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.ProcessBean;
+
+/**
+ * Alias the JSF scope annotations to the CDI scope annotations. If a JSF scope
+ * annotation is detected, advise the developer to update the code to use the
+ * equivalent CDI scope annotation. Forbid the developer from using the JSF
+ * managed bean annotation.
+ *
+ * @author Dan Allen
+ */
+public class FacesAnnotationsAdapterExtension implements Extension
+{
+ private final Map<Class<? extends Annotation>, Class<? extends Annotation>> scopeAliasMapping;
+
+ /*
+ * For unit testing
+ */
+ static final Map<Class<?>, Class<? extends Annotation>> aliasedBeans = new HashMap<Class<?>, Class<? extends Annotation>>();
+
+ public FacesAnnotationsAdapterExtension()
+ {
+ scopeAliasMapping = new HashMap<Class<? extends Annotation>, Class<? extends Annotation>>(3);
+ scopeAliasMapping.put(javax.faces.bean.RequestScoped.class, javax.enterprise.context.RequestScoped.class);
+ scopeAliasMapping.put(javax.faces.bean.SessionScoped.class, javax.enterprise.context.SessionScoped.class);
+ scopeAliasMapping.put(javax.faces.bean.ApplicationScoped.class, javax.enterprise.context.ApplicationScoped.class);
+ }
+
+ public void aliasJsfScopeIfDetected(@Observes final ProcessAnnotatedType<Object> annotatedType)
+ {
+ for (Class<? extends Annotation> scope : scopeAliasMapping.keySet())
+ {
+ if (annotatedType.getAnnotatedType().isAnnotationPresent(scope))
+ {
+ System.out.println("WARNING: Please annotate class " + annotatedType.getAnnotatedType().getJavaClass() + " with @" + scopeAliasMapping.get(scope).getName() + " instead of @" + scope.getName());
+ aliasedBeans.put(annotatedType.getAnnotatedType().getJavaClass(), scope);
+ annotatedType.setAnnotatedType(decorateType(annotatedType.getAnnotatedType(), scope));
+ break;
+ }
+ }
+ }
+
+ public void failIfJsfManagedBeanAnnotationPresent(@Observes final ProcessBean<?> bean)
+ {
+ if (bean.getAnnotated().isAnnotationPresent(javax.faces.bean.ManagedBean.class))
+ {
+ bean.addDefinitionError(new RuntimeException("Use of @javax.faces.bean.ManagedBean is forbidden. Please use @javax.inject.Named instead."));
+ }
+ }
+
+ private Class<? extends Annotation> getCdiScopeFor(final Class<? extends Annotation> jsfScope)
+ {
+ return scopeAliasMapping.get(jsfScope);
+ }
+
+ private AnnotatedType<Object> decorateType(final AnnotatedType<Object> type, final Class<? extends Annotation> jsfScope)
+ {
+ final Class<? extends Annotation> cdiScope = getCdiScopeFor(jsfScope);
+ final Annotation cdiScopeAnnotation = new Annotation()
+ {
+ public Class<? extends Annotation> annotationType()
+ {
+ return cdiScope;
+ }
+ };
+
+ final Set<Annotation> maskedAnnotations = new HashSet<Annotation>(type.getAnnotations());
+ maskedAnnotations.remove(type.getAnnotation(jsfScope));
+ maskedAnnotations.add(cdiScopeAnnotation);
+
+ return new AnnotatedType<Object>()
+ {
+ public Class<Object> getJavaClass()
+ {
+ return type.getJavaClass();
+ }
+
+ public Set<AnnotatedConstructor<Object>> getConstructors()
+ {
+ return type.getConstructors();
+ }
+
+ public Set<AnnotatedMethod<? super Object>> getMethods()
+ {
+ return type.getMethods();
+ }
+
+ public Set<AnnotatedField<? super Object>> getFields()
+ {
+ return type.getFields();
+ }
+
+ public Type getBaseType()
+ {
+ return type.getBaseType();
+ }
+
+ public Set<Type> getTypeClosure()
+ {
+ return type.getTypeClosure();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Annotation> T getAnnotation(final Class<T> annotationType)
+ {
+ if (annotationType == jsfScope)
+ {
+ return null;
+ }
+ else if (annotationType == cdiScope)
+ {
+ return (T) cdiScopeAnnotation;
+ }
+
+ return type.getAnnotation(annotationType);
+ }
+
+ public Set<Annotation> getAnnotations()
+ {
+ return maskedAnnotations;
+ }
+
+ public boolean isAnnotationPresent(final Class<? extends Annotation> annotationType)
+ {
+ if (annotationType == jsfScope)
+ {
+ return false;
+ }
+ else if (annotationType == cdiScope)
+ {
+ return true;
+ }
+ return type.isAnnotationPresent(annotationType);
+ }
+ };
+ }
+}
\ No newline at end of file
Modified: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/Begin.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/Begin.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/Begin.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -8,15 +8,15 @@
import java.lang.annotation.Target;
import javax.enterprise.context.Conversation;
+import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
/**
- * Marks the beginning of a persistent {@link Conversation}.
+ * Begins a persistent {@link Conversation}.
*
*<p>
- * <b>Note:</b> If this method throws an exception, the conversation will be
- * discarded, unless the exception is annotated with @
- * {@link RetainsConversation}
+ * <b>Note:</b> Unless the exception is of a permitted type, if this method
+ * throws an exception, the conversation will not begin.
*
* @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
*/
@@ -27,9 +27,34 @@
public @interface Begin
{
/**
- * The new conversation ID. Seam will Generate a conversation ID if left
- * blank. If a conversation with the ID already exists, TODO what should we
- * do?
+ * Sets the new {@link Conversation} ID. Seam will Generate a conversation ID
+ * if left blank.
+ * <p>
+ * If a conversation with the ID already exists... TODO what should we do?
+ * <p>
+ * TODO test default conversation ID functionality
*/
+ @Nonbinding
String id() default "";
+
+ /**
+ * Sets the {@link Conversation} timeout period, in milliseconds (E.g.: 5000
+ * = 5 seconds.)
+ * <p>
+ * TODO implement timeout support on @Begin
+ */
+ @Nonbinding
+ long timeout() default -1;
+
+ /**
+ * Sets the exception types for which, when encountered during a method
+ * invocation, the {@link Conversation} will still begin. (In other words:
+ * Permitted exceptions do not abort @{@link Begin})
+ * <p>
+ * <b>By default:</b> { empty array } - all encountered exceptions will
+ * prevent the {@link Conversation} from beginning.
+ */
+ @Nonbinding
+ Class<? extends Exception>[] permit() default {};
+
}
\ No newline at end of file
Modified: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundary.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundary.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundary.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -12,6 +12,11 @@
/**
* Parent annotation for @{@link Begin} and @{@link End}
+ * <p>
+ * <b>Note:</b> This should never be used.
+ * <p>
+ * TODO: Should we warn at startup if @{@link Begin} and @{@link End} are used
+ * together on the same method?
*
* @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
*/
Modified: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptor.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptor.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptor.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -4,8 +4,9 @@
package org.jboss.seam.faces.context.conversation;
import java.io.Serializable;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
import javax.enterprise.context.Conversation;
import javax.inject.Inject;
@@ -17,10 +18,10 @@
import org.slf4j.Logger;
/**
- * Intercepts methods annotated as Conversational entry points.
+ * Intercepts methods annotated as Conversational entry points: @{@link Begin}
+ * and @{@link End}
*
* @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
- *
*/
@ConversationBoundary
@Interceptor
@@ -35,26 +36,76 @@
Conversation conversation;
@AroundInvoke
- public Object before(final InvocationContext ctx) throws Exception
+ public Object around(final InvocationContext ctx) throws Exception
{
Object result = null;
+
+ try
+ {
+ if (Annotations.hasAnnotation(ctx.getMethod(), Begin.class))
+ {
+ beginConversation(ctx);
+ }
+
+ result = ctx.proceed();
+
+ if (Annotations.hasAnnotation(ctx.getMethod(), End.class))
+ {
+ endConversation(ctx);
+ }
+ }
+ catch (Exception e)
+ {
+ handleExceptionBegin(ctx, e);
+ handleExceptionEnd(ctx, e);
+ throw e;
+ }
+
+ return result;
+ }
+
+ private void handleExceptionBegin(final InvocationContext ctx, final Exception e)
+ {
if (Annotations.hasAnnotation(ctx.getMethod(), Begin.class))
{
- result = beginConversation(ctx);
+ List<? extends Class<? extends Exception>> typesPermittedByBegin = getPermittedExceptionTypesBegin(ctx.getMethod());
+ for (Class<? extends Exception> type : typesPermittedByBegin)
+ {
+ if (type.isInstance(e) == false)
+ {
+ log.debug("Aborting conversation: (#0) for method: (#1.#2(...)) - Encountered Exception of type (#4), which is not in the list of exceptions permitted by @Begin.", new Object[] { conversation.getId(), ctx.getMethod().getDeclaringClass().getName(), ctx.getMethod().getName(), e.getClass().getName() });
+ conversation.end();
+ }
+ }
}
+ }
+
+ private void handleExceptionEnd(final InvocationContext ctx, final Exception e)
+ {
if (Annotations.hasAnnotation(ctx.getMethod(), End.class))
{
- endConversation(ctx);
+ List<? extends Class<? extends Exception>> typesPermittedByEnd = getPermittedExceptionTypesEnd(ctx.getMethod());
+ boolean permitted = false;
+ for (Class<? extends Exception> type : typesPermittedByEnd)
+ {
+ if (type.isInstance(e))
+ {
+ permitted = true;
+ conversation.end();
+ }
+ }
+ if (!permitted)
+ {
+ log.debug("Conversation will remain open: (#0) for method: (#1.#2(...)) - Encountered Exception of type (#4), which is not in the list of exceptions permitted by @End.", new Object[] { conversation.getId(), ctx.getMethod().getDeclaringClass().getName(), ctx.getMethod().getName(), e.getClass().getName() });
+ }
}
-
- return result;
}
- private Object beginConversation(final InvocationContext ctx) throws Exception
+ private void beginConversation(final InvocationContext ctx) throws Exception
{
String cid = getConversationId(ctx.getMethod());
- if (cid != null)
+ if ((cid != null) && !"".equals(cid))
{
conversation.begin(cid);
}
@@ -62,47 +113,27 @@
{
conversation.begin();
}
-
- log.debug("Began conversation: (#0) on method: (#1.#2(...))", new Object[] { conversation.getId(), ctx.getMethod().getDeclaringClass().getName(), ctx.getMethod().getName() });
-
- try
- {
- Object result = ctx.proceed();
- return result;
- }
- catch (Exception e)
- {
- conversation.end();
- throw e;
- }
+ log.debug("Began conversation: (#0) before method: (#1.#2(...))", new Object[] { conversation.getId(), ctx.getMethod().getDeclaringClass().getName(), ctx.getMethod().getName() });
}
private void endConversation(final InvocationContext ctx)
{
+ log.debug("Ending conversation: (#0) after method: (#1.#2(...))", new Object[] { conversation.getId(), ctx.getMethod().getDeclaringClass().getName(), ctx.getMethod().getName() });
conversation.end();
}
private String getConversationId(final Method m)
{
- String result = null;
- for (Annotation a : m.getAnnotations())
- {
- if (a.annotationType().isAnnotationPresent(Begin.class))
- {
- result = a.annotationType().getAnnotation(Begin.class).id();
- }
- }
+ return Annotations.getAnnotation(m, Begin.class).id();
+ }
- if (result == null)
- {
- for (Annotation a : m.getDeclaringClass().getAnnotations())
- {
- if (a.annotationType().isAnnotationPresent(Begin.class))
- {
- result = a.annotationType().getAnnotation(Begin.class).id();
- }
- }
- }
- return result;
+ private List<? extends Class<? extends Exception>> getPermittedExceptionTypesBegin(final Method m)
+ {
+ return Arrays.asList(Annotations.getAnnotation(m, Begin.class).permit());
}
+
+ private List<? extends Class<? extends Exception>> getPermittedExceptionTypesEnd(final Method m)
+ {
+ return Arrays.asList(Annotations.getAnnotation(m, End.class).permit());
+ }
}
Modified: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/End.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/End.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/End.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -8,15 +8,15 @@
import java.lang.annotation.Target;
import javax.enterprise.context.Conversation;
+import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
/**
- * Marks the beginning of a persistent {@link Conversation}.
+ * Ends a persistent {@link Conversation}.
*
*<p>
- * <b>Note:</b> If this method throws an exception, the conversation will be
- * discarded, unless the exception is annotated with @
- * {@link RetainsConversation}
+ * <b>Note:</b> Unless the exception is of a permitted type, if this method
+ * throws an exception, the conversation will not be ended.
*
* @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
*/
@@ -27,9 +27,14 @@
public @interface End
{
/**
- * The new conversation ID. Seam will Generate a conversation ID if left
- * blank. If a conversation with the ID already exists, TODO what should we
- * do?
+ * Sets the exception types for which, when encountered during a method
+ * invocation, the {@link Conversation} will still end. (In other words:
+ * These exceptions do not abort @{@link End})
+ * <p>
+ * <b>By default:</b> { empty array } - all encountered exceptions will cause
+ * the {@link Conversation} to remain open.
*/
- String id() default "";
+ @Nonbinding
+ Class<? extends Exception>[] permit() default {};
+
}
\ No newline at end of file
Deleted: modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/RetainsConversation.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/RetainsConversation.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/context/conversation/RetainsConversation.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -1,35 +0,0 @@
-package org.jboss.seam.faces.context.conversation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import javax.enterprise.context.Conversation;
-import javax.inject.Qualifier;
-
-/**
- * Marks the beginning of a persistent {@link Conversation}.
- *
- *<p>
- * <b>Note:</b> If this method throws an exception, the conversation will be
- * discarded, unless the exception is annotated with {@link RetainsConversation}
- *
- * @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
- */
- at Qualifier
- at Target( { FIELD, PARAMETER })
- at Retention(RUNTIME)
- at Documented
-public @interface RetainsConversation
-{
- /**
- * The new conversation ID. Seam will Generate a conversation ID if left
- * blank. If a conversation with the ID already exists, TODO what should we
- * do?
- */
- String id() default "";
-}
\ No newline at end of file
Modified: modules/faces/trunk/src/main/java/org/jboss/seam/faces/util/Annotations.java
===================================================================
--- modules/faces/trunk/src/main/java/org/jboss/seam/faces/util/Annotations.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/java/org/jboss/seam/faces/util/Annotations.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -20,6 +20,9 @@
* Discover if a Method <b>m</b> has been annotated with <b>type</b>. This
* also discovers annotations defined through a @{@link Stereotype}.
*
+ * @param m The method to inspect.
+ * @param type The targeted annotation class
+ *
* @return True if annotation is present either on the method itself, or on
* the declaring class of the method. Returns false if the annotation
* is not present.
@@ -53,6 +56,9 @@
* Discover if a Class <b>c</b> has been annotated with <b>type</b>. This
* also discovers annotations defined through a @{@link Stereotype}.
*
+ * @param c The class to inspect.
+ * @param type The targeted annotation class
+ *
* @return True if annotation is present either on class, false if the
* annotation is not present.
*/
@@ -75,4 +81,60 @@
}
return result;
}
+
+ /**
+ * Inspect method <b>m</b> for a specific <b>type</b> of annotation. This
+ * also discovers annotations defined through a @ {@link Stereotype}.
+ *
+ * @param m The method to inspect.
+ * @param type The targeted annotation class
+ *
+ * @return The annotation instance found on this method or enclosing class,
+ * or null if no matching annotation was found.
+ */
+ public static <A extends Annotation> A getAnnotation(final Method m, final Class<A> type)
+ {
+ A result = m.getAnnotation(type);
+ if (result == null)
+ {
+ for (Annotation a : m.getAnnotations())
+ {
+ if (a.annotationType().isAnnotationPresent(type))
+ {
+ result = a.annotationType().getAnnotation(type);
+ }
+ }
+ }
+ if (result == null)
+ {
+ result = getAnnotation(m.getDeclaringClass(), type);
+ }
+ return result;
+ }
+
+ /**
+ * Inspect class <b>c</b> for a specific <b>type</b> of annotation. This also
+ * discovers annotations defined through a @ {@link Stereotype}.
+ *
+ * @param c The class to inspect.
+ * @param type The targeted annotation class
+ *
+ * @return The annotation instance found on this class, or null if no
+ * matching annotation was found.
+ */
+ public static <A extends Annotation> A getAnnotation(final Class<?> c, final Class<A> type)
+ {
+ A result = c.getAnnotation(type);
+ if (result == null)
+ {
+ for (Annotation a : c.getAnnotations())
+ {
+ if (a.annotationType().isAnnotationPresent(type))
+ {
+ result = a.annotationType().getAnnotation(type);
+ }
+ }
+ }
+ return result;
+ }
}
Modified: modules/faces/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
===================================================================
--- modules/faces/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension 2010-03-30 22:44:07 UTC (rev 12333)
@@ -1,2 +1,3 @@
org.jboss.seam.faces.context.ViewScopedExtension
-org.jboss.seam.faces.context.FlashScopedExtension
\ No newline at end of file
+org.jboss.seam.faces.context.FlashScopedExtension
+org.jboss.seam.faces.context.FacesAnnotationsAdapterExtension
\ No newline at end of file
Added: modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtensionTest.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtensionTest.java (rev 0)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/FacesAnnotationsAdapterExtensionTest.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -0,0 +1,35 @@
+/**
+ *
+ */
+package org.jboss.seam.faces.context;
+
+import static org.junit.Assert.assertTrue;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ArchivePaths;
+import org.jboss.shrinkwrap.api.Archives;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.impl.base.asset.ByteArrayAsset;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * @author <a href="mailto:lincolnbaxter at gmail.com>Lincoln Baxter, III</a>
+ */
+ at RunWith(Arquillian.class)
+public class FacesAnnotationsAdapterExtensionTest
+{
+
+ @Deployment
+ public static JavaArchive createTestArchive()
+ {
+ return Archives.create("test.jar", JavaArchive.class).addClasses(ImproperlyAnnotatedBean.class).addManifestResource(new ByteArrayAsset(new byte[0]), ArchivePaths.create("beans.xml"));
+ }
+
+ @Test
+ public void testImproperlyAnnotatedClassIsCaptured()
+ {
+ assertTrue(FacesAnnotationsAdapterExtension.aliasedBeans.containsKey(ImproperlyAnnotatedBean.class));
+ }
+}
Added: modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/ImproperlyAnnotatedBean.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/ImproperlyAnnotatedBean.java (rev 0)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/ImproperlyAnnotatedBean.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -0,0 +1,15 @@
+/**
+ *
+ */
+package org.jboss.seam.faces.context;
+
+import javax.faces.bean.RequestScoped;
+
+/**
+ * @author <a href="mailto:lincolnbaxter at gmail.com>Lincoln Baxter, III</a>
+ *
+ */
+ at RequestScoped
+public class ImproperlyAnnotatedBean
+{
+}
Modified: modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptorTest.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptorTest.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationBoundaryInterceptorTest.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -61,4 +61,82 @@
assertTrue(conversation.isTransient());
assertTrue(interceptedBean.isConversationLongRunningDuringInvocation2());
}
+
+ @Test
+ public void testConversationAbortsBeginOnFatalException()
+ {
+ assertTrue(conversation.isTransient());
+ assertFalse(interceptedBean.isConversationLongRunningDuringInvocation3());
+
+ try
+ {
+ interceptedBean.beginAndThrowFatalException();
+ }
+ catch (Exception e)
+ {
+ // expected
+ }
+
+ assertTrue(conversation.isTransient());
+ assertTrue(interceptedBean.isConversationLongRunningDuringInvocation3());
+ }
+
+ @Test
+ public void testConversationBeginsOnPermittedException()
+ {
+ assertTrue(conversation.isTransient());
+ assertFalse(interceptedBean.isConversationLongRunningDuringInvocation4());
+
+ try
+ {
+ interceptedBean.beginAndThrowPermittedException();
+ }
+ catch (Exception e)
+ {
+ // expected
+ }
+
+ assertFalse(conversation.isTransient());
+ assertTrue(interceptedBean.isConversationLongRunningDuringInvocation4());
+ }
+
+ @Test
+ public void testConversationAbortsEndOnFatalException()
+ {
+ assertTrue(conversation.isTransient());
+ assertFalse(interceptedBean.isConversationLongRunningDuringInvocation5());
+
+ try
+ {
+ interceptedBean.begin();
+ interceptedBean.endAndThrowFatalException();
+ }
+ catch (Exception e)
+ {
+ // expected
+ }
+
+ assertFalse(conversation.isTransient());
+ assertTrue(interceptedBean.isConversationLongRunningDuringInvocation5());
+ }
+
+ @Test
+ public void testConversationEndsOnPermittedException()
+ {
+ assertTrue(conversation.isTransient());
+ assertFalse(interceptedBean.isConversationLongRunningDuringInvocation6());
+
+ try
+ {
+ interceptedBean.begin();
+ interceptedBean.endAndThrowPermittedException();
+ }
+ catch (Exception e)
+ {
+ // expected
+ }
+
+ assertTrue(conversation.isTransient());
+ assertTrue(interceptedBean.isConversationLongRunningDuringInvocation6());
+ }
}
Modified: modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationalBean.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationalBean.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/context/conversation/ConversationalBean.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -7,6 +7,8 @@
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
+import org.jboss.seam.faces.SeamFacesException;
+
/**
* @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
*
@@ -17,11 +19,20 @@
@Inject
Conversation conversation;
- private boolean conversationLongRunningDuringInvocation = false;
-
+ private boolean conversationLongRunningDuringInvocation;
private boolean conversationLongRunningDuringInvocation2;
+ private boolean conversationLongRunningDuringInvocation3;
+ private boolean conversationLongRunningDuringInvocation4;
+ private boolean conversationLongRunningDuringInvocation5;
+ private boolean conversationLongRunningDuringInvocation6;
+
@Begin
+ public void begin()
+ {
+ }
+
+ @Begin
public void beginConversation()
{
if (!conversation.isTransient())
@@ -34,22 +45,80 @@
@End
public void beginAndEndConversation()
{
- conversationLongRunningDuringInvocation2 = true;
+ if (!conversation.isTransient())
+ {
+ conversationLongRunningDuringInvocation2 = true;
+ }
}
- public boolean isConversationLongRunningDuringInvocation2()
+ @Begin(permit = { SeamFacesException.class })
+ public void beginAndThrowFatalException()
{
- return conversationLongRunningDuringInvocation2;
+ if (!conversation.isTransient())
+ {
+ conversationLongRunningDuringInvocation3 = true;
+ }
+ throw new RuntimeException("A vanilla exception.");
}
- public void setConversationLongRunningDuringInvocation2(final boolean conversationLongRunningDuringInvocation2)
+ @Begin(permit = { SeamFacesException.class })
+ public void beginAndThrowPermittedException()
{
- this.conversationLongRunningDuringInvocation2 = conversationLongRunningDuringInvocation2;
+ if (!conversation.isTransient())
+ {
+ conversationLongRunningDuringInvocation4 = true;
+ }
+ throw new SeamFacesException("Just so it's not a vanilla Exception.");
}
+ @End(permit = { SeamFacesException.class })
+ public void endAndThrowFatalException()
+ {
+ if (!conversation.isTransient())
+ {
+ conversationLongRunningDuringInvocation5 = true;
+ }
+ throw new RuntimeException("A vanilla exception.");
+ }
+
+ @End(permit = { SeamFacesException.class })
+ public void endAndThrowPermittedException()
+ {
+ if (!conversation.isTransient())
+ {
+ conversationLongRunningDuringInvocation6 = true;
+ }
+ throw new SeamFacesException("A vanilla exception.");
+ }
+
public boolean isConversationLongRunningInsideMethodCall()
{
return conversationLongRunningDuringInvocation;
}
+ public boolean isConversationLongRunningDuringInvocation2()
+ {
+ return conversationLongRunningDuringInvocation2;
+ }
+
+ public boolean isConversationLongRunningDuringInvocation3()
+ {
+ return conversationLongRunningDuringInvocation3;
+ }
+
+ public boolean isConversationLongRunningDuringInvocation4()
+ {
+ return conversationLongRunningDuringInvocation4;
+ }
+
+ public boolean isConversationLongRunningDuringInvocation5()
+ {
+ return conversationLongRunningDuringInvocation5;
+ }
+
+ public boolean isConversationLongRunningDuringInvocation6()
+ {
+ return conversationLongRunningDuringInvocation6;
+ }
+
}
Modified: modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationTestObject.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationTestObject.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationTestObject.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -16,4 +16,9 @@
{
}
+ @End(permit = { Exception.class })
+ public void endPermittingExceptions()
+ {
+
+ }
}
Modified: modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationsTest.java
===================================================================
--- modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationsTest.java 2010-03-30 20:34:51 UTC (rev 12332)
+++ modules/faces/trunk/src/test/java/org/jboss/seam/faces/util/AnnotationsTest.java 2010-03-30 22:44:07 UTC (rev 12333)
@@ -43,4 +43,20 @@
assertTrue(Annotations.hasAnnotation(end, Begin.class));
}
+ public void testGetAnnotationOnMethodDirectly() throws Exception
+ {
+ Method end = AnnotationTestObject.class.getMethod("end", new Class[] {});
+ End anno = Annotations.getAnnotation(end, End.class);
+
+ assertTrue(anno instanceof End);
+ }
+
+ public void testGetAnnotationOnMethodIndirectlyFromClass() throws Exception
+ {
+ Method end = AnnotationTestObject.class.getMethod("begin", new Class[] {});
+ Begin anno = Annotations.getAnnotation(end, Begin.class);
+
+ assertTrue(anno instanceof Begin);
+ }
+
}
More information about the seam-commits
mailing list