All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.fulcrum.upload.DefaultUploadService Maven / Gradle / Ivy

The newest version!
package org.apache.fulcrum.upload;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.core.FileItem;
import org.apache.commons.fileupload2.core.FileItemInputIterator;
import org.apache.commons.fileupload2.core.FileUploadException;
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload;

import jakarta.servlet.http.HttpServletRequest;

/**
 * 

* This class is an implementation of {@link UploadService}. * *

* Files will be stored in temporary disk storage on in memory, depending on request size, * and will be available from the * org.apache.fulcrum.util.parser.ParameterParser as * org.apache.commons.fileupload.FileItem objects. * *

* This implementation of {@link UploadService} handles multiple files per single html * form, sent using multipart/form-data encoding type, as specified by RFC 1867. Use * org.apache.fulcrum.parser.ParameterParser#getFileItems(String) to acquire * an array of org.apache.commons.fileupload.FileItem objects associated with * given html form. * * @author Rafal Krzewski * @author Daniel Rall * @author Jason van Zyl * @version $Id$ */ public class DefaultUploadService extends AbstractLogEnabled implements UploadService, Initializable, Configurable, Contextualizable { /** A File Item Factory object for the actual uploading */ private DiskFileItemFactory itemFactory; /** * default 0, then a default buffer size will be used, e.g. 8192. */ private int sizeThreshold; /* sizeMax default -1 = no limit.*/ private int sizeMax = -1 ; /* fileSizeMax default -1 = no limit.*/ private long fileSizeMax = -1l; /* fileCountMax default -1 = no limit.*/ private int fileCountMax = -1; private String repositoryPath; private String headerEncoding; /** * The application root */ private String applicationRoot; /** * The maximum allowed upload size */ @Override public long getSizeMax() { return sizeMax; } /** * The threshold beyond which files are written directly to disk. */ @Override public long getSizeThreshold() { return itemFactory.getThreshold(); } /** * The location used to temporarily store files that are larger than the size threshold. */ @Override public String getRepository() { return itemFactory.getRepository().toAbsolutePath().toString(); } /** * @return Returns the headerEncoding. */ @Override public String getHeaderEncoding() { return headerEncoding; } /** * Follows RFC 1867 * * @param req * @param factory * @return a spec compliant servlet * @throws ServiceException */ public JakartaServletFileUpload getDefaultFileUpload(HttpServletRequest req, DiskFileItemFactory factory) { JakartaServletFileUpload fileUpload = new JakartaServletFileUpload<>( factory ); fileUpload.setSizeMax( sizeMax ); fileUpload.setHeaderCharset( null ); fileUpload.setFileSizeMax( fileSizeMax ); fileUpload.setFileCountMax( fileCountMax ); if (getHeaderEncoding() != null) { Charset uploadCharset = getHeaderEncoding().equals( "UTF-8" ) ? StandardCharsets.UTF_8 : getHeaderEncoding().startsWith( "ISO-8859" ) ? StandardCharsets.ISO_8859_1 : StandardCharsets.UTF_8; fileUpload.setHeaderCharset( uploadCharset ); } return fileUpload; } /** *

* Parses a RFC 1867 compliant * multipart/form-data stream. *

* * @param req The servlet request to be parsed. * @throws ServiceException Problems reading/parsing the request or storing the uploaded * file(s). */ @Override public List parseRequest(HttpServletRequest req) throws ServiceException { return parseRequest( req, this.sizeMax, this.itemFactory ); } /** *

* Parses a RFC 1867 compliant * multipart/form-data stream. *

* * @param req The servlet request to be parsed. * @param path The location where the files should be stored. * @throws ServiceException Problems reading/parsing the request or storing the uploaded * file(s). */ @Override public List parseRequest(HttpServletRequest req, String path) throws ServiceException { return parseRequest( req, this.sizeThreshold, this.sizeMax, path ); } /** *

* Parses a RFC 1867 compliant * multipart/form-data stream. *

* * @param req The servlet request to be parsed. * @param sizeThreshold the max size in bytes to be stored in memory * @param sizeMax the maximum allowed upload size in bytes * @param path The location where the files should be stored. * @return list of file items * @throws ServiceException Problems reading/parsing the request or storing the uploaded * file(s). */ @Override public List parseRequest(HttpServletRequest req, int sizeThreshold, int sizeMax, String path) throws ServiceException { Path buildPath = Paths.get( path ); return parseRequest( req, sizeMax, DiskFileItemFactory.builder() .setPath(buildPath ) .setBufferSize( sizeThreshold ) .get() ); } /** *

* Parses a RFC 1867 compliant * multipart/form-data stream. *

* * @param req The servlet request to be parsed. * @param sizeMax the maximum allowed upload size in bytes * @param factory the file item factory to use * @return list of file items * @throws ServiceException Problems reading/parsing the request or storing the uploaded * file(s). */ protected List parseRequest(HttpServletRequest req, int sizeMax, DiskFileItemFactory factory) throws ServiceException { try { JakartaServletFileUpload fileUpload = new JakartaServletFileUpload<>( factory ); fileUpload.setSizeMax( sizeMax ); fileUpload.setHeaderCharset( null ); fileUpload.setFileSizeMax( fileSizeMax ); fileUpload.setFileCountMax( fileCountMax ); if (getHeaderEncoding() != null) { Charset uploadCharset = getHeaderEncoding().equals( "UTF-8" ) ? StandardCharsets.UTF_8 : getHeaderEncoding().startsWith( "ISO-8859" ) ? StandardCharsets.ISO_8859_1 : StandardCharsets.UTF_8; fileUpload.setHeaderCharset( uploadCharset ); // fileUpload.setHeaderEncoding(headerEncoding); } return fileUpload.parseRequest( req ); } catch (FileUploadException e) { throw new ServiceException( UploadService.ROLE, e.getMessage(), e ); } } /** * Processes an RFC 1867 compliant * multipart/form-data stream. * * @param req The servlet request to be parsed. * * @return An iterator to instances of FileItemStream parsed from the * request, in the order that they were transmitted. * * @throws ServiceException if there are problems reading/parsing the request or storing * files. This may also be a network error while communicating * with the client or a problem while storing the uploaded * content. */ @Override public FileItemInputIterator getItemIterator(HttpServletRequest req) throws ServiceException { JakartaServletFileUpload upload = new JakartaServletFileUpload(); try { return upload.getItemIterator( req ); } catch (FileUploadException e) { throw new ServiceException( UploadService.ROLE, e.getMessage(), e ); } catch (IOException e) { throw new ServiceException( UploadService.ROLE, e.getMessage(), e ); } } /** * Utility method that determines whether the request contains multipart content. * * @param req The servlet request to be evaluated. Must be non-null. * * @return true if the request is multipart; false otherwise. */ @Override public boolean isMultipart(HttpServletRequest req) { return JakartaServletFileUpload.isMultipartContent( req ); } /** * @see org.apache.fulcrum.ServiceBroker#getRealPath(String) */ private String getRealPath(String path) { String absolutePath = null; if (applicationRoot == null) { absolutePath = new File( path ).getAbsolutePath(); } else { absolutePath = new File( applicationRoot, path ).getAbsolutePath(); } return absolutePath; } // ---------------- Avalon Lifecycle Methods --------------------- /** * Avalon component lifecycle method */ @Override public void configure(Configuration conf) { repositoryPath = conf.getAttribute( UploadService.REPOSITORY_KEY, UploadService.REPOSITORY_DEFAULT ); headerEncoding = conf.getAttribute( UploadService.HEADER_ENCODING_KEY, UploadService.HEADER_ENCODING_DEFAULT ); sizeMax = conf.getAttributeAsInteger( UploadService.SIZE_MAX_KEY, UploadService.SIZE_MAX_DEFAULT ); sizeThreshold = conf.getAttributeAsInteger( UploadService.SIZE_THRESHOLD_KEY, UploadService.SIZE_THRESHOLD_DEFAULT ); } /** * Avalon component lifecycle method * * Initializes the service. * * This method processes the repository path, to make it relative to the web application * root, if necessary */ @Override public void initialize() throws Exception { // test for the existence of the path within the webapp directory. // if it does not exist, assume the path was to be used as is. String testPath = getRealPath( repositoryPath ); File testDir = new File( testPath ); if (testDir.exists()) { repositoryPath = testPath; } getLogger().debug( "Upload Service: REPOSITORY_KEY => " + repositoryPath ); itemFactory = DiskFileItemFactory.builder() .setPath(Paths.get( repositoryPath ) ) .setBufferSize( sizeThreshold ) .get(); } /** * Avalon component lifecycle method */ @Override public void contextualize(Context context) throws ContextException { this.applicationRoot = context.get( "urn:avalon:home" ).toString(); } /** * The maximum allowed size of a sinlge file upload * @return the maximum size */ @Override public long getFileSizeMax() { return fileSizeMax; } public void setFileSizeMax(long fileSizeMax) { this.fileSizeMax = fileSizeMax; } /** * The maximum number of files allowed per request. * @return maximum number of files allowed per request */ public long getFileCountMax() { return fileCountMax; } public void setFileCountMax(int fileCountMax) { this.fileCountMax = fileCountMax; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy