You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2013/06/13 09:17:21 UTC

svn commit: r1492546 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces: application/ActionListenerImpl.java flow/FlowImpl.java flow/NavigationCaseImpl.java flow/builder/NavigationCaseBuilderImpl.java

Author: lu4242
Date: Thu Jun 13 07:17:20 2013
New Revision: 1492546

URL: http://svn.apache.org/r1492546
Log:
MYFACES-3691 Implement Faces Flows (ActionListener and NavigationCase builder)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/NavigationCaseImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/NavigationCaseBuilderImpl.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java?rev=1492546&r1=1492545&r2=1492546&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java Thu Jun 13 07:17:20 2013
@@ -86,7 +86,17 @@ public class ActionListenerImpl implemen
         }
         
         NavigationHandler navigationHandler = application.getNavigationHandler();
-        navigationHandler.handleNavigation(facesContext, fromAction, outcome);
+        String toFlowDocumentId = (component != null) ? 
+            (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
+        
+        if (toFlowDocumentId != null)
+        {
+            navigationHandler.handleNavigation(facesContext, fromAction, outcome, toFlowDocumentId);
+        }
+        else
+        {
+            navigationHandler.handleNavigation(facesContext, fromAction, outcome);
+        }
         //Render Response if needed
         facesContext.renderResponse();
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java?rev=1492546&r1=1492545&r2=1492546&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java Thu Jun 13 07:17:20 2013
@@ -21,11 +21,13 @@ package org.apache.myfaces.flow;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.el.MethodExpression;
 import javax.faces.application.NavigationCase;
+import javax.faces.context.FacesContext;
 import javax.faces.flow.Flow;
 import javax.faces.flow.FlowCallNode;
 import javax.faces.flow.FlowNode;
@@ -49,6 +51,8 @@ public class FlowImpl extends Flow imple
     private String _id;
     private String _definingDocumentId;
     
+    private Map<String, FlowNode> _flowNodeMap;
+    
     // The idea is use a normal HashMap, since there will not be modifications
     // after initialization ( all setters must call checkInitialized() )
     private Map<String, Parameter> _inboundParametersMap;
@@ -67,6 +71,9 @@ public class FlowImpl extends Flow imple
     private Map<String, SwitchNode> _unmodifiableSwitchesMap;
     private List<ViewNode> _unmodifiableViewsList;
     
+    private Map<String, Set<NavigationCase>> _navigationCases;
+    private Map<String, Set<NavigationCase>> _unmodifiableNavigationCases;
+    
     // No need to make it volatile, because FlowImpl instances are
     // created and initialized only at application startup, by a single
     // thread.
@@ -74,12 +81,14 @@ public class FlowImpl extends Flow imple
     
     public FlowImpl()
     {
+        _flowNodeMap = new HashMap<String, FlowNode>();
         _inboundParametersMap = new HashMap<String, Parameter>();
         _flowCallsMap = new HashMap<String, FlowCallNode>();
         _methodCallsList = new ArrayList<MethodCallNode>();
         _returnsMap = new HashMap<String, ReturnNode>();
         _switchesMap = new HashMap<String, SwitchNode>();
         _viewsList = new ArrayList<ViewNode>();
+        _navigationCases = new HashMap<String, Set<NavigationCase>>();
         
         // Collections.unmodifiableMap(...) uses delegation pattern, so as long
         // as we don't modify _inboundParametersMap in the wrong time, it
@@ -90,11 +99,14 @@ public class FlowImpl extends Flow imple
         _unmodifiableReturnsMap = Collections.unmodifiableMap(_returnsMap);
         _unmodifiableSwitchesMap = Collections.unmodifiableMap(_switchesMap);
         _unmodifiableViewsList = Collections.unmodifiableList(_viewsList);
-
+        
+        _unmodifiableNavigationCases = Collections.unmodifiableMap(_navigationCases);
     }
     
     public void freeze()
     {
+        
+        
         _initialized = true;
         
         for (Map.Entry<String, Parameter> entry : _inboundParametersMap.entrySet())
@@ -240,6 +252,7 @@ public class FlowImpl extends Flow imple
     {
         checkInitialized();
         _flowCallsMap.put(key, value);
+        _flowNodeMap.put(value.getId(), value);
     }
 
     @Override
@@ -252,6 +265,7 @@ public class FlowImpl extends Flow imple
     {
         checkInitialized();
         _methodCallsList.add(value);
+        _flowNodeMap.put(value.getId(), value);
     }
 
     @Override
@@ -264,6 +278,7 @@ public class FlowImpl extends Flow imple
     {
         checkInitialized();
         _returnsMap.put(key, value);
+        _flowNodeMap.put(value.getId(), value);
     }
 
     @Override
@@ -276,6 +291,7 @@ public class FlowImpl extends Flow imple
     {
         checkInitialized();
         _switchesMap.put(key, value);
+        _flowNodeMap.put(value.getId(), value);
     }
 
     @Override
@@ -288,20 +304,69 @@ public class FlowImpl extends Flow imple
     {
         checkInitialized();
         _viewsList.add(value);
+        _flowNodeMap.put(value.getId(), value);
     }
 
     @Override
     public FlowCallNode getFlowCall(Flow targetFlow)
     {
-        //TODO: Implement me!
-        throw new UnsupportedOperationException("Not supported yet.");
+        FacesContext facesContext = null;
+        for (Map.Entry<String, FlowCallNode> entry : _flowCallsMap.entrySet())
+        {
+            if (facesContext == null)
+            {
+                facesContext = FacesContext.getCurrentInstance();
+            }
+            String calledDocumentId = entry.getValue().getCalledFlowDocumentId(facesContext);
+            String calledFlowId = entry.getValue().getCalledFlowId(facesContext);
+            if (targetFlow.getDefiningDocumentId().equals(calledDocumentId) &&
+                targetFlow.getId().equals(calledFlowId) )
+            {
+                return entry.getValue();
+            }
+        }
+        return null;
     }
     
     @Override
     public FlowNode getNode(String nodeId)
     {
-        //TODO: Implement me!
-        throw new UnsupportedOperationException("Not supported yet.");
+        return _flowNodeMap.get(nodeId);
+    }
+    
+    public void addNavigationCases(String fromViewId, Set<NavigationCase> navigationCases)
+    {
+        checkInitialized();
+        Set<NavigationCase> navigationCaseSet = _navigationCases.get(fromViewId);
+        if (navigationCaseSet == null)
+        {
+            navigationCaseSet = new HashSet<NavigationCase>();
+            _navigationCases.put(fromViewId, navigationCaseSet);
+        }
+        navigationCaseSet.addAll(navigationCases);
+    }
+    
+    public void addNavigationCase(NavigationCase navigationCase)
+    {
+        checkInitialized();
+        Set<NavigationCase> navigationCaseSet = _navigationCases.get(navigationCase.getFromViewId());
+        if (navigationCaseSet == null)
+        {
+            navigationCaseSet = new HashSet<NavigationCase>();
+            _navigationCases.put(navigationCase.getFromViewId(), navigationCaseSet);
+        }
+        navigationCaseSet.add(navigationCase);
+    }
+    
+    public void removeNavigationCase(NavigationCase navigationCase)
+    {
+        checkInitialized();
+        Set<NavigationCase> navigationCaseSet = _navigationCases.get(navigationCase.getFromViewId());
+        if (navigationCaseSet == null)
+        {
+            return;
+        }
+        navigationCaseSet.remove(navigationCase);
     }
 
     private void checkInitialized() throws IllegalStateException
@@ -315,7 +380,7 @@ public class FlowImpl extends Flow imple
     @Override
     public Map<String, Set<NavigationCase>> getNavigationCases()
     {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return _unmodifiableNavigationCases;
     }
     
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/NavigationCaseImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/NavigationCaseImpl.java?rev=1492546&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/NavigationCaseImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/NavigationCaseImpl.java Thu Jun 13 07:17:20 2013
@@ -0,0 +1,426 @@
+/*
+ * 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.flow;
+
+import java.util.List;
+import java.util.Map;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.faces.application.NavigationCase;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+public class NavigationCaseImpl extends NavigationCase implements Freezable
+{
+
+    private String _condition;
+    private String _fromAction;
+    private String _fromOutcome;
+    private String _fromViewId;
+    private String _toViewId;
+    private String _toFlowDocumentId;
+    private boolean _includeViewParams;
+    private boolean _redirect;
+    private Map<String, List<String>> _parameters;
+    private ValueExpression _conditionExpression;
+    private ValueExpression _toViewIdExpression;
+
+    private boolean _initialized;
+
+    public NavigationCaseImpl()
+    {
+        super(null, null, null, null, null, null, false, false);
+    }
+
+    public NavigationCaseImpl(String fromViewId, String fromAction, String fromOutcome, String condition, 
+            String toViewId,
+            Map<String, List<String>> parameters, boolean redirect, boolean includeViewParams)
+    {
+        super(fromViewId, fromAction, fromOutcome, condition, toViewId, parameters, redirect, includeViewParams);
+        _condition = condition;
+        _fromViewId = fromViewId;
+        _fromAction = fromAction;
+        _fromOutcome = fromOutcome;
+        _toViewId = toViewId;
+        _toFlowDocumentId = null;
+        _redirect = redirect;
+        _includeViewParams = includeViewParams;
+        _parameters = parameters;
+    }
+
+    public NavigationCaseImpl(String fromViewId, String fromAction, String fromOutcome, String condition, 
+            String toViewId,
+            String toFlowDocumentId, Map<String, List<String>> parameters, boolean redirect,
+            boolean includeViewParams)
+    {
+        super(fromViewId, fromAction, fromOutcome, condition, toViewId, toFlowDocumentId, parameters, redirect, 
+                includeViewParams);
+        _condition = condition;
+        _fromViewId = fromViewId;
+        _fromAction = fromAction;
+        _fromOutcome = fromOutcome;
+        _toViewId = toViewId;
+        _toFlowDocumentId = toFlowDocumentId;
+        _redirect = redirect;
+        _includeViewParams = includeViewParams;
+        _parameters = parameters;
+
+    }
+
+    /**
+     * @return the _condition
+     */
+    public String getCondition()
+    {
+        return _condition;
+    }
+
+    /**
+     * @param condition the _condition to set
+     */
+    public void setCondition(String condition)
+    {
+        checkInitialized();
+        this._condition = condition;
+    }
+
+    /**
+     * @return the _fromAction
+     */
+    public String getFromAction()
+    {
+        return _fromAction;
+    }
+
+    /**
+     * @param fromAction the _fromAction to set
+     */
+    public void setFromAction(String fromAction)
+    {
+        checkInitialized();
+        this._fromAction = fromAction;
+    }
+
+    /**
+     * @return the _fromOutcome
+     */
+    public String getFromOutcome()
+    {
+        return _fromOutcome;
+    }
+
+    /**
+     * @param fromOutcome the _fromOutcome to set
+     */
+    public void setFromOutcome(String fromOutcome)
+    {
+        checkInitialized();
+        this._fromOutcome = fromOutcome;
+    }
+
+    /**
+     * @return the _fromViewId
+     */
+    public String getFromViewId()
+    {
+        return _fromViewId;
+    }
+
+    /**
+     * @param fromViewId the _fromViewId to set
+     */
+    public void setFromViewId(String fromViewId)
+    {
+        checkInitialized();
+        this._fromViewId = fromViewId;
+    }
+
+    /**
+     * @return the _toViewId
+     */
+    public String getToViewId()
+    {
+        return _toViewId;
+    }
+
+    /**
+     * @param toViewId the _toViewId to set
+     */
+    public void setToViewId(String toViewId)
+    {
+        checkInitialized();
+        this._toViewId = toViewId;
+    }
+
+    /**
+     * @return the _toFlowDocumentId
+     */
+    public String getToFlowDocumentId()
+    {
+        return _toFlowDocumentId;
+    }
+
+    /**
+     * @param toFlowDocumentId the _toFlowDocumentId to set
+     */
+    public void setToFlowDocumentId(String toFlowDocumentId)
+    {
+        checkInitialized();
+        this._toFlowDocumentId = toFlowDocumentId;
+    }
+
+    /**
+     * @return the _includeViewParams
+     */
+    public boolean isIncludeViewParams()
+    {
+        return _includeViewParams;
+    }
+
+    /**
+     * @param includeViewParams the _includeViewParams to set
+     */
+    public void setIncludeViewParams(boolean includeViewParams)
+    {
+        checkInitialized();
+        this._includeViewParams = includeViewParams;
+    }
+
+    /**
+     * @return the _redirect
+     */
+    public boolean isRedirect()
+    {
+        return _redirect;
+    }
+
+    /**
+     * @param redirect the _redirect to set
+     */
+    public void setRedirect(boolean redirect)
+    {
+        checkInitialized();
+        this._redirect = redirect;
+    }
+
+    /**
+     * @return the _parameters
+     */
+    public Map<String, List<String>> getParameters()
+    {
+        return _parameters;
+    }
+
+    /**
+     * @param parameters the _parameters to set
+     */
+    public void setParameters(Map<String, List<String>> parameters)
+    {
+        checkInitialized();
+        this._parameters = parameters;
+    }
+
+    /**
+     * @return the _conditionExpression
+     */
+    public ValueExpression getConditionExpression()
+    {
+        return _conditionExpression;
+    }
+
+    /**
+     * @param conditionExpression the _conditionExpression to set
+     */
+    public void setConditionExpression(ValueExpression conditionExpression)
+    {
+        checkInitialized();
+        this._conditionExpression = conditionExpression;
+    }
+
+    /**
+     * @return the _toViewIdExpression
+     */
+    public ValueExpression getToViewIdExpression()
+    {
+        return _toViewIdExpression;
+    }
+
+    /**
+     * @param toViewIdExpression the _toViewIdExpression to set
+     */
+    public void setToViewIdExpression(ValueExpression toViewIdExpression)
+    {
+        checkInitialized();
+        this._toViewIdExpression = toViewIdExpression;
+    }
+
+    public Boolean getCondition(FacesContext context)
+    {
+        if (_condition == null)
+        {
+            return null;
+        }
+
+        ValueExpression expression = _getConditionExpression(context);
+
+        return Boolean.TRUE.equals(expression.getValue(context.getELContext()));
+    }
+
+    private ValueExpression _getConditionExpression(FacesContext context)
+    {
+        assert _condition != null;
+
+        if (_conditionExpression == null)
+        {
+            ExpressionFactory factory = context.getApplication().getExpressionFactory();
+            _conditionExpression = factory.createValueExpression(context.getELContext(), _condition, Boolean.class);
+        }
+
+        return _conditionExpression;
+    }
+
+    public String getToViewId(FacesContext context)
+    {
+        if (_toViewId == null)
+        {
+            return null;
+        }
+
+        ValueExpression expression = _getToViewIdExpression(context);
+
+        return (String) ((expression.isLiteralText())
+                ? expression.getExpressionString() : expression.getValue(context.getELContext()));
+    }
+
+    private ValueExpression _getToViewIdExpression(FacesContext context)
+    {
+        assert _toViewId != null;
+
+        if (_toViewIdExpression == null)
+        {
+            ExpressionFactory factory = context.getApplication().getExpressionFactory();
+            _toViewIdExpression = factory.createValueExpression(context.getELContext(), _toViewId, String.class);
+        }
+
+        return _toViewIdExpression;
+    }
+
+    public boolean hasCondition()
+    {
+        return _condition != null && _condition.length() > 0;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int hash = 5;
+        hash = 47 * hash + (this._condition != null ? this._condition.hashCode() : 0);
+        hash = 47 * hash + (this._fromAction != null ? this._fromAction.hashCode() : 0);
+        hash = 47 * hash + (this._fromOutcome != null ? this._fromOutcome.hashCode() : 0);
+        hash = 47 * hash + (this._fromViewId != null ? this._fromViewId.hashCode() : 0);
+        hash = 47 * hash + (this._toViewId != null ? this._toViewId.hashCode() : 0);
+        hash = 47 * hash + (this._toFlowDocumentId != null ? this._toFlowDocumentId.hashCode() : 0);
+        hash = 47 * hash + (this._includeViewParams ? 1 : 0);
+        hash = 47 * hash + (this._redirect ? 1 : 0);
+        hash = 47 * hash + (this._parameters != null ? this._parameters.hashCode() : 0);
+        hash = 47 * hash + (this._conditionExpression != null ? this._conditionExpression.hashCode() : 0);
+        hash = 47 * hash + (this._toViewIdExpression != null ? this._toViewIdExpression.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+        {
+            return false;
+        }
+        if (getClass() != obj.getClass())
+        {
+            return false;
+        }
+        final NavigationCaseImpl other = (NavigationCaseImpl) obj;
+        if ((this._condition == null) ? (other._condition != null) : !this._condition.equals(other._condition))
+        {
+            return false;
+        }
+        if ((this._fromAction == null) ? (other._fromAction != null) : !this._fromAction.equals(other._fromAction))
+        {
+            return false;
+        }
+        if ((this._fromOutcome == null) ? (other._fromOutcome != null) : 
+                !this._fromOutcome.equals(other._fromOutcome))
+        {
+            return false;
+        }
+        if ((this._fromViewId == null) ? (other._fromViewId != null) : !this._fromViewId.equals(other._fromViewId))
+        {
+            return false;
+        }
+        if ((this._toViewId == null) ? (other._toViewId != null) : !this._toViewId.equals(other._toViewId))
+        {
+            return false;
+        }
+        if ((this._toFlowDocumentId == null) ? (other._toFlowDocumentId != null) : 
+                !this._toFlowDocumentId.equals(other._toFlowDocumentId))
+        {
+            return false;
+        }
+        if (this._includeViewParams != other._includeViewParams)
+        {
+            return false;
+        }
+        if (this._redirect != other._redirect)
+        {
+            return false;
+        }
+        if (this._parameters != other._parameters && (this._parameters == null || 
+                !this._parameters.equals(other._parameters)))
+        {
+            return false;
+        }
+        if (this._conditionExpression != other._conditionExpression && (this._conditionExpression == null || 
+                !this._conditionExpression.equals(other._conditionExpression)))
+        {
+            return false;
+        }
+        if (this._toViewIdExpression != other._toViewIdExpression && (this._toViewIdExpression == null || 
+                !this._toViewIdExpression.equals(other._toViewIdExpression)))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    public void freeze()
+    {
+        _initialized = true;
+    }
+    
+    private void checkInitialized() throws IllegalStateException
+    {
+        if (_initialized)
+        {
+            throw new IllegalStateException("Flow is inmutable once initialized");
+        }
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/NavigationCaseBuilderImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/NavigationCaseBuilderImpl.java?rev=1492546&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/NavigationCaseBuilderImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/NavigationCaseBuilderImpl.java Thu Jun 13 07:17:20 2013
@@ -0,0 +1,146 @@
+/*
+ * 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.flow.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.el.ValueExpression;
+import javax.faces.flow.builder.NavigationCaseBuilder;
+import org.apache.myfaces.flow.FlowImpl;
+import org.apache.myfaces.flow.NavigationCaseImpl;
+
+/**
+ *
+ * @author lu4242
+ */
+public class NavigationCaseBuilderImpl extends NavigationCaseBuilder
+{
+    private FlowImpl _facesFlow;
+    private FlowBuilderImpl _flowBuilder;
+    private NavigationCaseImpl _navigationCaseImpl;
+    
+    public NavigationCaseBuilderImpl(FlowBuilderImpl flowBuilder, FlowImpl facesFlow)
+    {
+        this._flowBuilder = flowBuilder;
+        this._facesFlow = facesFlow;
+        this._navigationCaseImpl = new NavigationCaseImpl();
+    }
+    
+    @Override
+    public NavigationCaseBuilder fromViewId(String fromViewId)
+    {
+        // This is the best place to add the navigation case into the flow, because
+        // fromViewId is required (cannot be null, and null does not mean '*')
+        if (this._navigationCaseImpl.getFromViewId() != null)
+        {
+            this._facesFlow.removeNavigationCase(_navigationCaseImpl);
+        }
+        if (fromViewId != null)
+        {
+            this._navigationCaseImpl.setFromViewId(fromViewId);
+            this._facesFlow.addNavigationCase(_navigationCaseImpl);
+        }
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder fromAction(String fromAction)
+    {
+        this._navigationCaseImpl.setFromAction(fromAction);
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder fromOutcome(String fromOutcome)
+    {
+        this._navigationCaseImpl.setFromOutcome(fromOutcome);
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder toViewId(String toViewId)
+    {
+        this._navigationCaseImpl.setToViewId(toViewId);
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder toFlowDocumentId(String toFlowDocumentId) 
+    {
+        this._navigationCaseImpl.setToFlowDocumentId(toFlowDocumentId);
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder condition(String condition)
+    {
+        this._navigationCaseImpl.setConditionExpression(null);
+        this._navigationCaseImpl.setCondition(condition);
+        return this;
+    }
+
+    @Override
+    public NavigationCaseBuilder condition(ValueExpression condition)
+    {
+        this._navigationCaseImpl.setCondition(null);
+        this._navigationCaseImpl.setConditionExpression(condition);
+        return this;
+    }
+
+    @Override
+    public RedirectBuilder redirect()
+    {
+        this._navigationCaseImpl.setRedirect(true);
+        return new RedirectBuilderImpl();
+    }
+    
+    public class RedirectBuilderImpl extends RedirectBuilder
+    {
+
+        @Override
+        public RedirectBuilder parameter(String name, String value)
+        {
+            //_navigationCaseImpl.
+            Map<String, List<String>> map = _navigationCaseImpl.getParameters();
+            if (map == null)
+            {
+                map = new HashMap<String, List<String>>();
+                _navigationCaseImpl.setParameters(map);
+            }
+            List<String> values = map.get(name);
+            if (values == null)
+            {
+                values = new ArrayList<String>();
+                map.put(name, values);
+            }
+            values.add(value);
+            return this;
+        }
+
+        @Override
+        public RedirectBuilder includeViewParams()
+        {
+            _navigationCaseImpl.setIncludeViewParams(true);
+            return this;
+        }
+        
+    }
+}