/**
* Licensed to Apereo under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. Apereo
* licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the License at the
* following location:
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apereo.portal.url;
import java.util.List;
import java.util.Map;
import javax.portlet.PortletMode;
import javax.portlet.WindowState;
import javax.servlet.http.HttpServletRequest;
import org.apereo.portal.IUserPreferencesManager;
import org.apereo.portal.api.portlet.DelegationRequest;
import org.apereo.portal.layout.IUserLayoutManager;
import org.apereo.portal.layout.node.IUserLayoutNodeDescription;
import org.apereo.portal.layout.node.IUserLayoutNodeDescription.LayoutNodeType;
import org.apereo.portal.portlet.delegation.IPortletDelegationManager;
import org.apereo.portal.portlet.om.IPortletEntity;
import org.apereo.portal.portlet.om.IPortletWindow;
import org.apereo.portal.portlet.om.IPortletWindowId;
import org.apereo.portal.portlet.registry.IPortletWindowRegistry;
import org.apereo.portal.user.IUserInstance;
import org.apereo.portal.user.IUserInstanceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Generates {@link IPortalUrlBuilder} objects based on various layout and portlet targets.
*
*/
@Service
public class PortalUrlProviderImpl implements IPortalUrlProvider {
private static final String PORTAL_ACTION_URL_BUILDER =
PortalUrlProviderImpl.class.getName() + ".PORTAL_ACTION_URL_BUILDER";
protected final Logger logger = LoggerFactory.getLogger(getClass());
private IUrlSyntaxProvider urlSyntaxProvider;
private IUserInstanceManager userInstanceManager;
private IUrlNodeSyntaxHelperRegistry urlNodeSyntaxHelperRegistry;
private IPortletWindowRegistry portletWindowRegistry;
private IPortletDelegationManager portletDelegationManager;
@Autowired
public void setPortletDelegationManager(IPortletDelegationManager portletDelegationManager) {
this.portletDelegationManager = portletDelegationManager;
}
@Autowired
public void setUrlSyntaxProvider(IUrlSyntaxProvider urlSyntaxProvider) {
this.urlSyntaxProvider = urlSyntaxProvider;
}
@Autowired
public void setUserInstanceManager(IUserInstanceManager userInstanceManager) {
this.userInstanceManager = userInstanceManager;
}
@Autowired
public void setUrlNodeSyntaxHelperRegistry(
IUrlNodeSyntaxHelperRegistry urlNodeSyntaxHelperRegistry) {
this.urlNodeSyntaxHelperRegistry = urlNodeSyntaxHelperRegistry;
}
@Autowired
public void setPortletWindowRegistry(IPortletWindowRegistry portletWindowRegistry) {
this.portletWindowRegistry = portletWindowRegistry;
}
@Override
public IPortalActionUrlBuilder getPortalActionUrlBuilder(HttpServletRequest request) {
return (IPortalActionUrlBuilder) request.getAttribute(PORTAL_ACTION_URL_BUILDER);
}
@Override
public IPortalActionUrlBuilder convertToPortalActionUrlBuilder(
HttpServletRequest request, IPortalUrlBuilder portalUrlBuilder) {
request.setAttribute(PORTAL_ACTION_URL_BUILDER, portalUrlBuilder);
return (IPortalActionUrlBuilder) portalUrlBuilder;
}
/* (non-Javadoc)
* @see org.apereo.portal.url.IPortalUrlProvider#getDefaultUrl(javax.servlet.http.HttpServletRequest)
*/
@Override
public IPortalUrlBuilder getDefaultUrl(HttpServletRequest request) {
final IUrlNodeSyntaxHelper urlNodeSyntaxHelper =
this.urlNodeSyntaxHelperRegistry.getCurrentUrlNodeSyntaxHelper(request);
final String defaultLayoutNodeId = urlNodeSyntaxHelper.getDefaultLayoutNodeId(request);
return this.getPortalUrlBuilderByLayoutNode(request, defaultLayoutNodeId, UrlType.RENDER);
}
/* (non-Javadoc)
* @see org.apereo.portal.url.IPortalUrlProvider#getPortalUrlBuilderByLayoutNode(javax.servlet.http.HttpServletRequest, java.lang.String, org.apereo.portal.url.UrlType)
*/
@Override
public IPortalUrlBuilder getPortalUrlBuilderByLayoutNode(
HttpServletRequest request, String layoutNodeId, UrlType urlType) {
final IPortletWindowId portletWindowId = getPortletWindowId(request, layoutNodeId);
return new PortalUrlBuilder(
this.urlSyntaxProvider, request, layoutNodeId, portletWindowId, urlType);
}
private IPortletWindowId getPortletWindowId(HttpServletRequest request, String layoutNodeId) {
if (layoutNodeId == null) {
return null;
}
final LayoutNodeType layoutNodeType = this.getLayoutNodeType(request, layoutNodeId);
if (layoutNodeType == null) {
throw new IllegalArgumentException("No layout node exists for id: " + layoutNodeId);
}
if (layoutNodeType != LayoutNodeType.PORTLET) {
return null;
}
final IPortletWindow portletWindow =
this.portletWindowRegistry.getOrCreateDefaultPortletWindowByLayoutNodeId(
request, layoutNodeId);
if (portletWindow == null) {
return null;
}
return portletWindow.getPortletWindowId();
}
/* (non-Javadoc)
* @see org.apereo.portal.url.IPortalUrlProvider#getPortalUrlBuilderByPortletWindow(javax.servlet.http.HttpServletRequest, org.apereo.portal.portlet.om.IPortletWindowId, org.apereo.portal.url.UrlType)
*/
@Override
public IPortalUrlBuilder getPortalUrlBuilderByPortletWindow(
HttpServletRequest request, IPortletWindowId portletWindowId, UrlType urlType) {
final IPortletWindow portletWindow =
this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
return getPortalUrlBuilderByPortletWindow(request, portletWindow, urlType);
}
/* (non-Javadoc)
* @see org.apereo.portal.url.IPortalUrlProvider#getPortalUrlBuilderByPortletFName(javax.servlet.http.HttpServletRequest, java.lang.String, org.apereo.portal.url.UrlType)
*/
@Override
public IPortalUrlBuilder getPortalUrlBuilderByPortletFName(
HttpServletRequest request, String portletFName, UrlType urlType) {
final IPortletWindow portletWindow =
this.portletWindowRegistry.getOrCreateDefaultPortletWindowByFname(
request, portletFName);
if (portletWindow == null) {
throw new IllegalArgumentException(
"Could not find PortletWindow for fname="
+ portletFName
+ " to create IPortalUrlBuilder");
}
return this.getPortalUrlBuilderByPortletWindow(request, portletWindow, urlType);
}
protected IPortalUrlBuilder getPortalUrlBuilderByPortletWindow(
HttpServletRequest request, IPortletWindow portletWindow, UrlType urlType) {
final IPortletWindowId portletWindowId = portletWindow.getPortletWindowId();
//See if the targeted portlet is actually a delegate
final IPortletWindowId parentPortletWindowId = portletWindow.getDelegationParentId();
if (parentPortletWindowId != null) {
//Get the portal url builder that targets the parent
final IPortalUrlBuilder portalUrlBuilder =
this.getPortalUrlBuilderByPortletWindow(
request, parentPortletWindowId, urlType);
//See if there is additional delegation request data that needs to be added to the URL
final DelegationRequest delegationRequest =
this.portletDelegationManager.getDelegationRequest(request, portletWindowId);
if (delegationRequest != null) {
final IPortletUrlBuilder parentPortletUrlBuilder =
portalUrlBuilder.getPortletUrlBuilder(parentPortletWindowId);
final Map<String, List<String>> parentParameters =
delegationRequest.getParentParameters();
if (parentParameters != null) {
parentPortletUrlBuilder.setParameters(parentParameters);
}
final PortletMode parentPortletMode = delegationRequest.getParentPortletMode();
if (parentPortletMode != null) {
parentPortletUrlBuilder.setPortletMode(parentPortletMode);
}
final WindowState parentWindowState = delegationRequest.getParentWindowState();
if (parentWindowState != null) {
parentPortletUrlBuilder.setWindowState(parentWindowState);
}
}
return portalUrlBuilder;
}
//create the portlet url builder
final String layoutNodeId = this.verifyPortletWindowId(request, portletWindowId);
return new PortalUrlBuilder(
this.urlSyntaxProvider, request, layoutNodeId, portletWindowId, urlType);
}
/**
* Verify the requested portlet window corresponds to a node in the user's layout and return the
* corresponding layout node id
*/
protected String verifyPortletWindowId(
HttpServletRequest request, IPortletWindowId portletWindowId) {
final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
final IPortletWindow portletWindow =
this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
final IPortletWindowId delegationParentWindowId = portletWindow.getDelegationParentId();
if (delegationParentWindowId != null) {
return verifyPortletWindowId(request, delegationParentWindowId);
}
final IPortletEntity portletEntity = portletWindow.getPortletEntity();
final String channelSubscribeId = portletEntity.getLayoutNodeId();
final IUserLayoutNodeDescription node = userLayoutManager.getNode(channelSubscribeId);
if (node == null) {
throw new IllegalArgumentException(
"No layout node exists for id "
+ channelSubscribeId
+ " of window "
+ portletWindowId);
}
return node.getId();
}
/**
* Verify the requested node exists in the user's layout. Also if the node exists see if it is a
* portlet node and if it is return the {@link IPortletWindowId} of the corresponding portlet.
*/
protected LayoutNodeType getLayoutNodeType(HttpServletRequest request, String folderNodeId) {
final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
final IUserLayoutNodeDescription node = userLayoutManager.getNode(folderNodeId);
if (node == null) {
return null;
}
return node.getType();
}
}