*/
@Override
public String encodeActionURL(String url)
{
String viewId = null, path = null;
QueryString queryStr = null;
int queryStart = -1;
if (url.startsWith("#") || isExternalURL(url) || isDirectLink(url))
{
return url;
}
// url might contain DirectLink=false parameter -- spec says remove if
// it does.
url = removeDirectLink(url);
// Now determine the target viewId
// First: split URL into path and query string
// Hold onto QueryString for later processing
queryStart = url.indexOf('?');
if (queryStart != -1)
{
// Get the query string
queryStr = new QueryString(url.substring(queryStart + 1), "UTF8");
path = url.substring(0, queryStart);
}
else
{
path = url;
// construct an empty queryString to hold the viewId
queryStr = new QueryString("UTF8");
}
// Determine the viewId by inspecting the URL
if (!isRelativePath(path))
{
viewId = getViewIdFromPath(path);
}
else
{
viewId = getViewIdFromRelativePath(path);
}
if (viewId == null)
{
throw new FacesException("encodeActionURL: unable to recognize viewId");
}
// put the viewId in the QueryStr.
queryStr.addParameter(ACTION_ID_PARAMETER_NAME, viewId);
if (mPhase == Bridge.PortletPhase.RENDER_PHASE)
{ // render - write
// the viewId into
// the response
// (interaction
// state)
RenderResponse renderResponse = (RenderResponse) getResponse();
PortletURL actionURL = renderResponse.createActionURL();
// Add parameters so they don't get lost
Enumeration<String> list = queryStr.getParameterNames();
while (list.hasMoreElements())
{
String param = list.nextElement().toString();
if (param.equals(Bridge.PORTLET_MODE_PARAMETER))
{
try
{
actionURL.setPortletMode(new PortletMode(queryStr.getParameter(param)));
}
catch (Exception e)
{
; // do nothing -- just ignore
}
}
else if (param.equals(Bridge.PORTLET_WINDOWSTATE_PARAMETER))
{
try
{
actionURL.setWindowState(new WindowState(queryStr.getParameter(param)));
}
catch (Exception e)
{
; // do nothing -- just ignore
}
}
else if (param.equals(Bridge.PORTLET_SECURE_PARAMETER))
{
try
{
actionURL.setSecure(Boolean.getBoolean(queryStr.getParameter(param)));
}
catch (Exception e)
{
; // do nothing -- just ignore
}
}
else
{
actionURL.setParameter(param, queryStr.getParameter(param));
}
}
// TODO hack to workaround double encoding problem
url = actionURL.toString();
url = url.replaceAll("\\&\\;", "&");
}
else
{ // action - write the viewId to navigational state
ActionResponse actionResponse = (ActionResponse) getResponse();
// set request params into navigational states
Enumeration<String> list = queryStr.getParameterNames();
while (list.hasMoreElements())
{
String param = list.nextElement();
if (param.equals(Bridge.PORTLET_MODE_PARAMETER))
{
try
{
actionResponse.setPortletMode(new PortletMode(queryStr.getParameter(param)));
}
catch (Exception e)
{
//TODO: Ignoring is probably dangerous here as it means that we are
// EITHER using exceptions for flow control (which is extreemly
// inefficient) or we should log a message saying what the issue
// is. According to the Javadocs an exception is thrown here if the
// portlet mode is not allowed or if sendRedirect has already been
// called. In either case we should log an information type message
// here.
; // do nothing -- just ignore
}
}
else if (param.equals(Bridge.PORTLET_WINDOWSTATE_PARAMETER))
{
try
{
actionResponse.setWindowState(new WindowState(queryStr.getParameter(param)));
}
catch (Exception e)
{
; // do nothing -- just ignore
}
}
else if (param.equals(Bridge.PORTLET_SECURE_PARAMETER))
{
; // ignore -- do nothing as can't encode into an actionResponse
}
else
{
actionResponse.setRenderParameter(param, queryStr.getParameter(param));
}
}
}
// Because we want to support translating a redirect that occurs
// during a render as an in place navigation AND we can't reverse