protected void generatePortletUrl(HttpServletRequest request, IPortletWindow portletWindow, IPortletWindowId delegationChildId, PortletUrl portletUrl, StringBuilder url) {
//Get the encoding to use for the URL
final String encoding = this.getEncoding(request);
//Look to see if the window is being delegated to, if so recurse to the parent for URL generation first
final IPortletWindowId delegationParentId = portletWindow.getDelegationParent();
if (delegationParentId != null) {
final IPortletWindow delegateParent = this.portletWindowRegistry.getPortletWindow(request, delegationParentId);
PortletUrl parentUrl = this.portletDelegationManager.getParentPortletUrl(request, delegationParentId);
if (parentUrl == null) {
parentUrl = new PortletUrl(delegationParentId);
parentUrl.setWindowState(delegateParent.getWindowState());
parentUrl.setPortletMode(delegateParent.getPortletMode());
parentUrl.setParameters(delegateParent.getRequestParameters());
}
//Parent URLs MUST be in the same type as the child
parentUrl.setRequestType(portletUrl.getRequestType());
this.generatePortletUrl(request, delegateParent, portletWindow.getPortletWindowId(), parentUrl, url);
}
// TODO Need to decide how to deal with 'secure' URL requests
final IPortletWindowId portletWindowId = portletWindow.getPortletWindowId();
final IPortletEntity parentPortletEntity = this.portletWindowRegistry.getParentPortletEntity(request, portletWindowId);
final String channelSubscribeId = parentPortletEntity.getChannelSubscribeId();
WindowState windowState = portletUrl.getWindowState();
PortletMode portletMode = portletUrl.getPortletMode();
final WindowState previousWindowState = portletWindow.getWindowState();
final PortletMode previousPortletMode = portletWindow.getPortletMode();
//Only do this stuff for the top level window
if (delegationParentId == null) {
//Get the channel runtime data from the request attributes, it should have been set there by the portlet adapter
final ChannelRuntimeData channelRuntimeData = (ChannelRuntimeData)request.getAttribute(IPortletAdaptor.ATTRIBUTE__RUNTIME_DATA);
if (channelRuntimeData == null) {
throw new IllegalStateException("No ChannelRuntimeData was found as a request attribute for key '" + IPortletAdaptor.ATTRIBUTE__RUNTIME_DATA + "' on request '" + request + "'");
}
// Determine the base path for the URL
// If the next state is EXCLUSIVE or there is no state change and the current state is EXCLUSIVE use the worker URL base
if (IPortletAdaptor.EXCLUSIVE.equals(windowState) || (windowState == null && IPortletAdaptor.EXCLUSIVE.equals(previousWindowState))) {
final String urlBase = channelRuntimeData.getBaseWorkerURL(UPFileSpec.FILE_DOWNLOAD_WORKER);
url.append(urlBase);
}
//In detached, need to make sure the URL is right
else if (IPortletAdaptor.DETACHED.equals(windowState) || (windowState == null && IPortletAdaptor.DETACHED.equals(previousWindowState))) {
final UPFileSpec upFileSpec = new UPFileSpec(channelRuntimeData.getUPFile());
upFileSpec.setMethodNodeId(channelSubscribeId);
upFileSpec.setTargetNodeId(channelSubscribeId);
final String urlBase = upFileSpec.getUPFile();
url.append(urlBase);
}
//Switching back from detached to a normal state
else if (IPortletAdaptor.DETACHED.equals(previousWindowState) && windowState != null && !previousWindowState.equals(windowState)) {
final UPFileSpec upFileSpec = new UPFileSpec(channelRuntimeData.getUPFile());
upFileSpec.setMethodNodeId(UPFileSpec.USER_LAYOUT_ROOT_NODE);
final String urlBase = upFileSpec.getUPFile();
url.append(urlBase);
}
//No special handling, just use the base action URL
else {
final String urlBase = channelRuntimeData.getBaseActionURL();
url.append(urlBase);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Using root url base '" + url + "' for " + portletUrl);
}
}
//Set the request target, creating a transient window ID if needed
boolean forceWindowState = false;
final String portletWindowIdString;
//If rendering as a delegate just reuse the id (it will always be transient)
if (delegationParentId != null) {
portletWindowIdString = portletWindowId.toString();
}
//If switching from a non-transient state to a transient state generate a new transient window id
else if (this.transientWindowStates.contains(windowState) && !this.transientWindowStates.contains(previousWindowState)) {
final IPortletWindowId transientPortletWindowId = this.portletWindowRegistry.createTransientPortletWindowId(request, portletWindowId);
portletWindowIdString = transientPortletWindowId.toString();
}
//If the window is transient, it is in a transient state and it is switching from a non-transient state
else if (this.portletWindowRegistry.isTransient(request, portletWindowId) &&
!this.transientWindowStates.contains(windowState) &&
(windowState != null || !this.transientWindowStates.contains(previousWindowState))) {
//Get non-transient version of id
final IPortletEntityId portletEntityId = portletWindow.getPortletEntityId();
final IPortletWindowId defaultPortletWindowId = this.portletWindowRegistry.getDefaultPortletWindowId(portletEntityId);
portletWindowIdString = defaultPortletWindowId.getStringId();
if (windowState == null) {
final IPortletWindow defaultPortletWindow = this.portletWindowRegistry.getPortletWindow(request, defaultPortletWindowId);
if (!previousWindowState.equals(defaultPortletWindow.getWindowState())) {
forceWindowState = true;