private NavigationCase calcMatchingNavigationCase()

in impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java [1178:1351]


    private NavigationCase calcMatchingNavigationCase(FacesContext context,
                                                      Set<? extends NavigationCase> casesList,
                                                      String actionRef,
                                                      String outcome)
    {
        NavigationCase noConditionCase = null;
        NavigationCase firstCase = null;
        NavigationCase firstCaseIf = null;
        NavigationCase secondCase = null;
        NavigationCase secondCaseIf = null;
        NavigationCase thirdCase = null;
        NavigationCase thirdCaseIf = null;
        NavigationCase fourthCase = null;
        NavigationCase fourthCaseIf = null;
                        
        for (NavigationCase caze : casesList)
        {
            String cazeOutcome = caze.getFromOutcome();
            String cazeActionRef = caze.getFromAction();
            Boolean cazeIf = caze.getCondition(context);
            boolean ifMatches = cazeIf == null ? false : cazeIf;
            // Faces 2.0: support conditional navigation via <if>.
            // Use for later cases.
            
            if(outcome == null && (cazeOutcome != null || cazeIf == null) && actionRef == null)
            {
                //To match an outcome value of null, the <from-outcome> must be absent and the <if> element present.
                continue;
            }
            
            //If there are no conditions on navigation case save it and return as last resort
            if (cazeOutcome == null && cazeActionRef == null &&
                cazeIf == null && noConditionCase == null && outcome != null)
            {
                noConditionCase = caze;
            }
            
            if (cazeActionRef != null)
            {
                if (cazeOutcome != null)
                {
                    if (actionRef != null && outcome != null
                            && cazeActionRef.equals(actionRef) && cazeOutcome.equals(outcome))
                    {
                        // First case: match if <from-action> matches action and <from-outcome> matches outcome.
                        // Caveat: evaluate <if> if available.

                        if (cazeIf != null)
                        {
                            if (ifMatches)
                            {
                                firstCaseIf = caze;
                                //return caze;
                            }

                            continue;
                        }
                        else
                        {
                            firstCase = caze;
                        }
                    }
                }
                else
                {
                    if ((actionRef != null) && cazeActionRef.equals (actionRef))
                    {
                        // Third case: if only <from-action> specified, match against action.
                        // Caveat: if <if> is available, evaluate.  If not, only match if outcome is not null.
                        if (cazeIf != null)
                        {
                            if (ifMatches)
                            {
                                thirdCaseIf = caze;
                            }
                            
                            continue;
                        }
                        else
                        {
                            if (outcome != null)
                            {
                                thirdCase = caze;
                            }
                            
                            continue;
                        }
                    }
                    else
                    {
                        // cazeActionRef != null and cazeOutcome == null
                        // but cazeActionRef does not match. No additional operation
                        // required because cazeIf is only taken into account 
                        // it cazeActionRef match. 
                        continue;
                    }
                }
            }
            else
            {
                if (cazeOutcome != null && (outcome != null) && cazeOutcome.equals (outcome))
                {
                    // Second case: if only <from-outcome> specified, match against outcome.
                    // Caveat: if <if> is available, evaluate.

                    if (cazeIf != null)
                    {
                        if (ifMatches)
                        {
                            secondCaseIf = caze;
                        }

                        continue;
                    }
                    else
                    {
                        secondCase = caze;
                    }
                }
            }

            // Fourth case: anything else matches if outcome is not null or <if> is specified.
            if (outcome != null && cazeIf != null)
            {
                // Again, if <if> present, evaluate.
                if (ifMatches)
                {
                    fourthCaseIf = caze;
                }

                continue;
            }

            if ((cazeIf != null) && ifMatches)
            {
                fourthCase = caze;
            }
        }
        
        if (firstCaseIf != null)
        {
            return firstCaseIf;
        }
        else if (firstCase != null)
        {
            return firstCase;
        }
        else if (secondCaseIf != null)
        {
            return secondCaseIf;
        }
        else if (secondCase != null)
        {
            return secondCase;
        }
        else if (thirdCaseIf != null)
        {
            return thirdCaseIf;
        }
        else if (thirdCase != null)
        {
            return thirdCase;
        }
        else if (fourthCaseIf != null)
        {
            return fourthCaseIf;
        }
        else if (fourthCase != null)
        {
            return fourthCase;
        }
        
        return noConditionCase;
    }