EXTCDI-311 support external handling of navigation-cases
git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/cdi/trunk@1551515 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/CodiNavigationHandler.java b/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/CodiNavigationHandler.java
index f8fea1d..67cdc38 100644
--- a/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/CodiNavigationHandler.java
+++ b/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/CodiNavigationHandler.java
@@ -197,7 +197,7 @@
return result;
}
- return new NavigationCaseMapWrapper(result);
+ return new NavigationCaseMapWrapper(result, this.wrapped);
}
/**
diff --git a/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/NavigationCaseMapWrapper.java b/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/NavigationCaseMapWrapper.java
index d95e87c..64c808e 100644
--- a/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/NavigationCaseMapWrapper.java
+++ b/jee-modules/jsf20-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf2/impl/navigation/NavigationCaseMapWrapper.java
@@ -25,7 +25,9 @@
import org.apache.myfaces.extensions.cdi.jsf.impl.util.JsfUtils;
import org.apache.myfaces.extensions.cdi.jsf.impl.util.RequestParameter;
+import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
+import javax.faces.application.NavigationHandler;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import java.util.List;
@@ -34,6 +36,7 @@
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
+import java.util.logging.Logger;
/**
* Destructive operations aren't supported (compared to the SubKeyMap used in MyFaces).
@@ -41,22 +44,39 @@
*/
class NavigationCaseMapWrapper implements Map<String, Set<NavigationCase>>
{
+ private static final Logger LOG = Logger.getLogger(NavigationCaseMapWrapper.class.getName());
+
private Map<String, Set<NavigationCase>> wrappedNavigationCaseMap;
+ private NavigationHandler wrapped;
private final Map<String, Set<NavigationCase>> viewConfigBasedNavigationCaseCache;
/**
* Constructor for wrapping the given navigation-cases
* @param navigationCases current navigation-cases
+ * @param wrapped
*/
- public NavigationCaseMapWrapper(Map<String, Set<NavigationCase>> navigationCases)
+ public NavigationCaseMapWrapper(Map<String, Set<NavigationCase>> navigationCases, NavigationHandler wrapped)
{
this.wrappedNavigationCaseMap = navigationCases;
+ this.wrapped = wrapped;
this.viewConfigBasedNavigationCaseCache = createViewConfigBasedNavigationCases(false);
}
private Map<String, Set<NavigationCase>> createViewConfigBasedNavigationCases(boolean allowParameters)
{
- Map<String, Set<NavigationCase>> result = new HashMap<String, Set<NavigationCase>>();
+ Map<String, Set<NavigationCase>> result;
+
+ if (this.wrapped instanceof ConfigurableNavigationHandler)
+ {
+ result = new DelegatingMap((ConfigurableNavigationHandler)this.wrapped);
+ }
+ else
+ {
+ LOG.warning("the wrapped navigation-handler doesn't extend " +
+ ConfigurableNavigationHandler.class.getName() +
+ ". therefore std. navigation-rules might not work correctly with mojarra");
+ result = new HashMap<String, Set<NavigationCase>>();
+ }
Collection<ViewConfigDescriptor> viewConfigDescriptors = ViewConfigCache.getViewConfigDescriptors();
@@ -233,4 +253,70 @@
result.addAll(createViewConfigBasedNavigationCases(true).entrySet());
return result;
}
+
+ //currently not a complete handling, but enough to fix the issues with mojarra
+ private class DelegatingMap extends HashMap<String, Set<NavigationCase>>
+ {
+ private static final long serialVersionUID = -955468874397821639L;
+ private final ConfigurableNavigationHandler wrapped;
+
+ private DelegatingMap(ConfigurableNavigationHandler wrapped)
+ {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public Set<NavigationCase> put(String key, Set<NavigationCase> value)
+ {
+ //delegate to the wrapped instance -> the innermost handler needs to receive it
+ //(because mojarra uses ConfigurableNavigationHandler#getNavigationCases
+ // to add cases for std. nav.rules from the outside)
+ return this.wrapped.getNavigationCases().put(key, value);
+ }
+
+ @Override
+ public Set<NavigationCase> get(Object key)
+ {
+ Set<NavigationCase> navigationCases = super.get(key);
+ if (navigationCases == null)
+ {
+ navigationCases = new HashSet<NavigationCase>();
+ put((String)key, navigationCases);
+ }
+
+ return new DelegatingSet(navigationCases, this.wrapped, (String)key);
+ }
+ }
+
+ //currently not a complete handling, but enough to fix the issues with mojarra
+ private class DelegatingSet extends HashSet<NavigationCase>
+ {
+ private static final long serialVersionUID = -7040572530963900394L;
+
+ private final ConfigurableNavigationHandler wrapped;
+ private String navigationCaseKey;
+
+ private DelegatingSet(Collection<? extends NavigationCase> c,
+ ConfigurableNavigationHandler wrapped,
+ String navigationCaseKey)
+ {
+ super(c);
+ this.wrapped = wrapped;
+ this.navigationCaseKey = navigationCaseKey;
+ }
+
+ @Override
+ public boolean add(NavigationCase navigationCase)
+ {
+ Set<NavigationCase> navigationCases = this.wrapped.getNavigationCases().get(this.navigationCaseKey);
+
+ if (navigationCases == null)
+ {
+ navigationCases = new HashSet<NavigationCase>();
+ this.wrapped.getNavigationCases().put(this.navigationCaseKey, navigationCases);
+ }
+
+ return navigationCases.add(navigationCase);
+ }
+ }
}