/**
* 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.portlet.delegation.jsp;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.portlet.PortletMode;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.TagSupport;
import javax.servlet.jsp.tagext.ValidationMessage;
import org.apereo.portal.api.portlet.DelegateState;
import org.apereo.portal.api.portlet.DelegationRequest;
import org.apereo.portal.api.portlet.PortletDelegationDispatcher;
import org.apereo.portal.api.portlet.PortletDelegationLocator;
import org.apereo.portal.portlet.PortletUtils;
import org.apereo.portal.portlet.om.IPortletWindowId;
/**
*/
public class RenderPortletTag extends TagSupport {
private static final long serialVersionUID = 1L;
public static final String DEFAULT_SESSION_KEY_PREFIX = "DELEGATE_WINDOW_ID__";
public static class TEI extends TagExtraInfo {
@Override
public ValidationMessage[] validate(TagData data) {
final List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
Object o = data.getAttribute("fname");
if (o == null) {
messages.add(new ValidationMessage(data.getId(), "fname cannot be null."));
}
if (messages.size() == 0) {
return null;
}
return messages.toArray(new ValidationMessage[messages.size()]);
}
}
private String sessionKeyPrefix = DEFAULT_SESSION_KEY_PREFIX;
private String fname = null;
private String windowState = null;
private String portletMode = null;
private transient WindowState parentUrlState = null;
private transient PortletMode parentUrlMode = null;
private Map<String, List<String>> parentUrlParameters = null;
public String getSessionKeyPrefix() {
return this.sessionKeyPrefix;
}
public void setSessionKeyPrefix(String windowSessionKey) {
this.sessionKeyPrefix = windowSessionKey;
}
public String getFname() {
return this.fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getWindowState() {
return this.windowState;
}
public void setWindowState(String windowState) {
this.windowState = windowState;
}
public String getPortletMode() {
return this.portletMode;
}
public void setPortletMode(String portletMode) {
this.portletMode = portletMode;
}
@Override
public int doStartTag() throws JspException {
return EVAL_BODY_INCLUDE;
}
@Override
public int doEndTag() throws JspException {
//From portlet:defineObjects
final RenderRequest renderRequest =
(RenderRequest) this.pageContext.getAttribute("renderRequest");
final RenderResponse renderResponse =
(RenderResponse) this.pageContext.getAttribute("renderResponse");
final PortletDelegationLocator portletDelegationLocator =
(PortletDelegationLocator)
renderRequest.getAttribute(
PortletDelegationLocator.PORTLET_DELECATION_LOCATOR_ATTR);
final String sessionKey = this.sessionKeyPrefix + this.fname;
final PortletSession portletSession = renderRequest.getPortletSession();
IPortletWindowId portletWindowId =
(IPortletWindowId) portletSession.getAttribute(sessionKey);
final PortletDelegationDispatcher portletDelegationDispatcher;
final DelegateState delegateState;
//No id in session, create a new dispatcher
if (portletWindowId == null) {
portletDelegationDispatcher =
portletDelegationLocator.createRequestDispatcher(renderRequest, this.fname);
portletWindowId = portletDelegationDispatcher.getPortletWindowId();
portletSession.setAttribute(sessionKey, portletWindowId);
final PortletMode portletMode = PortletUtils.getPortletMode(this.portletMode);
final WindowState windowState = PortletUtils.getWindowState(this.windowState);
delegateState = new DelegateState(portletMode, windowState);
}
//id in session, get the old dispatcher
else {
portletDelegationDispatcher =
portletDelegationLocator.getRequestDispatcher(renderRequest, portletWindowId);
delegateState = null;
}
final DelegationRequest delegationRequest = new DelegationRequest();
delegationRequest.setDelegateState(delegateState);
//Setup base for portlet URLs
delegationRequest.setParentPortletMode(this.parentUrlMode);
delegationRequest.setParentWindowState(this.parentUrlState);
delegationRequest.setParentParameters(this.parentUrlParameters);
final JspWriter out = this.pageContext.getOut();
try {
portletDelegationDispatcher.doRender(
renderRequest,
renderResponse,
delegationRequest,
new JspWriterPortletOutputHandler(out, renderResponse));
} catch (IOException e) {
throw new JspException(
"Failed to execute delegate render on portlet '" + this.fname + "'", e);
}
return Tag.EVAL_PAGE;
}
protected void setParentUrlState(WindowState parentUrlState) {
this.parentUrlState = parentUrlState;
}
protected void setParentUrlMode(PortletMode parentUrlMode) {
this.parentUrlMode = parentUrlMode;
}
protected void setParentUrlParameters(Map<String, List<String>> parentUrlParameters) {
this.parentUrlParameters = parentUrlParameters;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(this.parentUrlState.toString());
oos.writeObject(this.parentUrlMode.toString());
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
//Read & validate non-transient fields
ois.defaultReadObject();
//Read & validate transient fields
final String portletModeStr = (String) ois.readObject();
if (portletModeStr == null) {
throw new InvalidObjectException("portletMode can not be null");
}
this.parentUrlMode = PortletUtils.getPortletMode(portletModeStr);
final String windowStateStr = (String) ois.readObject();
if (windowStateStr == null) {
throw new InvalidObjectException("windowState can not be null");
}
this.parentUrlState = PortletUtils.getWindowState(windowStateStr);
}
}