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;
String viewIdToTest = 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 = viewIdToTest.substring (0, index);
// If queryString contains "faces-redirect=true", set isRedirect to true.
if (queryString.indexOf ("faces-redirect=true") != -1)
{
isRedirect = true;
}
// If queryString contains "includeViewParams=true" or
// "faces-include-view-params=true", set includeViewParams to true.
if (queryString.indexOf("includeViewParams=true") != -1
|| queryString.indexOf("faces-include-view-params=true") != -1)
{
includeViewParams = true;
}
}
// If viewIdToTest does not have a "file extension", use the one from the current viewId.
index = viewIdToTest.indexOf (".");
if (index == -1 && viewId != null)
{
index = viewId.lastIndexOf(".");
if (index != -1)
{
viewIdToTest += viewId.substring (index);
}
}
// 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.
if (!viewIdToTest.startsWith ("/") && viewId != null)
{
index = viewId.lastIndexOf ("/");
if (index == -1)
{
viewIdToTest = "/" + viewIdToTest;
}
else
{
viewIdToTest = viewId.substring (0, index + 1) + viewIdToTest;
}
}
// Call ViewHandler.deriveViewId() and set the result as implicitViewId.
try
{
implicitViewId = facesContext.getApplication().getViewHandler().deriveViewId (facesContext, viewIdToTest);
}
catch (UnsupportedOperationException e)
{
// This is the case when a pre-JSF 2.0 ViewHandler is used.
// In this case, the default algorithm must be used.
// FIXME: I think we're always calling the "default" ViewHandler.deriveViewId() algorithm and we don't
// distinguish between pre-JSF 2.0 and JSF 2.0 ViewHandlers. This probably needs to be addressed.
}
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 (queryString != null && !"".equals(queryString))
{
String[] splitQueryParams = queryString.split("&(amp;)?"); // "&" or "&"
params = new HashMap<String, List<String>>();
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)
{
// no value for the given parameter yet
paramValues = new ArrayList<String>();
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;
}