You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2011/05/15 01:36:40 UTC
svn commit: r1103252 - in /myfaces/extensions/cdi/trunk/jee-modules:
jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/
jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/
Author: gpetracek
Date: Sat May 14 23:36:40 2011
New Revision: 1103252
URL: http://svn.apache.org/viewvc?rev=1103252&view=rev
Log:
EXTCDI-180 and EXTCDI-181 exception-handler enhancements
Added:
myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/DefaultErrorViewExceptionHandler.java
Modified:
myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/ConversationUtils.java
myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/CodiFacesContextWrapper.java
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/ConversationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/ConversationUtils.java?rev=1103252&r1=1103251&r2=1103252&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/ConversationUtils.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/util/ConversationUtils.java Sat May 14 23:36:40 2011
@@ -25,6 +25,7 @@ import org.apache.myfaces.extensions.cdi
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowScoped;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.config.WindowContextConfig;
import org.apache.myfaces.extensions.cdi.core.api.provider.BeanManagerProvider;
+import org.apache.myfaces.extensions.cdi.core.impl.projectstage.ProjectStageProducer;
import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
@@ -37,6 +38,7 @@ import org.apache.myfaces.extensions.cdi
import org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi.EditableWindowContext;
import org.apache.myfaces.extensions.cdi.message.api.Message;
+import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.Typed;
@@ -617,33 +619,45 @@ public abstract class ConversationUtils
//don't move it to an observer due to an unpredictable invocation order
public static void postRenderCleanup(FacesContext facesContext)
{
- BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
+ try
+ {
+ BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
- EditableWindowContextManager windowContextManager =
- CodiUtils.getContextualReferenceByClass(beanManager, EditableWindowContextManager.class);
+ EditableWindowContextManager windowContextManager =
+ CodiUtils.getContextualReferenceByClass(beanManager, EditableWindowContextManager.class);
- WindowContextConfig windowContextConfig =
- CodiUtils.getContextualReferenceByClass(beanManager, WindowContextConfig.class);
+ WindowContextConfig windowContextConfig =
+ CodiUtils.getContextualReferenceByClass(beanManager, WindowContextConfig.class);
- ViewAccessConversationExpirationEvaluatorRegistry registry =
- CodiUtils.getContextualReferenceByClass(
- beanManager, ViewAccessConversationExpirationEvaluatorRegistry.class);
+ ViewAccessConversationExpirationEvaluatorRegistry registry =
+ CodiUtils.getContextualReferenceByClass(
+ beanManager, ViewAccessConversationExpirationEvaluatorRegistry.class);
- UIViewRoot uiViewRoot = facesContext.getViewRoot();
+ UIViewRoot uiViewRoot = facesContext.getViewRoot();
- //e.g. in case of a ViewExpiredException (e.g. in case of an expired session)
- if(uiViewRoot == null)
- {
- return;
- }
+ //e.g. in case of a ViewExpiredException (e.g. in case of an expired session)
+ if(uiViewRoot == null)
+ {
+ return;
+ }
- registry.broadcastRenderedViewId(uiViewRoot.getViewId());
+ registry.broadcastRenderedViewId(uiViewRoot.getViewId());
- storeCurrentViewIdAsOldViewId(facesContext);
+ storeCurrentViewIdAsOldViewId(facesContext);
- if(windowContextConfig.isCloseEmptyWindowContextsEnabled())
+ if(windowContextConfig.isCloseEmptyWindowContextsEnabled())
+ {
+ cleanupInactiveWindowContexts(windowContextManager);
+ }
+ }
+ catch (ContextNotActiveException e)
{
- cleanupInactiveWindowContexts(windowContextManager);
+ if(ProjectStageProducer.getInstance().getProjectStage() ==
+ org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStage.Development)
+ {
+ e.printStackTrace();
+ }
+ //we can ignore the exception because it's just an optional (immediate) cleanup
}
//if the cache would get resetted by an observer or a phase-listener
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/CodiFacesContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/CodiFacesContextWrapper.java?rev=1103252&r1=1103251&r2=1103252&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/CodiFacesContextWrapper.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/CodiFacesContextWrapper.java Sat May 14 23:36:40 2011
@@ -21,6 +21,7 @@ package org.apache.myfaces.extensions.cd
import org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig;
import org.apache.myfaces.extensions.cdi.core.impl.util.ClassDeactivation;
import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
+import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewConfigCache;
import org.apache.myfaces.extensions.cdi.jsf.impl.listener.request.BeforeAfterFacesRequestBroadcaster;
import org.apache.myfaces.extensions.cdi.jsf.impl.listener.request.FacesMessageEntry;
import org.apache.myfaces.extensions.cdi.jsf2.impl.scope.conversation.RedirectedConversationAwareExternalContext;
@@ -28,10 +29,12 @@ import org.apache.myfaces.extensions.cdi
import org.apache.myfaces.extensions.cdi.message.api.Message;
import javax.faces.application.FacesMessage;
+import javax.faces.application.Application;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextWrapper;
-import javax.faces.application.Application;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -51,6 +54,8 @@ class CodiFacesContextWrapper extends Fa
private boolean temporaryViewRootAwareApplicationWrapperActivated;
+ private boolean defaultErrorViewExceptionHandlerActivated;
+
CodiFacesContextWrapper(FacesContext wrappedFacesContext)
{
this.wrappedFacesContext = wrappedFacesContext;
@@ -62,6 +67,24 @@ class CodiFacesContextWrapper extends Fa
}
/**
+ * {@inheritDoc}
+ */
+ @Override
+ public ExceptionHandler getExceptionHandler()
+ {
+ lazyInit();
+
+ ExceptionHandler exceptionHandler = this.wrappedFacesContext.getExceptionHandler();
+
+ if(this.defaultErrorViewExceptionHandlerActivated)
+ {
+ exceptionHandler = new DefaultErrorViewExceptionHandler(exceptionHandler);
+ }
+ tryToInjectFields(exceptionHandler);
+ return exceptionHandler;
+ }
+
+ /**
* Performs dependency injection manually (if permitted)
* {@inheritDoc}
*/
@@ -122,6 +145,22 @@ class CodiFacesContextWrapper extends Fa
this.temporaryViewRootAwareApplicationWrapperActivated =
ClassDeactivation.isClassActivated(SecurityAwareViewHandler.class) &&
ClassDeactivation.isClassActivated(TemporaryViewRootAwareApplicationWrapper.class);
+
+ //deactivate it, if there is no default-error-view available
+ //ExceptionHandler used as marker because it's part of the jsf2 api and won't change
+ this.defaultErrorViewExceptionHandlerActivated =
+ ViewConfigCache.getDefaultErrorViewConfigDescriptor() != null &&
+ ClassDeactivation.isClassActivated(ExceptionHandler.class);
+ }
+ }
+
+ private void tryToInjectFields(ExceptionHandler exceptionHandler)
+ {
+ CodiUtils.injectFields(exceptionHandler, this.advancedQualifierRequiredForDependencyInjection);
+
+ if(exceptionHandler instanceof ExceptionHandlerWrapper)
+ {
+ tryToInjectFields(((ExceptionHandlerWrapper) exceptionHandler).getWrapped());
}
}
Added: myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/DefaultErrorViewExceptionHandler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/DefaultErrorViewExceptionHandler.java?rev=1103252&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/DefaultErrorViewExceptionHandler.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/listener/request/DefaultErrorViewExceptionHandler.java Sat May 14 23:36:40 2011
@@ -0,0 +1,135 @@
+/*
+ * 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.myfaces.extensions.cdi.jsf2.impl.listener.request;
+
+import org.apache.myfaces.extensions.cdi.core.api.Advanced;
+import org.apache.myfaces.extensions.cdi.core.api.config.view.DefaultErrorView;
+import org.apache.myfaces.extensions.cdi.core.api.navigation.ViewNavigationHandler;
+import org.apache.myfaces.extensions.cdi.core.impl.projectstage.ProjectStageProducer;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.faces.FacesException;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.ViewExpiredException;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.context.Flash;
+import javax.faces.event.ExceptionQueuedEvent;
+import javax.faces.event.ExceptionQueuedEventContext;
+import javax.inject.Inject;
+import java.util.Iterator;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Advanced
+class DefaultErrorViewExceptionHandler extends ExceptionHandlerWrapper
+{
+ private ExceptionHandler wrapped;
+
+ @Inject
+ private ViewNavigationHandler viewNavigationHandler;
+
+ DefaultErrorViewExceptionHandler(ExceptionHandler wrapped)
+ {
+ this.wrapped = wrapped;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handle() throws FacesException
+ {
+ Iterator<ExceptionQueuedEvent> exceptionQueuedEventIterator = getUnhandledExceptionQueuedEvents().iterator();
+
+ while (exceptionQueuedEventIterator.hasNext())
+ {
+ ExceptionQueuedEventContext exceptionQueuedEventContext =
+ (ExceptionQueuedEventContext) exceptionQueuedEventIterator.next().getSource();
+
+ @SuppressWarnings({"ThrowableResultOfMethodCallIgnored"})
+ Throwable throwable = exceptionQueuedEventContext.getException();
+
+ String viewId = null;
+
+ if (throwable instanceof ViewExpiredException)
+ {
+ viewId = ((ViewExpiredException) throwable).getViewId();
+ }
+ else if(throwable instanceof ContextNotActiveException)
+ {
+ FacesContext facesContext = exceptionQueuedEventContext.getContext();
+ Flash flash = facesContext.getExternalContext().getFlash();
+
+ //the error page uses a cdi scope which isn't active as well
+ if(flash.containsKey(ContextNotActiveException.class.getName()))
+ {
+ break;
+ }
+
+ if(facesContext.getViewRoot() != null)
+ {
+ viewId = facesContext.getViewRoot().getViewId();
+ }
+ }
+
+ if(viewId != null)
+ {
+ FacesContext facesContext = exceptionQueuedEventContext.getContext();
+ UIViewRoot uiViewRoot = facesContext.getApplication().getViewHandler().createView(facesContext, viewId);
+
+ if (uiViewRoot == null)
+ {
+ continue;
+ }
+
+ if(facesContext.isProjectStage(ProjectStage.Development) ||
+ ProjectStageProducer.getInstance().getProjectStage() ==
+ org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStage.Development)
+ {
+ throwable.printStackTrace();
+ }
+
+ facesContext.setViewRoot(uiViewRoot);
+ exceptionQueuedEventIterator.remove();
+
+ Flash flash = facesContext.getExternalContext().getFlash();
+ flash.put(throwable.getClass().getName(), throwable);
+ flash.keep(throwable.getClass().getName());
+
+ this.viewNavigationHandler.navigateTo(DefaultErrorView.class);
+
+ break;
+ }
+ }
+
+ this.wrapped.handle();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExceptionHandler getWrapped()
+ {
+ return wrapped;
+ }
+}