1/*2 * Copyright 2000-2001,2004 The Apache Software Foundation.3 * 4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 * 8 * http://www.apache.org/licenses/LICENSE-2.09 * 10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16packageorg.apache.jetspeed.portal.portlets;
1718import org.apache.ecs.ConcreteElement;
19import org.apache.ecs.StringElement;
20import org.apache.jetspeed.portal.portlets.AbstractPortlet;
21import org.apache.turbine.util.RunData;
2223import java.io.BufferedInputStream;
24import java.io.ByteArrayOutputStream;
25import java.io.InputStream;
26import java.net.URL;
27import java.net.URLConnection;
282930/*** 31 * This portlet class is intended to be used for internal URLs that will 32 * not work properly if they are part of the same request as the Jetspeed/Turbine33 * controller servlet--Struts-mapped URLs are an example of these.34 * <br>35 * ServletProxyPortlet uses an application context-relative URL as an input parameter. It uses data obtained from36 * <code>org.apache.turbine.util.RunData</code> to construct an absolute URL and append the session id to it. Using this37 * URL, it constructs a java.net.URL object, retrieves the content from it, and converts the content to a String. Finally,38 * it returns an ECS StringElement created with this String for Jetspeed to render as a portlet. Content is returned as-is;39 * no filtering is performed on the html before returning it.40 * <br/><br/>41 * This portlet accepts 3 parameters:<br/>42 *43 * URL (required) -- the web application-context relative URL (a query string may be used to pass parameters)<br/>44 * session_token (optional) -- token key used by the web server to pass the session id on the query string<br/>45 * protocol (optional) -- protocol to use to make the URL request46 *47 * @author <a href="mailto:joe.barefoot@motiva.com">Joe Barefoot</a>48 */495051publicclassServletProxyPortletextendsAbstractPortlet52 {
53privatefinalstaticint BUFFER_SIZE = 2048;
5455/*** The name of the parameter to hold our application context-relative URL */56publicstaticfinal String URL_PARAMETER_NAME = "URL";
57/*** The name of the parameter to hold the protocol to use (optional, default is http) **/58publicstaticfinal String PROTOCOL_PARAMETER_NAME = "protocol";
59/*** The name of the parameter to hold the token by which the session ID is passed on the query string (optional, default is jsessionid)60 * This is included to accomodate all web servers, as the token is usually different from one server to another.61 */62publicstaticfinal String SESSION_TOKEN_PARAMETER_NAME = "session_token";
6364/*** The default protocol used to construct the URL -- http */65publicstaticfinal String DEFAULT_PROTOCOL = "http";
66/*** The default token to use to pass the session ID on the query String -- jsessionid */67publicstaticfinal String DEFAULT_SESSION_TOKEN = "jsessionid";
6869/*** Gets content by proxy (java.net.URL) from an internal URL and returns it70 *71 * @param rundata The RunData object for the current request72 * @return an ECS StringElement73 */74public ConcreteElement getContent(RunData rundata)
75 {
76 String servletURL = processURL(rundata);
77if(servletURL == null)
78 {
79returnnew StringElement("ServletInvokerPortlet: Must specify a URL using the URL parameter");
80 }
81 String content;
8283// This is probably not robust for large content returns, but should work okay within an application context with small amounts of content.84try85 {
8687 URL url = new URL(servletURL);
88 URLConnection connection = url.openConnection();
89 InputStream stream = connection.getInputStream();
90 BufferedInputStream in = new BufferedInputStream(stream);
91int length = 0;
92 byte[] buf = new byte[BUFFER_SIZE];
93 ByteArrayOutputStream out = new ByteArrayOutputStream();
94while ((in != null) && ((length = in.read(buf)) != -1))
95 {
96// the data has already been read into buf97 out.write(buf, 0, length);
98 }
99 content = out.toString();
100returnnew StringElement(content);
101 }
102catch (Exception e)
103 {
104 String message = "ServletInvokerPortlet: Error invoking " + servletURL + ": " + e.getMessage();
105returnnew StringElement(message);
106 }
107108 }
109110/*** Constructs a full URL to retrieve content from. Override to append custom (default) query parameters, etc.111 *112 * @param rundata The RunData object for the current request113 * @return An absolute URL with the session ID appended114 */115protected String processURL(RunData rundata)
116 {
117 String servletURL = getPortletConfig().getInitParameter(URL_PARAMETER_NAME);
118if( servletURL == null) // short-circuit119 {
120returnnull;
121 }
122 String protocol = getPortletConfig().getInitParameter(PROTOCOL_PARAMETER_NAME);
123if(protocol == null)
124 {
125 protocol = DEFAULT_PROTOCOL;
126 }
127 String token = getPortletConfig().getInitParameter(SESSION_TOKEN_PARAMETER_NAME);
128if(token == null)
129 {
130 token = DEFAULT_SESSION_TOKEN;
131 }
132133134 String queryString = new String();
135int queryIndex = servletURL.indexOf("?");
136if(queryIndex > 0)
137 {
138 queryString = servletURL.substring(queryIndex);
139 servletURL = servletURL.substring(0, queryIndex);
140 }
141 servletURL = protocol + "://" + rundata.getServerName() + ":" + rundata.getServerPort() + rundata.getContextPath() + servletURL + ";" + token + "=" + rundata.getSession().getId() + queryString;
142return servletURL;
143 }
144145 }