001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.http.widget;
016:
017: import java.util.Iterator;
018: import java.util.Map;
019: import javax.servlet.http.HttpServletResponse;
020: import org.araneaframework.InputData;
021: import org.araneaframework.OutputData;
022: import org.araneaframework.Path;
023: import org.araneaframework.core.Assert;
024: import org.araneaframework.http.util.ServletUtil;
025: import org.araneaframework.uilib.support.FileInfo;
026:
027: /**
028: * Widget that serves content (allows downloading) of specified files.
029: *
030: * @author Taimo Peelo (taimo@araneaframework.org)
031: * @author Alar Kvell (alar@araneaframework.org)
032: */
033: public class FileDownloaderWidget extends DownloaderWidget {
034: protected FileInfo file;
035:
036: protected String fileName;
037:
038: protected boolean contentDispositionInline = true;
039:
040: public FileDownloaderWidget(FileInfo file) {
041: super (file.readFileContent(), file.getContentType());
042: Assert.notNullParam(file, "file");
043: this .fileName = normalizeFileName(file.getOriginalFilename());
044: }
045:
046: public FileDownloaderWidget(byte[] fileContent, String contentType,
047: String fileName) {
048: super (fileContent, contentType);
049: Assert.notEmptyParam(fileName, "fileName");
050: this .fileName = normalizeFileName(fileName);
051: }
052:
053: /** @since 1.1 */
054: public FileDownloaderWidget(byte[] fileContent, Map headers) {
055: super (fileContent, headers);
056: }
057:
058: /**
059: * Returns value of currently used content-disposition response header.
060: * @return false if content-disposition header is set to "attachment"
061: */
062: public boolean isContentDispositionInline() {
063: return contentDispositionInline;
064: }
065:
066: /**
067: * Sets content-disposition header to "inline" (true) or "attachment" (false).
068: */
069: public void setContentDispositionInline(
070: boolean contentDispositionInline) {
071: this .contentDispositionInline = contentDispositionInline;
072: }
073:
074: /** Used internally to extract only file name from supplied filename (no file path). */
075: protected String normalizeFileName(String fileName) {
076: return FileDownloaderWidget.staticNormalizeFileName(fileName);
077: }
078:
079: // as IE (6) provides full names for uploaded files, we use some heuristics
080: // to ensure filename does not include the full path. By no means bulletproof
081: // as it does some harm to filenames containing slashes/backslashes.
082: public static String staticNormalizeFileName(String fileName) {
083: fileName = fileName.trim();
084: // shouldn't happen, but anyway...
085: if (fileName.endsWith("\\"))
086: fileName = fileName.substring(0, fileName.length() - 1);
087: if (fileName.endsWith("/"))
088: fileName = fileName.substring(0, fileName.length() - 1);
089:
090: if (fileName.lastIndexOf('\\') != -1) {
091: fileName = fileName
092: .substring(fileName.lastIndexOf('\\') + 1);
093: }
094: // IE on MAC?
095: if (fileName.lastIndexOf('/') != -1) {
096: fileName = fileName
097: .substring(fileName.lastIndexOf('/') + 1);
098: }
099: return fileName;
100: }
101:
102: protected void action(Path path, InputData input, OutputData output)
103: throws Exception {
104: super .action(path, input, output);
105:
106: HttpServletResponse response = ServletUtil.getResponse(output);
107: if (headers != null) {
108: for (Iterator i = headers.entrySet().iterator(); i
109: .hasNext();) {
110: Map.Entry entry = (Map.Entry) i.next();
111: response.setHeader((String) entry.getKey(),
112: (String) entry.getValue());
113: }
114: } else
115: response.setHeader("Content-Disposition",
116: (contentDispositionInline ? "inline;"
117: : "attachment;")
118: + "filename=" + fileName);
119:
120: close();
121: }
122:
123: protected void close() {
124: }
125:
126: }
|