001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.portals.gems.file;
018:
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.util.Iterator;
025: import java.util.LinkedList;
026: import java.util.List;
027:
028: import javax.portlet.PortletConfig;
029: import javax.portlet.PortletException;
030: import javax.portlet.PortletPreferences;
031: import javax.portlet.PortletRequest;
032: import javax.portlet.RenderRequest;
033: import javax.portlet.RenderResponse;
034: import javax.servlet.http.HttpServletRequest;
035:
036: import org.apache.jetspeed.PortalReservedParameters;
037: import org.apache.jetspeed.om.folder.Folder;
038: import org.apache.jetspeed.request.RequestContext;
039: import org.apache.portals.bridges.common.GenericServletPortlet;
040:
041: /**
042: * FilePortlet
043: *
044: * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
045: * @version $Id: FilePortlet.java 601037 2007-12-04 18:50:55Z taylor $
046: */
047: public class FilePortlet extends GenericServletPortlet {
048: public static final String PARAM_USE_LANGUAGE = "use-language";
049: /**
050: * Name of portlet preference for source file url
051: */
052: public static final String PARAM_SOURCE_FILE = "file";
053:
054: /**
055: * Name of portlet preference for source file url
056: */
057: public static final String PARAM_SOURCE_BASE_PATH = "basepath";
058:
059: /**
060: * Name of portlet preference for source file url
061: */
062: public static final String PARAM_SOURCE_FILE_PATH = "filepath";
063:
064: /**
065: * Is the file stored in the webapp or outside of the webapp? valid values
066: * "webapp" and "filesystem", defaults to webapp
067: */
068: public static final String PARAM_LOCATION = "location";
069:
070: private boolean webappLocation = true;
071:
072: /**
073: * Default URL for the source file
074: */
075: private String defaultSourceFile = null;
076:
077: /**
078: * Default base URL for the source file
079: */
080: private String defaultSourceBasePath = null;
081:
082: private boolean useLanguage = false;
083:
084: public void init(PortletConfig config) throws PortletException {
085: super .init(config);
086: String use = config.getInitParameter(PARAM_USE_LANGUAGE);
087: if (use != null && use.equalsIgnoreCase("true"))
088: this .useLanguage = true;
089: this .defaultSourceFile = config
090: .getInitParameter(PARAM_SOURCE_FILE);
091: this .defaultSourceBasePath = config
092: .getInitParameter(PARAM_SOURCE_BASE_PATH);
093: String location = config.getInitParameter(PARAM_LOCATION);
094: if (location != null && location.equals("filesystem"))
095: webappLocation = false;
096: else
097: webappLocation = true;
098: }
099:
100: private RequestContext getRequestContext(PortletRequest request) {
101: return (RequestContext) request
102: .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
103:
104: }
105:
106: private HttpServletRequest getHttpServletRequest(
107: PortletRequest pRequest) {
108: return getRequestContext(pRequest).getRequest();
109:
110: }
111:
112: public void doView(RenderRequest request, RenderResponse response)
113: throws PortletException, IOException {
114: // NOTE: this is Jetspeed specific
115: HttpServletRequest req = getHttpServletRequest(request);
116: String fileName = (String) req.getSession()
117: .getAttribute("file");
118: if (fileName != null && !fileName.equals("")) {
119: InputStream is = null;
120: try {
121: fileName = getFilePath(fileName);
122: is = new FileInputStream(fileName);
123: if (is == null) {
124: byte[] bytes = ("File " + fileName + " not found.")
125: .getBytes();
126: response.getPortletOutputStream().write(bytes);
127: return;
128: }
129: setContentType(fileName, response);
130: drain(is, response.getPortletOutputStream());
131: response.getPortletOutputStream().flush();
132: is.close();
133: req.getSession().removeAttribute("file");
134: } catch (Exception e) {
135: if (is != null)
136: is.close();
137: byte[] bytes = ("File " + fileName + " not found.")
138: .getBytes();
139: req.getSession().removeAttribute("file");
140: response.setContentType("text/html");
141: response.getPortletOutputStream().write(bytes);
142: return;
143: }
144: } else {
145: String path = (String) request
146: .getAttribute(PortalReservedParameters.PATH_ATTRIBUTE);
147: if (null == path) {
148: PortletPreferences prefs = request.getPreferences();
149: path = prefs.getValue(PARAM_SOURCE_FILE,
150: this .defaultSourceFile);
151: } else {
152: if (path.endsWith(".css"))
153: path = null;
154: }
155: if (null == path && this .defaultSourceBasePath != null) {
156: String filepath = request
157: .getParameter(PARAM_SOURCE_FILE_PATH);
158: if (filepath == null) {
159: filepath = (String) request
160: .getAttribute(PARAM_SOURCE_FILE_PATH);
161: }
162:
163: if (filepath != null) {
164: path = ((this .defaultSourceBasePath.length() > 0) ? (this .defaultSourceBasePath + "/")
165: : "")
166: + filepath;
167: }
168: }
169:
170: if (null == path) {
171: response.setContentType("text/html");
172: response.getWriter().println(
173: "Could not find source document.");
174: } else {
175: setContentType(path, response);
176: List paths = fallback(path, request.getLocale()
177: .getLanguage());
178: renderFile(response, paths);
179: }
180: }
181: }
182:
183: protected List fallback(String path, String language) {
184: List paths = new LinkedList();
185: if (this .useLanguage) {
186: if (webappLocation) {
187: path = concatenatePaths("/WEB-INF/", path);
188: }
189: String fallbackPath = path;
190: File temp = new File(path);
191: String parentPath = temp.getParent();
192: String name = temp.getName();
193: path = concatenatePaths(parentPath, language);
194: path = concatenatePaths(path, name);
195: paths.add(path);
196: paths.add(fallbackPath);
197: } else {
198: if (webappLocation) {
199: path = concatenatePaths("/WEB-INF/", path);
200: }
201: paths.add(path);
202: }
203: return paths;
204: }
205:
206: protected void setContentType(String path, RenderResponse response) {
207: // Note these content types need to be added to the portlet.xml
208: if (path.endsWith(".html")) {
209: response.setContentType("text/html");
210: } else if (path.endsWith(".pdf")) {
211: response.setContentType("application/pdf");
212: } else if (path.endsWith(".zip")) {
213: response.setContentType("application/zip");
214: } else if (path.endsWith(".csv")) {
215: response.setContentType("text/csv");
216: } else if (path.endsWith(".xml") || path.endsWith(".xsl")) {
217: response.setContentType("text/xml");
218: } else if (path.endsWith(".psml") || path.endsWith(".link")) {
219: response.setContentType("text/xml");
220: } else {
221: response.setContentType("text/html");
222: }
223: }
224:
225: protected void renderFile(RenderResponse response, List paths)
226: throws PortletException, IOException {
227: boolean drained = false;
228: Iterator it = paths.iterator();
229: while (it.hasNext()) {
230: String fileName = (String) it.next();
231: InputStream is = null;
232: try {
233: if (this .webappLocation) {
234: is = this .getPortletContext().getResourceAsStream(
235: fileName);
236: } else {
237: is = new FileInputStream(fileName);
238: }
239: if (is != null) {
240: drain(is, response.getPortletOutputStream());
241: response.getPortletOutputStream().flush();
242: is.close();
243: drained = true;
244: break;
245: }
246: } catch (Exception e) {
247: // do nothing, find next file
248: }
249: }
250: if (!drained) {
251: String fileName = (String) paths.get(0);
252: byte[] bytes = ("File " + fileName + " not found.")
253: .getBytes();
254: response.getPortletOutputStream().write(bytes);
255: return;
256: }
257: }
258:
259: static final int BLOCK_SIZE = 4096;
260:
261: public static void drain(InputStream r, OutputStream w)
262: throws IOException {
263: byte[] bytes = new byte[BLOCK_SIZE];
264: try {
265: int length = r.read(bytes);
266: while (length != -1) {
267: if (length != 0) {
268: w.write(bytes, 0, length);
269: }
270: length = r.read(bytes);
271: }
272: } finally {
273: bytes = null;
274: }
275: }
276:
277: private String getFilePath(String path) {
278: String pageRoot = System.getProperty("java.io.tmpdir");
279: String sep = System.getProperty("file.separator");
280: if (sep == null || sep.equals(""))
281: sep = "/";
282:
283: String ar[] = path.split("_");
284: if (ar.length == 1)
285: return pageRoot + sep + path;
286: return pageRoot + sep + ar[0] + sep + ar[1];
287: }
288:
289: protected static String concatenatePaths(String base, String path) {
290: String result = "";
291: if (base == null) {
292: if (path == null) {
293: return result;
294: }
295: return path;
296: } else {
297: if (path == null) {
298: return base;
299: }
300: }
301: if (base.endsWith(Folder.PATH_SEPARATOR)) {
302: if (path.startsWith(Folder.PATH_SEPARATOR)) {
303: result = base.concat(path.substring(1));
304: return result;
305: }
306:
307: } else {
308: if (!path.startsWith(Folder.PATH_SEPARATOR)) {
309: result = base.concat(Folder.PATH_SEPARATOR)
310: .concat(path);
311: return result;
312: }
313: }
314: return base.concat(path);
315: }
316:
317: }
|