Skip to content

Commit

Permalink
Handlers are being called
Browse files Browse the repository at this point in the history
Handlers are now being called (at least in the simple case, need more tests).
  • Loading branch information
LightGuard committed Nov 9, 2010
1 parent 19347b6 commit 7ede72d
Show file tree
Hide file tree
Showing 14 changed files with 506 additions and 44 deletions.
Expand Up @@ -27,7 +27,7 @@
*
* @param <T> Exception type this event represents
*/
public class ExceptionHandlingEvent<T extends Throwable>
public class CatchEvent<T extends Throwable>
{
protected enum ExceptionHandlingFlow
{
Expand All @@ -44,7 +44,7 @@ protected enum ExceptionHandlingFlow
boolean inbound;
boolean outbound;

public ExceptionHandlingEvent(final StackInfo stackInfo, final boolean inbound)
public CatchEvent(final StackInfo stackInfo, final boolean inbound)
{
this.exception = (T) stackInfo.getCurrentCause();
this.stackInfo = stackInfo;
Expand Down
1 change: 1 addition & 0 deletions impl/pom.xml
Expand Up @@ -60,6 +60,7 @@
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-extensions</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
@@ -0,0 +1,64 @@
/*
* 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 org.jboss.weld.extensions.bean.ForwardingInjectionPoint;

import javax.enterprise.inject.spi.InjectionPoint;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class CatchInjectionPoint extends ForwardingInjectionPoint
{
private InjectionPoint delegate;
private Set<Annotation> qualifiers;

public CatchInjectionPoint(InjectionPoint delegate)
{
this.delegate = delegate;
this.qualifiers = new HashSet<Annotation>(delegate.getQualifiers());
}

public void addQualifier(Annotation qualifier)
{
this.qualifiers.add(qualifier);
}

public void addAllQualifiers(Collection<Annotation> qualifiers)
{
this.qualifiers.addAll(qualifiers);
}

@Override
protected InjectionPoint delegate()
{
return this.delegate;
}

@Override public Set<Annotation> getQualifiers()
{
return this.qualifiers;
}
}
Expand Up @@ -53,9 +53,24 @@ public int compare(AnnotatedMethod lhs, AnnotatedMethod rhs)

if (lhsExceptionType.equals(rhsExceptionType))
{
final int lhsPrecedence = lhsEventParam.getAnnotation(Handles.class).precedence();
final int rhsPrecedence = rhsEventParam.getAnnotation(Handles.class).precedence();
return this.comparePrecedence(lhsPrecedence, rhsPrecedence);
// 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(Inbound.class) && rhsEventParam.isAnnotationPresent(Inbound.class))
|| (!lhsEventParam.isAnnotationPresent(Inbound.class) && !rhsEventParam.isAnnotationPresent(
Inbound.class)))
{
final int lhsPrecedence = lhsEventParam.getAnnotation(Handles.class).precedence();
final int rhsPrecedence = rhsEventParam.getAnnotation(Handles.class).precedence();
return this.comparePrecedence(lhsPrecedence, rhsPrecedence);
}
else if (lhsEventParam.isAnnotationPresent(Inbound.class) && !rhsEventParam.isAnnotationPresent(Inbound.class))
{
return -1; // Inbound first
}
else
{
return 1;
}
}
return compareHierarchies(lhsExceptionType, rhsExceptionType);
}
Expand Down
Expand Up @@ -22,9 +22,14 @@
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 javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -44,9 +49,10 @@ public class ExceptionHandlerDispatch
* @param eventException
*/
@SuppressWarnings({"unchecked", "MethodWithMultipleLoops", "ThrowableResultOfMethodCallIgnored"})
public void executeHandlers(@Observes Throwable eventException)
public void executeHandlers(@Observes Throwable eventException, final BeanManager bm)
{
final Stack<Throwable> unwrappedExceptions = new Stack<Throwable>();
CreationalContext<Object> ctx = null;

Throwable exception = eventException;

Expand All @@ -56,54 +62,82 @@ public void executeHandlers(@Observes Throwable eventException)
}
while ((exception = exception.getCause()) != null);

// Inbound handlers
int indexOfException = 0;
while (indexOfException < unwrappedExceptions.size())
try
{
ExceptionHandlingEvent ehe = new ExceptionHandlingEvent(new StackInfo(unwrappedExceptions, indexOfException),
true);
ctx = bm.createCreationalContext(null);

List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
this.extension.getHandlersForExceptionType(unwrappedExceptions.get(indexOfException).getClass()));

for (AnnotatedMethod handler : handlerMethods)
// Inbound handlers
int indexOfException = 0;
while (indexOfException < unwrappedExceptions.size())
{
// TODO: Get bean from AnnotatedMethod, create bean, call method
CatchEvent ehe = new CatchEvent(new StackInfo(unwrappedExceptions, indexOfException), true);

List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
this.extension.getHandlersForExceptionType(unwrappedExceptions.get(indexOfException).getClass()));

for (AnnotatedMethod handler : handlerMethods)
{
if (((AnnotatedParameter) handler.getParameters().get(0)).isAnnotationPresent(Inbound.class))
{
invokeHandler(bm, ctx, handler, ehe);
}

// make use of InjectableMethod#public <T> T invoke(Object receiver, CreationalContext<T> creationalContext, ParameterValueRedefiner redefinition)
// TODO: Make sure things like mute are handled
}

// TODO: Make sure things like mute are handled
// TODO rollbacks, throws, etc

indexOfException++;
}

// TODO rollbacks, throws, etc
// Run outbound handlers, same list, just reversed
indexOfException = 0;
while (indexOfException < unwrappedExceptions.size())
{
CatchEvent ehe = new CatchEvent(new StackInfo(unwrappedExceptions, indexOfException),
false);

indexOfException++;
}
List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
this.extension.getHandlersForExceptionType(unwrappedExceptions.get(indexOfException).getClass()));

// Run outbound handlers, same list, just reversed
indexOfException = 0;
while (indexOfException < unwrappedExceptions.size())
{
ExceptionHandlingEvent ehe = new ExceptionHandlingEvent(new StackInfo(unwrappedExceptions, indexOfException),
false);
Collections.reverse(handlerMethods);

List<AnnotatedMethod> handlerMethods = new ArrayList<AnnotatedMethod>(
this.extension.getHandlersForExceptionType(unwrappedExceptions.get(indexOfException).getClass()));
for (AnnotatedMethod handler : handlerMethods)
{
// Defining Outbound as the absence of Inbound
if (!((AnnotatedParameter) handler.getParameters().get(0)).isAnnotationPresent(Inbound.class))
{
invokeHandler(bm, ctx, handler, ehe);
}

Collections.reverse(handlerMethods);
// TODO: Make sure things like mute are handled
}

for (AnnotatedMethod handler : handlerMethods)
{
// TODO: Get bean from AnnotatedMethod, create bean, call method
// TODO rollbacks, throws, etc

// make use of InjectableMethod#public <T> T invoke(Object receiver, CreationalContext<T> creationalContext, ParameterValueRedefiner redefinition)
indexOfException++;
}

// TODO: Make sure things like mute are handled
}
finally
{
if (ctx != null)
{
ctx.release();
}
}

// TODO rollbacks, throws, etc
}

indexOfException++;
}
@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,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;

import javax.enterprise.util.AnnotationLiteral;

public class HandlesExceptionsLiteral extends AnnotationLiteral<HandlesExceptions> implements HandlesExceptions
{
private static final long serialVersionUID = -6775381615228078023L;

public static final HandlesExceptions INSTANCE = new HandlesExceptionsLiteral();
}
@@ -0,0 +1,33 @@
/*
* 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.util.AnnotationLiteral;

@SuppressWarnings({"ClassExplicitlyAnnotation"})
public class OutboundLiteral extends AnnotationLiteral<Outbound> implements Outbound
{
private static final long serialVersionUID = 411584330706373947L;

public static final Outbound INSTANCE = new OutboundLiteral();
}
@@ -0,0 +1,67 @@
/*
* 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 org.jboss.weld.extensions.reflection.annotated.ParameterValueRedefiner;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

public class OutboundParameterValueRedefiner implements ParameterValueRedefiner
{
final CatchEvent event;
final BeanManager bm;
final Bean<?> declaringBean;

public OutboundParameterValueRedefiner(CatchEvent event, final BeanManager manager, Bean<?> declaringBean)
{
this.event = event;
this.bm = manager;
this.declaringBean = declaringBean;
}

public Object redefineParameterValue(ParameterValue value)
{
CreationalContext<?> ctx = this.bm.createCreationalContext(this.declaringBean);

try
{
switch (value.getPosition())
{
case 0:
{
return event;
}
}
return value.getDefaultValue(ctx);
}
finally
{
if (ctx != null)
{
ctx.release();
}
}
}
}

0 comments on commit 7ede72d

Please sign in to comment.