Repository: deltaspike Updated Branches: refs/heads/master fd5beb5b2 -> bfb01bd40
DELTASPIKE-341 Bridge between JSF and DS Exception Handling Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/bfb01bd4 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/bfb01bd4 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/bfb01bd4 Branch: refs/heads/master Commit: bfb01bd40adc52c92b56f170248516ed892e5392 Parents: fd5beb5 Author: tandraschko <[email protected]> Authored: Sat Feb 15 20:14:24 2014 +0100 Committer: tandraschko <[email protected]> Committed: Sat Feb 15 20:14:24 2014 +0100 ---------------------------------------------------------------------- .../example/PlaygroundJsfModuleConfig.java | 33 ++++++ .../deltaspike/example/exception/Jsf.java | 36 +++++++ .../example/exception/TestException.java | 24 +++++ .../exception/TestExceptionController.java | 32 ++++++ .../example/exception/TestExceptionHandler.java | 34 +++++++ .../exceptionhandling/exceptionhandling.xhtml | 37 +++++++ .../jsf/api/config/JsfModuleConfig.java | 14 +++ .../exception/DeltaSpikeExceptionHandler.java | 102 +++++++++++++++++++ .../DeltaSpikeExceptionHandlerFactory.java | 46 +++++++++ .../main/resources/META-INF/faces-config.xml | 1 + 10 files changed, 359 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/PlaygroundJsfModuleConfig.java ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/PlaygroundJsfModuleConfig.java b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/PlaygroundJsfModuleConfig.java new file mode 100644 index 0000000..432843b --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/PlaygroundJsfModuleConfig.java @@ -0,0 +1,33 @@ +/* + * 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.example; + +import java.lang.annotation.Annotation; +import javax.enterprise.inject.Specializes; +import org.apache.deltaspike.example.exception.Jsf; +import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; + +@Specializes +public class PlaygroundJsfModuleConfig extends JsfModuleConfig +{ + public Class<? extends Annotation> getExceptionQualifier() + { + return Jsf.class; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/Jsf.java ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/Jsf.java b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/Jsf.java new file mode 100644 index 0000000..2f00c53 --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/Jsf.java @@ -0,0 +1,36 @@ +/* + * 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.example.exception; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +@Target( { TYPE, ElementType.PARAMETER } ) +@Retention(RUNTIME) +@Documented +@Qualifier +public @interface Jsf +{ + +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestException.java ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestException.java b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestException.java new file mode 100644 index 0000000..5f322c4 --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestException.java @@ -0,0 +1,24 @@ +/* + * 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.example.exception; + +public class TestException extends RuntimeException +{ + +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionController.java ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionController.java b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionController.java new file mode 100644 index 0000000..597aea0 --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionController.java @@ -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.deltaspike.example.exception; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +@Named +@RequestScoped +public class TestExceptionController +{ + public void throwException() + { + throw new TestException(); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionHandler.java b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionHandler.java new file mode 100644 index 0000000..b6d3a35 --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/example/exception/TestExceptionHandler.java @@ -0,0 +1,34 @@ +/* + * 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.example.exception; + +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; + +@ExceptionHandler +public class TestExceptionHandler +{ + public void handleTestException(@Handles @Jsf ExceptionEvent<TestException> event) + { + System.err.println("TestException handled!"); + + event.handled(); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/examples/jsf-playground/src/main/webapp/views/exceptionhandling/exceptionhandling.xhtml ---------------------------------------------------------------------- diff --git a/deltaspike/examples/jsf-playground/src/main/webapp/views/exceptionhandling/exceptionhandling.xhtml b/deltaspike/examples/jsf-playground/src/main/webapp/views/exceptionhandling/exceptionhandling.xhtml new file mode 100644 index 0000000..d713600 --- /dev/null +++ b/deltaspike/examples/jsf-playground/src/main/webapp/views/exceptionhandling/exceptionhandling.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> + +<h:head> + <title>DeltaSpike JSF Playground</title> +</h:head> + +<h:body> + <h:form> + <h:commandButton value="Throw Exception" actionListener="#{testExceptionController.throwException}" /> + </h:form> +</h:body> + +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java index 221cb21..dec847d 100644 --- a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java +++ b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java @@ -18,11 +18,13 @@ */ package org.apache.deltaspike.jsf.api.config; +import java.lang.annotation.Annotation; import org.apache.deltaspike.core.api.config.DeltaSpikeConfig; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Default; import javax.faces.context.FacesContext; /** @@ -104,6 +106,18 @@ public class JsfModuleConfig implements DeltaSpikeConfig return null; } + /** + * Defines the {@link javax.enterprise.Qualifier} which will be used to fire the + * {@link org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent} + * for unhandled JSF exceptions. + * + * @return the {@link javax.enterprise.Qualifier}. + */ + public Class<? extends Annotation> getExceptionQualifier() + { + return Default.class; + } + protected boolean isDelegatedWindowHandlingEnabled() { if (ClassUtils.tryToLoadClassForName(CLIENT_WINDOW_CLASS_NAME) == null) http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java new file mode 100644 index 0000000..2593d0e --- /dev/null +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java @@ -0,0 +1,102 @@ +/* + * 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.jsf.impl.exception; + +import java.util.Iterator; +import javax.enterprise.inject.spi.BeanManager; +import javax.faces.FacesException; +import javax.faces.context.ExceptionHandler; +import javax.faces.context.ExceptionHandlerWrapper; +import javax.faces.context.FacesContext; +import javax.faces.event.ExceptionQueuedEvent; +import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.spi.activation.Deactivatable; +import org.apache.deltaspike.core.util.ClassDeactivationUtils; +import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; +import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; + +public class DeltaSpikeExceptionHandler extends ExceptionHandlerWrapper implements Deactivatable +{ + private final ExceptionHandler wrapped; + private final JsfModuleConfig jsfModuleConfig; + + private boolean isActivated = true; + + public DeltaSpikeExceptionHandler(ExceptionHandler wrapped) + { + this.isActivated = ClassDeactivationUtils.isActivated(getClass()); + this.wrapped = wrapped; + this.jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); + } + + @Override + public ExceptionHandler getWrapped() + { + return wrapped; + } + + @Override + public void handle() throws FacesException + { + if (isActivated) + { + FacesContext context = FacesContext.getCurrentInstance(); + + if (context.getResponseComplete()) + { + return; + } + + Iterable<ExceptionQueuedEvent> exceptionQueuedEvents = getUnhandledExceptionQueuedEvents(); + if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null) + { + Iterator<ExceptionQueuedEvent> iterator = exceptionQueuedEvents.iterator(); + + BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); + + while (iterator.hasNext()) + { + Throwable throwable = iterator.next().getContext().getException(); + Throwable rootCause = getRootCause(throwable); + + ExceptionToCatchEvent event = new ExceptionToCatchEvent( + rootCause, + AnnotationInstanceProvider.of(jsfModuleConfig.getExceptionQualifier())); + + beanManager.fireEvent(event); + + if (event.isHandled()) + { + iterator.remove(); + } + + // a handle method might redirect and set responseComplete + if (context.getResponseComplete()) + { + break; + } + } + } + } + + super.handle(); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java new file mode 100644 index 0000000..c105648 --- /dev/null +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.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.jsf.impl.exception; + +import javax.faces.context.ExceptionHandler; +import javax.faces.context.ExceptionHandlerFactory; + +public class DeltaSpikeExceptionHandlerFactory extends ExceptionHandlerFactory +{ + private final ExceptionHandlerFactory wrapped; + private final DeltaSpikeExceptionHandler handler; + + public DeltaSpikeExceptionHandlerFactory(final ExceptionHandlerFactory wrapped) + { + this.wrapped = wrapped; + this.handler = new DeltaSpikeExceptionHandler(wrapped.getExceptionHandler()); + } + + @Override + public ExceptionHandler getExceptionHandler() + { + return handler; + } + + @Override + public ExceptionHandlerFactory getWrapped() + { + return wrapped; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bfb01bd4/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml index fbebb8f..b06e277 100644 --- a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml +++ b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml @@ -49,6 +49,7 @@ </application> <factory> + <exception-handler-factory>org.apache.deltaspike.jsf.impl.exception.DeltaSpikeExceptionHandlerFactory</exception-handler-factory> <lifecycle-factory>org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeLifecycleFactoryWrapper</lifecycle-factory> <faces-context-factory>org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory</faces-context-factory> </factory>
