001: package org.apache.turbine.services.upload;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.File;
023: import java.io.UnsupportedEncodingException;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import javax.servlet.http.HttpServletRequest;
028:
029: import org.apache.commons.configuration.Configuration;
030: import org.apache.commons.fileupload.FileItem;
031: import org.apache.commons.fileupload.FileUploadException;
032: import org.apache.commons.fileupload.disk.DiskFileItemFactory;
033: import org.apache.commons.fileupload.servlet.ServletFileUpload;
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036: import org.apache.turbine.Turbine;
037: import org.apache.turbine.services.InitializationException;
038: import org.apache.turbine.services.TurbineBaseService;
039: import org.apache.turbine.util.TurbineException;
040: import org.apache.turbine.util.parser.ParameterParser;
041:
042: /**
043: * <p> This class is an implementation of {@link UploadService}.
044: *
045: * <p> Files will be stored in temporary disk storage on in memory,
046: * depending on request size, and will be available from the {@link
047: * org.apache.turbine.util.parser.ParameterParser} as {@link
048: * org.apache.commons.fileupload.FileItem}s.
049: *
050: * <p>This implementation of {@link UploadService} handles multiple
051: * files per single html widget, sent using multipar/mixed encoding
052: * type, as specified by RFC 1867. Use {@link
053: * org.apache.turbine.util.parser.ParameterParser#getFileItems(String)} to
054: * acquire an array of {@link
055: * org.apache.commons.fileupload.FileItem}s associated with given
056: * html widget.
057: *
058: * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
059: * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
060: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
061: * @version $Id: TurbineUploadService.java 534527 2007-05-02 16:10:59Z tv $
062: */
063: public class TurbineUploadService extends TurbineBaseService implements
064: UploadService {
065: /** Logging */
066: private static Log log = LogFactory
067: .getLog(TurbineUploadService.class);
068:
069: /** A File Upload object for the actual uploading */
070: protected ServletFileUpload fileUpload = null;
071:
072: /** A File Item Factory object for the actual uploading */
073: protected DiskFileItemFactory itemFactory = null;
074:
075: /** Auto Upload yes? */
076: private boolean automatic;
077:
078: /**
079: * Initializes the service.
080: *
081: * This method processes the repository path, to make it relative to the
082: * web application root, if neccessary
083: */
084: public void init() throws InitializationException {
085: Configuration conf = getConfiguration();
086:
087: String repoPath = conf.getString(UploadService.REPOSITORY_KEY,
088: UploadService.REPOSITORY_DEFAULT);
089:
090: if (!repoPath.startsWith("/")) {
091: // If our temporary directory is in the application
092: // space, try to create it. If this fails, throw
093: // an exception.
094: String testPath = Turbine.getRealPath(repoPath);
095: File testDir = new File(testPath);
096: if (!testDir.exists()) {
097: if (!testDir.mkdirs()) {
098: throw new InitializationException(
099: "Could not create target directory!");
100: }
101: }
102: repoPath = testPath;
103: conf.setProperty(UploadService.REPOSITORY_KEY, repoPath);
104: }
105:
106: log.debug("Upload Path is now " + repoPath);
107:
108: long sizeMax = conf.getLong(UploadService.SIZE_MAX_KEY,
109: UploadService.SIZE_MAX_DEFAULT);
110:
111: log.debug("Max Size " + sizeMax);
112:
113: int sizeThreshold = conf.getInt(
114: UploadService.SIZE_THRESHOLD_KEY,
115: UploadService.SIZE_THRESHOLD_DEFAULT);
116:
117: log.debug("Threshold Size " + sizeThreshold);
118:
119: automatic = conf.getBoolean(UploadService.AUTOMATIC_KEY,
120: UploadService.AUTOMATIC_DEFAULT);
121:
122: log.debug("Auto Upload " + automatic);
123:
124: itemFactory = new DiskFileItemFactory();
125: itemFactory.setSizeThreshold(sizeThreshold);
126: itemFactory.setRepository(new File(repoPath));
127: fileUpload = new ServletFileUpload(itemFactory);
128: fileUpload.setSizeMax(sizeMax);
129:
130: setInit(true);
131: }
132:
133: /**
134: * <p> Retrieves the value of <code>size.max</code> property of the
135: * {@link org.apache.turbine.services.upload.UploadService}.
136: *
137: * @return The maximum upload size.
138: */
139: public long getSizeMax() {
140: return fileUpload.getSizeMax();
141: }
142:
143: /**
144: * <p> Retrieves the value of <code>size.threshold</code> property of
145: * {@link org.apache.turbine.services.upload.UploadService}.
146: *
147: * @return The threshold beyond which files are written directly to disk.
148: */
149: public int getSizeThreshold() {
150: return itemFactory.getSizeThreshold();
151: }
152:
153: /**
154: * Retrieves the value of the 'automatic' property of {@link
155: * UploadService}. This reports whether the Parameter parser
156: * should allow "automatic" uploads if it is submitted to
157: * Turbine.
158: *
159: * @return The value of 'automatic' property of {@link
160: * UploadService}.
161: */
162: public boolean getAutomatic() {
163: return automatic;
164: }
165:
166: /**
167: * <p> Retrieves the value of the <code>repository</code> property of
168: * {@link org.apache.turbine.services.upload.UploadService}.
169: *
170: * @return The repository.
171: */
172: public String getRepository() {
173: return itemFactory.getRepository().getAbsolutePath();
174: }
175:
176: /**
177: * <p> Processes an <a href="http://rf.cx/rfc1867.html">RFC
178: * 1867</a> compliant <code>multipart/form-data</code> stream.
179: *
180: * @param req The servlet request to be parsed.
181: * @param params The ParameterParser instance to insert form
182: * fields into.
183: * @param path The location where the files should be stored.
184: * @exception TurbineException Problems reading/parsing the
185: * request or storing the uploaded file(s).
186: */
187: public void parseRequest(HttpServletRequest req,
188: ParameterParser params, String path)
189: throws TurbineException {
190: String contentType = req.getHeader(CONTENT_TYPE);
191: if (!contentType.startsWith(MULTIPART_FORM_DATA)) {
192: throw new TurbineException("the request doesn't contain a "
193: + MULTIPART_FORM_DATA + " stream");
194: }
195: int requestSize = req.getContentLength();
196: if (requestSize == -1) {
197: throw new TurbineException(
198: "the request was rejected because "
199: + "it's size is unknown");
200: }
201: if (requestSize > getSizeMax()) {
202: throw new TurbineException(
203: "the request was rejected because "
204: + "it's size exceeds allowed range");
205: }
206:
207: try {
208: List fileList = fileUpload.parseRequest(req);
209:
210: if (fileList != null) {
211: for (Iterator it = fileList.iterator(); it.hasNext();) {
212: FileItem fi = (FileItem) it.next();
213: if (fi.isFormField()) {
214: log.debug("Found an simple form field: "
215: + fi.getFieldName() + ", adding value "
216: + fi.getString());
217:
218: String value = null;
219: try {
220: value = fi.getString(params
221: .getCharacterEncoding());
222: } catch (UnsupportedEncodingException e) {
223: log
224: .error(params
225: .getCharacterEncoding()
226: + " encoding is not supported."
227: + "Used the default when reading form data.");
228: value = fi.getString();
229: }
230: params.add(fi.getFieldName(), value);
231: } else {
232: log.debug("Found an uploaded file: "
233: + fi.getFieldName());
234: log.debug("It has " + fi.getSize()
235: + " Bytes and is "
236: + (fi.isInMemory() ? "" : "not ")
237: + "in Memory");
238: log.debug("Adding FileItem as "
239: + fi.getFieldName() + " to the params");
240: params.add(fi.getFieldName(), fi);
241: }
242: }
243: }
244: } catch (FileUploadException e) {
245: throw new TurbineException(e);
246: }
247: }
248: }
|