Repository: deltaspike Updated Branches: refs/heads/master b0ce121ac -> e5160ee16
DELTASPIKE-523 unified structure Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/e5160ee1 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/e5160ee1 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/e5160ee1 Branch: refs/heads/master Commit: e5160ee16e95d740c5d46132d54e5587d1208618 Parents: b0ce121 Author: gpetracek <[email protected]> Authored: Mon Mar 3 15:44:25 2014 +0100 Committer: gpetracek <[email protected]> Committed: Mon Mar 3 15:44:25 2014 +0100 ---------------------------------------------------------------------- .../control/IntrospectiveExceptionEvent.java | 46 ---- .../event/IntrospectiveExceptionEvent.java | 46 ++++ .../control/DefaultExceptionEvent.java | 2 +- .../control/ExceptionHandlerBroadcaster.java | 213 +++++++++++++++++++ .../control/ExceptionHandlerDispatch.java | 212 ------------------ .../impl/exception/control/event/EventTest.java | 2 +- 6 files changed, 261 insertions(+), 260 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/IntrospectiveExceptionEvent.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/IntrospectiveExceptionEvent.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/IntrospectiveExceptionEvent.java deleted file mode 100644 index 1eb061c..0000000 --- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/IntrospectiveExceptionEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.deltaspike.core.spi.exception.control; - -import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; -import org.apache.deltaspike.core.api.exception.control.ExceptionHandlingFlow; - -/** - * Internal view into the ExceptionEvent. Methods on this interface are used by the ExceptionHandlerDispatcher. - */ -public interface IntrospectiveExceptionEvent<T extends Throwable> extends ExceptionEvent<T> -{ - /** - * Check to see if this event has been unmuted and therefore called again. - */ - boolean isUnmute(); - - /** - * The next expected step in the exception handling flow (i.e. abort, rethrow, etc) - */ - ExceptionHandlingFlow getCurrentExceptionHandlingFlow(); - - boolean isBeforeTraversal(); - - /** - * Returns the exception that should be thrown if the next step in the flow is THROW. - */ - Throwable getThrowNewException(); -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/event/IntrospectiveExceptionEvent.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/event/IntrospectiveExceptionEvent.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/event/IntrospectiveExceptionEvent.java new file mode 100644 index 0000000..d4255a8 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/exception/control/event/IntrospectiveExceptionEvent.java @@ -0,0 +1,46 @@ +/* + * 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.deltaspike.core.spi.exception.control.event; + +import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; +import org.apache.deltaspike.core.api.exception.control.ExceptionHandlingFlow; + +/** + * Internal view into the ExceptionEvent. Methods on this interface are used by the ExceptionHandlerBroadcaster. + */ +public interface IntrospectiveExceptionEvent<T extends Throwable> extends ExceptionEvent<T> +{ + /** + * Check to see if this event has been unmuted and therefore called again. + */ + boolean isUnmute(); + + /** + * The next expected step in the exception handling flow (i.e. abort, rethrow, etc) + */ + ExceptionHandlingFlow getCurrentExceptionHandlingFlow(); + + boolean isBeforeTraversal(); + + /** + * Returns the exception that should be thrown if the next step in the flow is THROW. + */ + Throwable getThrowNewException(); +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/DefaultExceptionEvent.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/DefaultExceptionEvent.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/DefaultExceptionEvent.java index 95d3799..0ddf7d2 100644 --- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/DefaultExceptionEvent.java +++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/DefaultExceptionEvent.java @@ -21,7 +21,7 @@ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.ExceptionHandlingFlow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent; -import org.apache.deltaspike.core.spi.exception.control.IntrospectiveExceptionEvent; +import org.apache.deltaspike.core.spi.exception.control.event.IntrospectiveExceptionEvent; import javax.enterprise.inject.Typed; http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerBroadcaster.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerBroadcaster.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerBroadcaster.java new file mode 100644 index 0000000..9b8e6f4 --- /dev/null +++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerBroadcaster.java @@ -0,0 +1,213 @@ +/* + * 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.deltaspike.core.impl.exception.control; + +import org.apache.deltaspike.core.api.exception.control.HandlerMethod; +import org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent; +import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; +import org.apache.deltaspike.core.api.provider.BeanProvider; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.spi.BeanManager; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Logger; + +/** + * Observer of {@link org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent} events and + * handler dispatcher. All handlers are invoked from this class. This class is immutable. + */ +@ApplicationScoped +public class ExceptionHandlerBroadcaster +{ + private static final Logger LOG = Logger.getLogger(ExceptionHandlerBroadcaster.class.getName()); + + /** + * Observes the event, finds the correct exception handler(s) and invokes them. + * + * @param exceptionEventEvent exception to be invoked + * @param beanManager active bean manager + * @throws Throwable If a handler requests the exception to be re-thrown. + */ + public void executeHandlers(@Observes @Any ExceptionToCatchEvent exceptionEventEvent, + final BeanManager beanManager) throws Throwable + { + LOG.entering( + ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", exceptionEventEvent.getException()); + + CreationalContext<Object> creationalContext = null; + + Throwable throwException = null; + + final HandlerMethodStorage handlerMethodStorage = + BeanProvider.getContextualReference(HandlerMethodStorage.class); + + try + { + creationalContext = beanManager.createCreationalContext(null); + + final Set<HandlerMethod<?>> processedHandlers = new HashSet<HandlerMethod<?>>(); + + final ExceptionStackEvent stack = new ExceptionStackEvent(exceptionEventEvent.getException()); + + beanManager.fireEvent(stack); // Allow for modifying the exception stack + + inbound_cause: + //indentation needed by the current checkstyle rules + while (stack.getCurrent() != null) + { + final List<HandlerMethod<?>> callbackExceptionEvent = new ArrayList<HandlerMethod<?>>( + handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), + beanManager, exceptionEventEvent.getQualifiers(), true)); + + for (HandlerMethod<?> handler : callbackExceptionEvent) + { + if (!processedHandlers.contains(handler)) + { + LOG.fine(String.format("Notifying handler %s", handler)); + + @SuppressWarnings("rawtypes") + final DefaultExceptionEvent callbackEvent = new DefaultExceptionEvent(stack, true, + exceptionEventEvent.isHandled()); + + handler.notify(callbackEvent, beanManager); + + LOG.fine(String.format("Handler %s returned status %s", handler, + callbackEvent.getCurrentExceptionHandlingFlow().name())); + + if (!callbackEvent.isUnmute()) + { + processedHandlers.add(handler); + } + + switch (callbackEvent.getCurrentExceptionHandlingFlow()) + { + case HANDLED: + exceptionEventEvent.setHandled(true); + return; + case HANDLED_AND_CONTINUE: + exceptionEventEvent.setHandled(true); + break; + case ABORT: + return; + case SKIP_CAUSE: + exceptionEventEvent.setHandled(true); + stack.skipCause(); + continue inbound_cause; + case THROW_ORIGINAL: + throwException = exceptionEventEvent.getException(); + break; + case THROW: + throwException = callbackEvent.getThrowNewException(); + break; + default: + throw new IllegalStateException( + "Unexpected enum type " + callbackEvent.getCurrentExceptionHandlingFlow()); + } + } + } + + final Collection<HandlerMethod<? extends Throwable>> handlersForException = + handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), + beanManager, exceptionEventEvent.getQualifiers(), false); + + final List<HandlerMethod<? extends Throwable>> handlerMethods = + new ArrayList<HandlerMethod<? extends Throwable>>(handlersForException); + + // Reverse these so category handlers are last + Collections.reverse(handlerMethods); + + for (HandlerMethod<?> handler : handlerMethods) + { + if (!processedHandlers.contains(handler)) + { + LOG.fine(String.format("Notifying handler %s", handler)); + + @SuppressWarnings("rawtypes") + final DefaultExceptionEvent depthFirstEvent = new DefaultExceptionEvent(stack, false, + exceptionEventEvent.isHandled()); + handler.notify(depthFirstEvent, beanManager); + + LOG.fine(String.format("Handler %s returned status %s", handler, + depthFirstEvent.getCurrentExceptionHandlingFlow().name())); + + if (!depthFirstEvent.isUnmute()) + { + processedHandlers.add(handler); + } + + switch (depthFirstEvent.getCurrentExceptionHandlingFlow()) + { + case HANDLED: + exceptionEventEvent.setHandled(true); + return; + case HANDLED_AND_CONTINUE: + exceptionEventEvent.setHandled(true); + break; + case ABORT: + return; + case SKIP_CAUSE: + exceptionEventEvent.setHandled(true); + stack.skipCause(); + continue inbound_cause; + case THROW_ORIGINAL: + throwException = exceptionEventEvent.getException(); + break; + case THROW: + throwException = depthFirstEvent.getThrowNewException(); + break; + default: + throw new IllegalStateException( + "Unexpected enum type " + depthFirstEvent.getCurrentExceptionHandlingFlow()); + } + } + } + stack.skipCause(); + } + + if (!exceptionEventEvent.isHandled() && throwException == null) + { + LOG.warning(String.format("No handlers found for exception %s", exceptionEventEvent.getException())); + throw exceptionEventEvent.getException(); + } + + if (throwException != null) + { + throw throwException; + } + } + finally + { + if (creationalContext != null) + { + creationalContext.release(); + } + LOG.exiting(ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", + exceptionEventEvent.getException()); + } + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerDispatch.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerDispatch.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerDispatch.java deleted file mode 100644 index 55bf8ee..0000000 --- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exception/control/ExceptionHandlerDispatch.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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.deltaspike.core.impl.exception.control; - -import org.apache.deltaspike.core.api.exception.control.HandlerMethod; -import org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent; -import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; -import org.apache.deltaspike.core.api.provider.BeanProvider; - -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.event.Observes; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.spi.BeanManager; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Logger; - -/** - * Observer of {@link org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent} events and - * handler dispatcher. All handlers are invoked from this class. This class is immutable. - */ -@ApplicationScoped -public class ExceptionHandlerDispatch -{ - private static final Logger LOG = Logger.getLogger(ExceptionHandlerDispatch.class.getName()); - - /** - * Observes the event, finds the correct exception handler(s) and invokes them. - * - * @param exceptionEventEvent exception to be invoked - * @param beanManager active bean manager - * @throws Throwable If a handler requests the exception to be re-thrown. - */ - public void executeHandlers(@Observes @Any ExceptionToCatchEvent exceptionEventEvent, - final BeanManager beanManager) throws Throwable - { - LOG.entering(ExceptionHandlerDispatch.class.getName(), "executeHandlers", exceptionEventEvent.getException()); - - CreationalContext<Object> creationalContext = null; - - Throwable throwException = null; - - final HandlerMethodStorage handlerMethodStorage = - BeanProvider.getContextualReference(HandlerMethodStorage.class); - - try - { - creationalContext = beanManager.createCreationalContext(null); - - final Set<HandlerMethod<?>> processedHandlers = new HashSet<HandlerMethod<?>>(); - - final ExceptionStackEvent stack = new ExceptionStackEvent(exceptionEventEvent.getException()); - - beanManager.fireEvent(stack); // Allow for modifying the exception stack - - inbound_cause: - //indentation needed by the current checkstyle rules - while (stack.getCurrent() != null) - { - final List<HandlerMethod<?>> callbackExceptionEvent = new ArrayList<HandlerMethod<?>>( - handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), - beanManager, exceptionEventEvent.getQualifiers(), true)); - - for (HandlerMethod<?> handler : callbackExceptionEvent) - { - if (!processedHandlers.contains(handler)) - { - LOG.fine(String.format("Notifying handler %s", handler)); - - @SuppressWarnings("rawtypes") - final DefaultExceptionEvent callbackEvent = new DefaultExceptionEvent(stack, true, - exceptionEventEvent.isHandled()); - - handler.notify(callbackEvent, beanManager); - - LOG.fine(String.format("Handler %s returned status %s", handler, - callbackEvent.getCurrentExceptionHandlingFlow().name())); - - if (!callbackEvent.isUnmute()) - { - processedHandlers.add(handler); - } - - switch (callbackEvent.getCurrentExceptionHandlingFlow()) - { - case HANDLED: - exceptionEventEvent.setHandled(true); - return; - case HANDLED_AND_CONTINUE: - exceptionEventEvent.setHandled(true); - break; - case ABORT: - return; - case SKIP_CAUSE: - exceptionEventEvent.setHandled(true); - stack.skipCause(); - continue inbound_cause; - case THROW_ORIGINAL: - throwException = exceptionEventEvent.getException(); - break; - case THROW: - throwException = callbackEvent.getThrowNewException(); - break; - default: - throw new IllegalStateException( - "Unexpected enum type " + callbackEvent.getCurrentExceptionHandlingFlow()); - } - } - } - - final Collection<HandlerMethod<? extends Throwable>> handlersForException = - handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), - beanManager, exceptionEventEvent.getQualifiers(), false); - - final List<HandlerMethod<? extends Throwable>> handlerMethods = - new ArrayList<HandlerMethod<? extends Throwable>>(handlersForException); - - // Reverse these so category handlers are last - Collections.reverse(handlerMethods); - - for (HandlerMethod<?> handler : handlerMethods) - { - if (!processedHandlers.contains(handler)) - { - LOG.fine(String.format("Notifying handler %s", handler)); - - @SuppressWarnings("rawtypes") - final DefaultExceptionEvent depthFirstEvent = new DefaultExceptionEvent(stack, false, - exceptionEventEvent.isHandled()); - handler.notify(depthFirstEvent, beanManager); - - LOG.fine(String.format("Handler %s returned status %s", handler, - depthFirstEvent.getCurrentExceptionHandlingFlow().name())); - - if (!depthFirstEvent.isUnmute()) - { - processedHandlers.add(handler); - } - - switch (depthFirstEvent.getCurrentExceptionHandlingFlow()) - { - case HANDLED: - exceptionEventEvent.setHandled(true); - return; - case HANDLED_AND_CONTINUE: - exceptionEventEvent.setHandled(true); - break; - case ABORT: - return; - case SKIP_CAUSE: - exceptionEventEvent.setHandled(true); - stack.skipCause(); - continue inbound_cause; - case THROW_ORIGINAL: - throwException = exceptionEventEvent.getException(); - break; - case THROW: - throwException = depthFirstEvent.getThrowNewException(); - break; - default: - throw new IllegalStateException( - "Unexpected enum type " + depthFirstEvent.getCurrentExceptionHandlingFlow()); - } - } - } - stack.skipCause(); - } - - if (!exceptionEventEvent.isHandled() && throwException == null) - { - LOG.warning(String.format("No handlers found for exception %s", exceptionEventEvent.getException())); - throw exceptionEventEvent.getException(); - } - - if (throwException != null) - { - throw throwException; - } - } - finally - { - if (creationalContext != null) - { - creationalContext.release(); - } - LOG.exiting(ExceptionHandlerDispatch.class.getName(), "executeHandlers", - exceptionEventEvent.getException()); - } - } -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e5160ee1/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java index 0297991..d4245fb 100644 --- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java +++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java @@ -24,7 +24,7 @@ import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; -import org.apache.deltaspike.core.spi.exception.control.IntrospectiveExceptionEvent; +import org.apache.deltaspike.core.spi.exception.control.event.IntrospectiveExceptionEvent; import org.apache.deltaspike.test.core.impl.exception.control.event.literal.EventQualifierLiteral; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment;
