001: package org.apache.turbine.services.upload;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License")
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.File;
020: import java.io.UnsupportedEncodingException;
021:
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import javax.servlet.http.HttpServletRequest;
026:
027: import org.apache.commons.configuration.Configuration;
028:
029: import org.apache.commons.fileupload.DiskFileUpload;
030: import org.apache.commons.fileupload.FileItem;
031: import org.apache.commons.fileupload.FileUploadException;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
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 279820 2005-09-09 17:05:54Z henning $
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 DiskFileUpload fileUpload = null;
071:
072: /** Auto Upload yes? */
073: private boolean automatic;
074:
075: /**
076: * Initializes the service.
077: *
078: * This method processes the repository path, to make it relative to the
079: * web application root, if neccessary
080: */
081: public void init() throws InitializationException {
082: Configuration conf = getConfiguration();
083:
084: String repoPath = conf.getString(UploadService.REPOSITORY_KEY,
085: UploadService.REPOSITORY_DEFAULT);
086:
087: if (!repoPath.startsWith("/")) {
088: // If our temporary directory is in the application
089: // space, try to create it. If this fails, throw
090: // an exception.
091: String testPath = Turbine.getRealPath(repoPath);
092: File testDir = new File(testPath);
093: if (!testDir.exists()) {
094: if (!testDir.mkdirs()) {
095: throw new InitializationException(
096: "Could not create target directory!");
097: }
098: }
099: repoPath = testPath;
100: conf.setProperty(UploadService.REPOSITORY_KEY, repoPath);
101: }
102:
103: log.debug("Upload Path is now " + repoPath);
104:
105: long sizeMax = conf.getLong(UploadService.SIZE_MAX_KEY,
106: UploadService.SIZE_MAX_DEFAULT);
107:
108: log.debug("Max Size " + sizeMax);
109:
110: int sizeThreshold = conf.getInt(
111: UploadService.SIZE_THRESHOLD_KEY,
112: UploadService.SIZE_THRESHOLD_DEFAULT);
113:
114: log.debug("Threshold Size " + sizeThreshold);
115:
116: automatic = conf.getBoolean(UploadService.AUTOMATIC_KEY,
117: UploadService.AUTOMATIC_DEFAULT);
118:
119: log.debug("Auto Upload " + automatic);
120:
121: fileUpload = new DiskFileUpload();
122: fileUpload.setSizeMax(sizeMax);
123: fileUpload.setSizeThreshold(sizeThreshold);
124: fileUpload.setRepositoryPath(repoPath);
125:
126: setInit(true);
127: }
128:
129: /**
130: * <p> Retrieves the value of <code>size.max</code> property of the
131: * {@link org.apache.turbine.services.upload.UploadService}.
132: *
133: * @return The maximum upload size.
134: */
135: public long getSizeMax() {
136: return fileUpload.getSizeMax();
137: }
138:
139: /**
140: * <p> Retrieves the value of <code>size.threshold</code> property of
141: * {@link org.apache.turbine.services.upload.UploadService}.
142: *
143: * @return The threshold beyond which files are written directly to disk.
144: */
145: public int getSizeThreshold() {
146: return fileUpload.getSizeThreshold();
147: }
148:
149: /**
150: * Retrieves the value of the 'automatic' property of {@link
151: * UploadService}. This reports whether the Parameter parser
152: * should allow "automatic" uploads if it is submitted to
153: * Turbine.
154: *
155: * @return The value of 'automatic' property of {@link
156: * UploadService}.
157: */
158: public boolean getAutomatic() {
159: return automatic;
160: }
161:
162: /**
163: * <p> Retrieves the value of the <code>repository</code> property of
164: * {@link org.apache.turbine.services.upload.UploadService}.
165: *
166: * @return The repository.
167: */
168: public String getRepository() {
169: return fileUpload.getRepositoryPath();
170: }
171:
172: /**
173: * <p> Processes an <a href="http://rf.cx/rfc1867.html">RFC
174: * 1867</a> compliant <code>multipart/form-data</code> stream.
175: *
176: * @param req The servlet request to be parsed.
177: * @param params The ParameterParser instance to insert form
178: * fields into.
179: * @param path The location where the files should be stored.
180: * @exception TurbineException Problems reading/parsing the
181: * request or storing the uploaded file(s).
182: */
183: public void parseRequest(HttpServletRequest req,
184: ParameterParser params, String path)
185: throws TurbineException {
186: String contentType = req.getHeader(CONTENT_TYPE);
187: if (!contentType.startsWith(MULTIPART_FORM_DATA)) {
188: throw new TurbineException("the request doesn't contain a "
189: + MULTIPART_FORM_DATA + " stream");
190: }
191: int requestSize = req.getContentLength();
192: if (requestSize == -1) {
193: throw new TurbineException(
194: "the request was rejected because "
195: + "it's size is unknown");
196: }
197: if (requestSize > getSizeMax()) {
198: throw new TurbineException(
199: "the request was rejected because "
200: + "it's size exceeds allowed range");
201: }
202:
203: try {
204: List fileList = fileUpload.parseRequest(req,
205: getSizeThreshold(), getSizeMax(), path);
206:
207: if (fileList != null) {
208: for (Iterator it = fileList.iterator(); it.hasNext();) {
209: FileItem fi = (FileItem) it.next();
210: if (fi.isFormField()) {
211: log.debug("Found an simple form field: "
212: + fi.getFieldName() + ", adding value "
213: + fi.getString());
214:
215: String value = null;
216: try {
217: value = fi.getString(params
218: .getCharacterEncoding());
219: } catch (UnsupportedEncodingException e) {
220: log
221: .error(params
222: .getCharacterEncoding()
223: + " encoding is not supported."
224: + "Used the default when reading form data.");
225: value = fi.getString();
226: }
227: params.add(fi.getFieldName(), value);
228: } else {
229: log.debug("Found an uploaded file: "
230: + fi.getFieldName());
231: log.debug("It has " + fi.getSize()
232: + " Bytes and is "
233: + (fi.isInMemory() ? "" : "not ")
234: + "in Memory");
235: log.debug("Adding FileItem as "
236: + fi.getFieldName() + " to the params");
237: params.add(fi.getFieldName(), fi);
238: }
239: }
240: }
241: } catch (FileUploadException e) {
242: throw new TurbineException(e);
243: }
244: }
245: }
|