Package org.exoplatform.upload

Source Code of org.exoplatform.upload.UploadService$UploadLimit

/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.exoplatform.upload;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.PortalContainerInfo;
import org.gatein.common.logging.Logger;
import org.gatein.common.logging.LoggerFactory;
import org.gatein.common.text.EntityEncoder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class UploadService
{
   /** . */
   private static final Logger log = LoggerFactory.getLogger(UploadService.class);
  
   private List<MimeTypeUploadPlugin> plugins ;

   private Map<String, UploadResource> uploadResources = new LinkedHashMap<String, UploadResource>();

   private String uploadLocation_;

   private UploadLimit defaultUploadLimitMB_;

   private Map<String, UploadLimit> uploadLimits = new LinkedHashMap<String, UploadLimit>();
  
   public static String UPLOAD_RESOURCES_STACK = "uploadResourcesStack";
  
   public static enum UploadUnit
   {
      KB, MB, GB
   };
  
   public UploadService(PortalContainerInfo pinfo, InitParams params) throws Exception
   {
      String tmpDir = System.getProperty("java.io.tmpdir");
      if (params == null || params.getValueParam("upload.limit.size") == null)
         defaultUploadLimitMB_ = new UploadLimit(0, UploadUnit.MB); // 0 means unlimited
      else
         defaultUploadLimitMB_ = new UploadLimit(Integer.parseInt(params.getValueParam("upload.limit.size").getValue()), UploadUnit.MB);
      uploadLocation_ = tmpDir + "/" + pinfo.getContainerName() + "/eXoUpload";
      File uploadDir = new File(uploadLocation_);
      if (!uploadDir.exists())
         uploadDir.mkdirs();
   }
  
   public void register(MimeTypeUploadPlugin plugin) {
      if(plugins == null) plugins = new ArrayList<MimeTypeUploadPlugin>() ;
      plugins.add(plugin) ;
   }
  
   /**
    * Create UploadResource for HttpServletRequest
    *
    * @param request
    *           the webapp's {@link javax.servlet.http.HttpServletRequest}
    * @throws FileUploadException
    */
   public void createUploadResource(HttpServletRequest request) throws FileUploadException
   {
      String uploadId = request.getParameter("uploadId");
      createUploadResource(uploadId, request);
   }

   public void createUploadResource(String uploadId, HttpServletRequest request) throws FileUploadException
   {
      UploadResource upResource = new UploadResource(uploadId);
      upResource.setFileName("");// Avoid NPE in UploadHandler
      uploadResources.put(upResource.getUploadId(), upResource);

      putToStackInSession(request.getSession(true), uploadId);

      double contentLength = request.getContentLength();
      upResource.setEstimatedSize(contentLength);
      if (isLimited(upResource, contentLength))
      {
         upResource.setStatus(UploadResource.FAILED_STATUS);
         return;
      }

      ServletFileUpload servletFileUpload = makeServletFileUpload(upResource);
      // parse request
      List<FileItem> itemList = servletFileUpload.parseRequest(request);
      if (itemList == null || itemList.size() != 1 || itemList.get(0).isFormField())
      {
         log.debug("Please upload 1 file per request");
         removeUploadResource(uploadId);
         return;
      }

      DiskFileItem fileItem = (DiskFileItem)itemList.get(0);
      String fileName = fileItem.getName();
      if (fileName == null)
         fileName = uploadId;
      fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
      String storeLocation = uploadLocation_ + "/" + uploadId + "." + fileName;

     
      // commons-fileupload will store the temp file with name *.tmp
      // we need to rename it to our desired name
      fileItem.getStoreLocation().renameTo(new File(storeLocation));
      File fileStore = new File(storeLocation);
      if (!fileStore.exists())
         try
         {
            fileStore.createNewFile();
         }
         catch (IOException e)
         {
            throw new RuntimeException(e);
         }
     

      upResource.setFileName(fileName);
      upResource.setMimeType(fileItem.getContentType());
      if(plugins != null)
         for(MimeTypeUploadPlugin plugin : plugins)
         {
            String mimeType = plugin.getMimeType(fileName) ;
            if(mimeType != null) upResource.setMimeType(mimeType) ;
         }
      upResource.setStoreLocation(storeLocation);
      upResource.setStatus(UploadResource.UPLOADED_STATUS);
   }

   /**
    * @deprecated use {@link #createUploadResource(String, javax.servlet.http.HttpServletRequest)}  instead
    *
    */
   public void createUploadResource(String uploadId, String encoding, String contentType, double contentLength,
                                    InputStream inputStream) throws Exception
   {
      UploadResource upResource = new UploadResource(uploadId);
      RequestStreamReader reader = new RequestStreamReader(upResource);
      uploadResources.put(upResource.getUploadId(), upResource);
      if (isLimited(upResource, contentLength))
      {
         upResource.setStatus(UploadResource.FAILED_STATUS);
         return;
      }
     
      Map<String, String> headers = reader.parseHeaders(inputStream, encoding);

      String fileName = reader.getFileName(headers);
      if (fileName == null)
         fileName = uploadId;
      fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);

      upResource.setFileName(fileName);
      upResource.setMimeType(headers.get(RequestStreamReader.CONTENT_TYPE));
      upResource.setStoreLocation(uploadLocation_ + "/" + uploadId + "." + fileName);
      upResource.setEstimatedSize(contentLength);     
      File fileStore = new File(upResource.getStoreLocation());
      if (!fileStore.exists())
         fileStore.createNewFile();
      FileOutputStream output = new FileOutputStream(fileStore);
      reader.readBodyData(inputStream, contentType, output);

      if (upResource.getStatus() == UploadResource.UPLOADING_STATUS)
      {
         upResource.setStatus(UploadResource.UPLOADED_STATUS);
         return;
      }

      uploadResources.remove(uploadId);
      fileStore.delete();
   }

   @SuppressWarnings("unchecked")
   private void putToStackInSession(HttpSession session, String uploadId)
   {
      Set<String> uploadResouceIds = (Set<String>)session.getAttribute(UploadService.UPLOAD_RESOURCES_STACK);
      if (uploadResouceIds == null)
      {
         uploadResouceIds = new HashSet();
      }
      uploadResouceIds.add(uploadId);
      session.setAttribute(UploadService.UPLOAD_RESOURCES_STACK, uploadResouceIds);
   }

   /**
    * Get UploadResource by uploadId
    *
    * @param uploadId
    *           uploadId of UploadResource
    * @return org.exoplatform.upload.UploadResource of uploadId
    */
   public UploadResource getUploadResource(String uploadId)
   {
      return uploadResources.get(uploadId);
   }

   /**
    * Clean up temporary files that are uploaded in the Session but not removed yet
    *
    * @param session
    */
   public void cleanUp(HttpSession session)
   {
      log.debug("Cleaning up uploaded files for temporariness");
      Set<String> uploadIds = (Set<String>)session.getAttribute(UploadService.UPLOAD_RESOURCES_STACK);
      if (uploadIds != null)
      {
         for (String id : uploadIds)
         {
            removeUploadResource(id);
            uploadLimits.remove(id);
         }
      }
   }

   /**
    * @deprecated use {@link #removeUploadResource(String)} instead
    *
    * @param uploadId
    */
   @Deprecated
   public void removeUpload(String uploadId)
   {
      removeUploadResource(uploadId);
   }
  
   /**
    * Remove the UploadResource and its temporary file that associated with given <code>uploadId</code>.
    * <br/>If <code>uploadId</code> is null or UploadResource is null, do nothing
    *
    * @param uploadId uploadId of UploadResource will be removed
    */
   public void removeUploadResource(String uploadId)
   {
      if (uploadId == null)
         return;
      UploadResource upResource = uploadResources.get(uploadId);
      if (upResource != null)
      {
         uploadResources.remove(uploadId);

         if (upResource.getStoreLocation() != null)
         {
            File file = new File(upResource.getStoreLocation());
            file.delete();
         }
      }

      // uploadLimitsMB_.remove(uploadId);
   }

   /**
    * Registry upload limit size for uploadLimitsMB_. If limitMB is null,
    * defaultUploadLimitMB_ will be registried
    *
    * @param uploadId
    * @param limitMB
    *           upload limit size
    */
   public void addUploadLimit(String uploadId, Integer limitMB)
   {
      addUploadLimit(uploadId, limitMB, UploadUnit.MB);
   }
  
   public void addUploadLimit(String uploadId, Integer limit, UploadUnit unit)
   {
      if (limit == null)
      {
         uploadLimits.put(uploadId, defaultUploadLimitMB_);
      }
      else if(unit == null)
      {
         uploadLimits.put(uploadId, new UploadLimit(limit, UploadUnit.MB));
      }
      else
      {
         uploadLimits.put(uploadId, new UploadLimit(limit, unit));
      }
   }
  
   public void removeUploadLimit(String uploadId)
   {
      uploadLimits.remove(uploadId);
   }

   /**
    * Get all upload limit sizes
    *
    * @return all upload limit sizes
    */
   public Map<String, UploadLimit> getUploadLimits()
   {
      return uploadLimits;
   }

   private ServletFileUpload makeServletFileUpload(final UploadResource upResource)
   {
      // Create a factory for disk-based file items
      DiskFileItemFactory factory = new DiskFileItemFactory();

      // Set factory constraints
      factory.setSizeThreshold(0);
      factory.setRepository(new File(uploadLocation_));

      // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
      upload.setHeaderEncoding("UTF-8");
      ProgressListener listener = new ProgressListener()
      {
         public void update(long pBytesRead, long pContentLength, int pItems)
         {
            if (pBytesRead == upResource.getUploadedSize())
               return;
            upResource.addUploadedBytes(pBytesRead - upResource.getUploadedSize());
         }
      };
      upload.setProgressListener(listener);
      return upload;
   }

   private boolean isLimited(UploadResource upResource, double contentLength)
   {
      // by default, use the limit set in the service
      UploadLimit limit = defaultUploadLimitMB_;
      // if the limit is set in the request (specific for this upload) then use
      // this value instead of the default one
      if (uploadLimits.containsKey(upResource.getUploadId()))
      {
         limit = uploadLimits.get(upResource.getUploadId());
      }

      double estimatedSize = contentLength / limit.division;
      if (limit.getLimit() > 0 && estimatedSize > limit.getLimit())
      { // a limit set to 0 means unlimited        
         if (log.isDebugEnabled())
         {
            log.debug("Upload cancelled because file bigger than size limit : " + estimatedSize + " " + limit.unit + " > " + limit.getLimit()
               + " " + limit.unit);
         }
         return true;
      }
      return false;
   }

   public static class UploadLimit
   {
      private int limit;
     
      private int division;
     
      private UploadUnit unit;
     
      public UploadLimit(int limit, UploadUnit unit)
      {
         this.limit = limit;
         this.unit = unit;
         if(unit == UploadUnit.KB)
         {
            division = 1024;
         }
         else if(unit == UploadUnit.MB)
         {
            division = 1024 * 1024;
         }
         else if(unit == UploadUnit.GB)
         {
            division = 1024 * 1024 * 1024;
         }
      }
     
      public int getLimit()
      {
         return limit;
      }
     
      public String getUnit()
      {
         return unit.toString();
      }
   }
}
TOP

Related Classes of org.exoplatform.upload.UploadService$UploadLimit

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.