in impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java [1003:1168]
private NavigationCase getOutcomeNavigationCase(FacesContext facesContext, String fromAction, String outcome)
{
String implicitViewId = null;
boolean includeViewParams = false;
int index;
boolean isRedirect = false;
String queryString = null;
NavigationCase result = null;
String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
StringBuilder viewIdToTest = SharedStringBuilder.get(facesContext, OUTCOME_NAVIGATION_SB);
viewIdToTest.append(outcome);
// If viewIdToTest contains a query string, remove it and set queryString with that value.
index = viewIdToTest.indexOf("?");
if (index != -1)
{
queryString = viewIdToTest.substring(index + 1);
viewIdToTest.setLength(index);
// If queryString contains "faces-redirect=true", set isRedirect to true.
if (queryString.contains("faces-redirect=true"))
{
isRedirect = true;
}
// If queryString contains "includeViewParams=true" or
// "faces-include-view-params=true", set includeViewParams to true.
if (queryString.contains("includeViewParams=true")
|| queryString.contains("faces-include-view-params=true"))
{
includeViewParams = true;
}
}
// If viewIdToTest does not have a "file extension", use the one from the current viewId.
index = viewIdToTest.indexOf(".");
if (index == -1)
{
if (viewId != null)
{
index = viewId.lastIndexOf('.');
if (index != -1)
{
viewIdToTest.append(viewId.substring (index));
}
}
else
{
// This case happens when for for example there is a ViewExpiredException,
// and a custom ExceptionHandler try to navigate using implicit navigation.
// In this case, there is no UIViewRoot set on the FacesContext, so viewId
// is null.
// In this case, it should try to derive the viewId of the view that was
// not able to restore, to get the extension and apply it to
// the implicit navigation.
String tempViewId = getViewIdSupport().calculateViewId(facesContext);
if (tempViewId != null)
{
index = tempViewId.lastIndexOf('.');
if(index != -1)
{
viewIdToTest.append(tempViewId.substring(index));
}
}
}
if (log.isLoggable(Level.FINEST))
{
log.finest("getOutcomeNavigationCase -> viewIdToTest: " + viewIdToTest);
}
}
// If viewIdToTest does not start with "/", look for the last "/" in viewId. If not found, simply prepend "/".
// Otherwise, prepend everything before and including the last "/" in viewId.
boolean startWithSlash = false;
if (viewIdToTest.length() > 0)
{
startWithSlash = viewIdToTest.charAt(0) == '/';
}
if (!startWithSlash)
{
index = -1;
if (viewId != null)
{
index = viewId.lastIndexOf('/');
}
if (index == -1)
{
viewIdToTest.insert(0, '/');
}
else
{
viewIdToTest.insert(0, viewId, 0, index + 1);
}
}
// Apply normalization
String viewIdToTestString = null;
boolean applyNormalization = false;
for (int i = 0; i < viewIdToTest.length() - 1; i++)
{
if (viewIdToTest.charAt(i) == '.' &&
viewIdToTest.charAt(i+1) == '/')
{
applyNormalization = true;
break;
}
}
if (applyNormalization)
{
viewIdToTestString = FilenameUtils.normalize(viewIdToTest.toString(), true);
}
else
{
viewIdToTestString = viewIdToTest.toString();
}
// Call ViewHandler.deriveViewId() and set the result as implicitViewId.
implicitViewId = facesContext.getApplication().getViewHandler().deriveViewId(facesContext, viewIdToTestString);
if (implicitViewId != null)
{
// Append all params from the queryString
// (excluding faces-redirect, includeViewParams and faces-include-view-params)
Map<String, List<String>> params = null;
if (StringUtils.isNotBlank(queryString))
{
String[] splitQueryParams = AMP_PATTERN.split(queryString); // "&" or "&"
params = new HashMap<>(splitQueryParams.length, 1f);
for (String queryParam : splitQueryParams)
{
String[] splitParam = StringUtils.splitShortString(queryParam, '=');
if (splitParam.length == 2)
{
// valid parameter - add it to params
if ("includeViewParams".equals(splitParam[0])
|| "faces-include-view-params".equals(splitParam[0])
|| "faces-redirect".equals(splitParam[0]))
{
// ignore includeViewParams, faces-include-view-params and faces-redirect
continue;
}
List<String> paramValues = params.get(splitParam[0]);
if (paramValues == null)
{
paramValues = new ArrayList<>(5);
params.put(splitParam[0], paramValues);
}
paramValues.add(splitParam[1]);
}
else
{
// invalid parameter
throw new FacesException("Invalid parameter \"" + queryParam + "\" in outcome " + outcome);
}
}
}
// Finally, create the NavigationCase.
result = new NavigationCase(viewId, fromAction, outcome, null, implicitViewId, params, isRedirect,
includeViewParams);
}
return result;
}