Skip to content

Commit

Permalink
Added HandlerMethod and impl
Browse files Browse the repository at this point in the history
Actually encapsulating all the functionality into one place to get info about Handler methods.
  • Loading branch information
LightGuard committed Nov 10, 2010
1 parent 332e5b0 commit 7d83fb3
Show file tree
Hide file tree
Showing 20 changed files with 369 additions and 189 deletions.

This file was deleted.

This file was deleted.

Expand Up @@ -38,5 +38,13 @@
@Documented
public @interface Handles
{
/**
* Direction of the cause chain traversal to listen.
*/
public abstract TraversalPath during() default TraversalPath.ASCENDING;

/**
* Precedence relative to handlers for the same type
*/
public abstract int precedence() default 0;
}
@@ -0,0 +1,32 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.seam.exception.control;

/**
* Direction of a exception cause chain traversal.
*/
public enum TraversalPath
{
ASCENDING,
DESCENDING
}
Expand Up @@ -24,48 +24,34 @@

import org.jboss.weld.extensions.reflection.HierarchyDiscovery;

import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Set;

/**
* Comparator to sort exception handlers according qualifier ({@link DuringDescTraversal} first),
* precedence (highest to lowest) and finally hierarchy (least to most specific).
* Comparator to sort exception handlers according qualifier
* ({@link org.jboss.seam.exception.control.TraversalPath#ASCENDING} first), precedence (highest to lowest) and
* finally hierarchy (least to most specific).
*/
@SuppressWarnings({"MethodWithMoreThanThreeNegations", "unchecked"})
public final class ExceptionHandlerComparator implements Comparator<AnnotatedMethod>
public final class ExceptionHandlerComparator implements Comparator<HandlerMethod>
{

/**
* {@inheritDoc}
*/
public int compare(AnnotatedMethod lhs, AnnotatedMethod rhs)
public int compare(HandlerMethod lhs, HandlerMethod rhs)
{
final AnnotatedParameter lhsEventParam = (AnnotatedParameter) lhs.getParameters().get(0);
final AnnotatedParameter rhsEventParam = (AnnotatedParameter) rhs.getParameters().get(0);

final Type lhsExceptionType = ((ParameterizedType) lhsEventParam.getBaseType()).getActualTypeArguments()[0];
final Type rhsExceptionType = ((ParameterizedType) rhsEventParam.getBaseType()).getActualTypeArguments()[0];

if (lhsExceptionType.equals(rhsExceptionType))
if (lhs.getExceptionType().equals(rhs.getExceptionType()))
{
// Really this is so all handlers are returned in the TreeSet (even if they're of the same type, but one is
// inbound, the other is outbound
if ((lhsEventParam.isAnnotationPresent(DuringDescTraversal.class) && rhsEventParam.isAnnotationPresent(
DuringDescTraversal.class))
|| (!lhsEventParam.isAnnotationPresent(DuringDescTraversal.class) && !rhsEventParam.isAnnotationPresent(
DuringDescTraversal.class)))
if (lhs.getTraversalPath() == rhs.getTraversalPath())
{
final int lhsPrecedence = lhsEventParam.getAnnotation(Handles.class).precedence();
final int rhsPrecedence = rhsEventParam.getAnnotation(Handles.class).precedence();
return this.comparePrecedence(lhsPrecedence, rhsPrecedence);
return this.comparePrecedence(lhs.getPrecedence(), rhs.getPrecedence());
}
else if (lhsEventParam.isAnnotationPresent(DuringDescTraversal.class) && !rhsEventParam.isAnnotationPresent(
DuringDescTraversal.class))
else if (lhs.getTraversalPath() == TraversalPath.DESCENDING)
{
return -1; // DuringDescTraversal first
}
Expand All @@ -74,7 +60,7 @@ else if (lhsEventParam.isAnnotationPresent(DuringDescTraversal.class) && !rhsEve
return 1;
}
}
return compareHierarchies(lhsExceptionType, rhsExceptionType);
return compareHierarchies(lhs.getExceptionType(), rhs.getExceptionType());
}

private int compareHierarchies(Type lhsExceptionType, Type rhsExceptionType)
Expand Down
Expand Up @@ -22,13 +22,9 @@
package org.jboss.seam.exception.control;

import org.jboss.seam.exception.control.extension.CatchExtension;
import org.jboss.weld.extensions.reflection.annotated.InjectableMethod;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -71,7 +67,7 @@ public void executeHandlers(@Observes ExceptionToCatchEvent eventException, fina
{
ctx = bm.createCreationalContext(null);

final Set<AnnotatedMethod> processedHandlers = new HashSet<AnnotatedMethod>();
final Set<HandlerMethod> processedHandlers = new HashSet<HandlerMethod>();
boolean rethrow = false;

// DuringDescTraversal handlers
Expand All @@ -80,16 +76,15 @@ public void executeHandlers(@Observes ExceptionToCatchEvent eventException, fina
while (exceptionIndex >= 0)
{

List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
extension.getHandlersForExceptionType(unwrappedExceptions.get(exceptionIndex).getClass()));
List<HandlerMethod> handlerMethods = new ArrayList<HandlerMethod>(
extension.getHandlersForExceptionType(unwrappedExceptions.get(exceptionIndex).getClass(), bm));

for (AnnotatedMethod handler : handlerMethods)
for (HandlerMethod handler : handlerMethods)
{
if (((AnnotatedParameter) handler.getParameters().get(0)).isAnnotationPresent(DuringDescTraversal.class)
&& !processedHandlers.contains(handler))
if (handler.getTraversalPath() == TraversalPath.DESCENDING && !processedHandlers.contains(handler))
{
final CatchEvent event = new CatchEvent(new StackInfo(unwrappedExceptions, exceptionIndex), true);
invokeHandler(bm, ctx, handler, event);
handler.notify(event, bm);

if (!event.isUnMute())
{
Expand Down Expand Up @@ -125,19 +120,18 @@ public void executeHandlers(@Observes ExceptionToCatchEvent eventException, fina
while (exceptionIndex >= 0)
{

List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
extension.getHandlersForExceptionType(unwrappedExceptions.get(exceptionIndex).getClass()));
List<HandlerMethod> handlerMethods = new ArrayList<HandlerMethod>(
extension.getHandlersForExceptionType(unwrappedExceptions.get(exceptionIndex).getClass(), bm));

Collections.reverse(handlerMethods);

for (AnnotatedMethod handler : handlerMethods)
for (HandlerMethod handler : handlerMethods)
{
// Defining DuringAscTraversal as the absence of DuringDescTraversal
if (!((AnnotatedParameter) handler.getParameters().get(0)).isAnnotationPresent(DuringDescTraversal.class)
&& !processedHandlers.contains(handler))
if (handler.getTraversalPath() == TraversalPath.ASCENDING && !processedHandlers.contains(handler))
{
final CatchEvent event = new CatchEvent(new StackInfo(unwrappedExceptions, exceptionIndex), false);
invokeHandler(bm, ctx, handler, event);
handler.notify(event, bm);

if (!event.isUnMute())
{
Expand Down Expand Up @@ -179,16 +173,4 @@ public void executeHandlers(@Observes ExceptionToCatchEvent eventException, fina
}
}
}

@SuppressWarnings({"unchecked"})
private void invokeHandler(BeanManager bm, CreationalContext<Object> ctx, AnnotatedMethod handler, CatchEvent event)
{
Bean<?> handlerBean = bm.resolve(bm.getBeans(handler.getJavaMember().getDeclaringClass(),
HandlesExceptionsLiteral.INSTANCE));
Object handlerInstance = bm.getReference(handlerBean, handler.getBaseType(), ctx);

InjectableMethod im = new InjectableMethod(handler, handlerBean, bm);

im.invoke(handlerInstance, ctx, new OutboundParameterValueRedefiner(event, bm, handlerBean));
}
}
@@ -0,0 +1,76 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.seam.exception.control;

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Set;

public interface HandlerMethod<T extends Throwable>
{
/**
* Obtains the bean class of the bean that declares the observer method.
*/
Class<?> getBeanClass();

/**
* Obtains the Bean reference that declares the observer method.
*/
Bean<?> getBean();

/**
* Obtains the set of handled event qualifiers.
*/
Set<Annotation> getHandlesQualifiers();

/**
* Obtains the handled event type.
*/
Type getExceptionType();

/**
* Calls the handler method, passing the given event object.
*
* @param event event to pass to the handler.
* @param bm Active BeanManager
*/
void notify(CatchEvent<T> event, BeanManager bm);

/**
* Obtains the direction of the traversal path the handler will be listening.
*/
TraversalPath getTraversalPath();

/**
* Obtains the precedence of the handler.
*/
int getPrecedence();

/**
* Obtains the actual method of the handler.
*/
Method getJavaMethod();
}

0 comments on commit 7d83fb3

Please sign in to comment.