in pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java [122:422]
public PortalURL parse(HttpServletRequest request) {
String reqURI = request.getRequestURI();
String contextPath = request.getContextPath();
String servletName = request.getServletPath();
if (isDebug) {
LOG.debug("Parsing. Context Path: " + contextPath + ", Servlet Name: " + servletName + ", Request URI: " + reqURI);
}
String urlBase = request.getScheme()+"://" + request.getServerName() + ":" + request.getServerPort();
// Construct portal URL using info retrieved from servlet request.
RelativePortalURLImpl portalURL = new RelativePortalURLImpl(urlBase, contextPath, servletName, this, request);
// Support added for filter. Should we separate into a different impl?
String pathInfo = request.getPathInfo();
if (pathInfo == null) {
if(servletName.contains(".jsp") && !servletName.endsWith(".jsp")) {
int idx = servletName.indexOf(".jsp")+".jsp".length();
pathInfo = servletName.substring(idx);
servletName = servletName.substring(0, idx);
portalURL = new RelativePortalURLImpl(urlBase, contextPath, servletName, this, request);
if (isDebug) {
LOG.debug("Constructed new URL due to JSP processing. pathInfo: " + pathInfo);
}
}
}
// we want to work with the untranslated path info, so extract it from the URI.
// chop off query string.
String prefix = contextPath + servletName;
int qi = reqURI.indexOf("?");
qi = (qi < 0) ? reqURI.length() : qi;
pathInfo = reqURI.substring(prefix.length(), qi);
if (isTrace) {
LOG.debug("Parsing request pathInfo: " + pathInfo);
}
// Need to set the render path (= page) and PRP mapper before the rest of the URL is parsed
StringBuilder renderPath = new StringBuilder();
if (pathInfo.length() > 0 && pathInfo.charAt(0) != '/') {
renderPath.append('/');
}
int ind = pathInfo.indexOf(TOKEN_DELIM + PREFIX);
if (ind < 0) {
// there are no parameters to process
renderPath.append(urlDecode(pathInfo));
pathInfo = "";
} else {
// parameters, etc. remain to be processed
renderPath.append(urlDecode(pathInfo.substring(0, ind)));
pathInfo = pathInfo.substring(ind);
}
portalURL.setRenderPath(renderPath.toString());
if (isTrace) {
LOG.debug("Parse: renderPath: " + renderPath.toString() + ", pathInfo: " + pathInfo);
}
// Set up public render parameter mapper & portlet ID list
ServletContext sc = request.getServletContext();
DriverConfiguration dc = (DriverConfiguration) sc.getAttribute(AttributeKeys.DRIVER_CONFIG);
// special handling for default page
String rp = (renderPath.length() > 0) ? renderPath.toString() : null;
PublicRenderParameterMapper prpm = dc.getPublicRenderParameterService()
.getPRPMapper(rp);
portalURL.setPublicRenderParameterMapper(prpm);
Collection<String> pids = dc.getPageConfig(rp).getPortletIds();
portalURL.setPortletIds(pids);
// Extract the version info for the portlets on the page and store in URL
StringBuilder vstr = new StringBuilder();
if (isTrace) {
vstr.append("Portlet Versions: ");
}
for (String pid : pids) {
String appName = PortletWindowConfig.fromId(pid).getContextPath();
try {
String pv = dc.getPortletRegistryService().getPortletApplication(appName).getVersion();
portalURL.setVersion(pid, pv);
if (isTrace) {
vstr.append(pid).append(" = ").append(pv).append(", ");
}
} catch (Exception e) {
LOG.error("Portlet application definition could not be retrieved for " + appName);
}
}
if (isTrace) {
LOG.debug(vstr.toString());
}
// Tokenize the rest and process the tokens
ArrayList<String> portletIds = new ArrayList<String>();
if (pathInfo.length() > 2) {
String[] tokens = pathInfo.split(TOKEN_DELIM + PREFIX);
for (String t : tokens) {
// vals contains the component values of the token after the type
String type, val;
String[] vals;
if (t.length() < 3) {
// LOG.warn("Token >>" + t + "<< is too short!! ");
continue;
} else {
type = t.substring(0, 2);
val = t.substring(2);
vals = val.split(DELIM);
}
// If the first value is numeric, attempt to dereference the index to obtain the portlet ID.
// The code assumes that the portlet ID table in the URL appears directly after the render path.
int index = -1;
String pid = null;
if ((vals[0].length() > 0) && vals[0].matches("\\d+")) {
try {
index = Integer.parseInt(vals[0]);
if ((index >= 0) && (index < portletIds.size())) {
pid = portletIds.get(index);
}
} catch (Exception e) {
LOG.error("error parsing URL pid reference token. Token: " + vals[0] + ", exception: " + e.toString());
}
}
// Get the portlet IDs & reference numbers. The portlet IDs are URL encoded.
if (type.equals(PORTLET_ID)) {
portletIds.add(Integer.parseInt(vals[1]), urlDecode(vals[0]));
continue;
}
// Cacheability definition: portalURL.setCacheability().
if (type.equals(CACHE_LEVEL)) {
portalURL.setCacheability(urlDecode(vals[0]));
continue;
}
// ResourceID definition: portalURL.setResourceID().
if (type.equals(RESOURCE_ID)) {
portalURL.setResourceID(urlDecode(vals[0]));
continue;
}
// Authenticate definition: portalURL.setAuthenticated().
if (type.equals(AUTHENTICATE)) {
portalURL.setAuthenticated(Boolean.valueOf(urlDecode(vals[0])));
continue;
}
// Resource window definition: portalURL.setResourceWindow().
if (type.equals(RESOURCE)) {
portalURL.setTargetWindow(pid);
portalURL.setType(URLType.Resource);
continue;
}
// Render window definition: portalURL.setResourceWindow().
if (type.equals(RENDER)) {
portalURL.setTargetWindow(pid);
portalURL.setType(URLType.Render);
continue;
}
// Action window definition: portalURL.setActionWindow().
if (type.equals(ACTION)) {
portalURL.setTargetWindow(pid);
portalURL.setType(URLType.Action);
continue;
}
// Ajax Action window definition: portalURL.setActionWindow().
if (type.equals(AJAX_ACTION)) {
portalURL.setTargetWindow(pid);
portalURL.setType(URLType.AjaxAction);
continue;
}
// Partial Action window definition: portalURL.setActionWindow().
if (type.equals(PARTIAL_ACTION)) {
portalURL.setTargetWindow(pid);
portalURL.setType(URLType.PartialAction);
continue;
}
// Window state definition: portalURL.setWindowState().
if (type.equals(WINDOW_STATE)) {
portalURL.setWindowState(pid, new WindowState(urlDecode(vals[1])));
continue;
}
// Portlet mode definition: portalURL.setPortletMode().
if (type.equals(PORTLET_MODE)) {
portalURL.setPortletMode(pid, new PortletMode(urlDecode(vals[1])));
continue;
}
// The remaining types deal with parameters, so extract the
// parameter name and values.
StringBuilder dbgstr = new StringBuilder();
if (isTrace) {
dbgstr.append("Decoding parameter: window ID=").append(pid)
.append(", name/value=").append(vals[1]);
}
String values = vals[1];
if (type.equals(PUBLIC_RENDER_PARAM)) {
if (vals.length != 3) {
LOG.warn("Bad PRP Token: " + val);
} else {
values = vals[2];
}
}
String[] pVals = values.split(VALUE_DELIM, -1);
String[] paramValues = new String[0];
String paramName = "";
boolean isEmptyArray = false;
if (pVals.length > 1) {
if (pVals.length == 2 && pVals[1].equals(VALUE_ARRAY_EMPTY)) {
isEmptyArray = true;
}
for (int i = 0; i < pVals.length; i++){
if (pVals[i].equals(VALUE_NULL)) {
pVals[i] = null;
} else {
pVals[i] = urlDecode(pVals[i]);
}
}
}
if (pVals.length == 0 || pVals[0] == null) {
LOG.warn("Bad parameter token: " + values);
} else {
paramName = pVals[0];
if (isEmptyArray) {
paramValues = new String[0];
} else {
paramValues = Arrays.copyOfRange(pVals, 1, pVals.length);
}
}
if (isTrace) {
dbgstr.append(", paramName=").append(paramName);
dbgstr.append(", Values length=").append(paramValues.length);
dbgstr.append(", paramValues=").append(Arrays.toString(paramValues));
LOG.debug(dbgstr.toString());
}
// Portal URL parameter: portalURL.addParameter().
if(type.equals(RENDER_PARAM)) {
portalURL.addParameter(new PortalURLParameter(pid, paramName, paramValues));
continue;
}
// Portal URL parameter: portalURL.addParameter().
if(type.equals(ACTION_PARAM)) {
portalURL.addParameter(new PortalURLParameter(pid, paramName, paramValues,
PortalURLParameter.PARAM_TYPE_ACTION));
continue;
}
// Portal URL parameter: portalURL.addParameter().
if(type.equals(RESOURCE_PARAM)) {
portalURL.addParameter(new PortalURLParameter(pid, paramName, paramValues,
PortalURLParameter.PARAM_TYPE_RESOURCE));
continue;
}
//set public parameter in portalURL
if (type.equals(PUBLIC_RENDER_PARAM)){
PublicRenderParameterMapper mapper = portalURL.getPublicRenderParameterMapper();
int prpGroup = mapper.getIndex(pid, paramName);
if (prpGroup >= 0) {
mapper.setValues(prpGroup, paramValues);
} else {
StringBuilder sb = new StringBuilder("Could not find public render parameter group for portlet ID=");
sb.append(pid).append(", parameter name=").append(paramName);
LOG.warn(sb.toString());
}
continue;
}
}
}
// If we're dealing with a render request (with or without target portlet),
// we can parse the servlet request parameters directly.
if (portalURL.getType() == URLType.Render || portalURL.getType() == URLType.Portal) {
portalURL.handleServletRequestParams();
}
if (isTrace) {
LOG.debug("Found " + portletIds.size() + " IDs: " + Arrays.toString(portletIds.toArray()));
}
// Return the portal URL.
return portalURL;
}