001    /*
002     * Copyright © 2008, 2012 Pedro Agulló Soliveres.
003     * 
004     * This file is part of DirectJNgine.
005     *
006     * DirectJNgine is free software: you can redistribute it and/or modify
007     * it under the terms of the GNU Lesser General Public License as published by
008     * the Free Software Foundation, either version 3 of the License.
009     *
010     * Commercial use is permitted to the extent that the code/component(s)
011     * do NOT become part of another Open Source or Commercially developed
012     * licensed development library or toolkit without explicit permission.
013     *
014     * DirectJNgine is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public License
020     * along with DirectJNgine.  If not, see <http://www.gnu.org/licenses/>.
021     * 
022     * This software uses the ExtJs library (http://extjs.com), which is 
023     * distributed under the GPL v3 license (see http://extjs.com/license).
024     */
025    
026    package com.softwarementors.extjs.djn.router.processor.standard.form.upload;
027    
028    import java.io.IOException;
029    import java.io.Writer;
030    import java.util.HashMap;
031    import java.util.List;
032    import java.util.Map;
033    
034    import org.apache.commons.fileupload.FileItem;
035    import org.apache.commons.fileupload.FileUploadException;
036    import org.apache.commons.fileupload.servlet.ServletFileUpload;
037    import org.apache.log4j.Logger;
038    
039    import com.softwarementors.extjs.djn.api.Registry;
040    import com.softwarementors.extjs.djn.config.GlobalConfiguration;
041    import com.softwarementors.extjs.djn.router.dispatcher.Dispatcher;
042    import com.softwarementors.extjs.djn.router.processor.standard.form.FormPostRequestProcessorBase;
043    
044    import edu.umd.cs.findbugs.annotations.NonNull;
045    
046    public class UploadFormPostRequestProcessor extends FormPostRequestProcessorBase {
047      
048      @NonNull
049      private static final Logger logger = Logger.getLogger(UploadFormPostRequestProcessor.class);
050      
051      public UploadFormPostRequestProcessor(Registry registry, Dispatcher dispatcher, GlobalConfiguration globalConfiguration) {
052        super( registry, dispatcher, globalConfiguration );
053      }
054    
055      public void process(List<FileItem> fileItems, Writer writer) throws IOException {
056        assert fileItems != null;
057        assert writer != null;
058        
059        Map<String, String> formParameters = new HashMap<String,String>();
060        Map<String, FileItem> fileFields = new HashMap<String,FileItem>();
061        for( FileItem item : fileItems ) {
062          if (item.isFormField()) {
063            formParameters.put( item.getFieldName(), item.getString());
064          } 
065          else {
066            fileFields.put( item.getFieldName(), item );
067          }
068        }
069        
070        if( logger.isDebugEnabled()) { // Avoid expensive function calls if logging is not needed
071          logger.debug( "Request data (UPLOAD FORM)=>" + getFormParametersLogString(formParameters) + " FILES: " + getFileParametersLogString(fileFields));
072        }
073        String result = process(formParameters, fileFields);
074        
075        String resultString = "<html><body><textarea>";
076        resultString += result;
077        resultString += ("</textarea></body></html>");
078        writer.write( resultString );
079        if( logger.isDebugEnabled() ) {
080          logger.debug( "ResponseData data (UPLOAD FORM)=>" + resultString );
081        }
082      }
083    
084      private static String getFormParametersLogString(Map<String, String> formParameters) {
085        StringBuilder result = new StringBuilder();
086        for( Map.Entry<String,String> entry : formParameters.entrySet() ) {
087          String fieldName = entry.getKey();
088          String value = entry.getValue();
089          result.append( fieldName );
090          result.append( "=");
091          result.append( value);
092          result.append( ";");
093        }
094        return result.toString();
095      }
096    
097      private static String getFileParametersLogString(Map<String, FileItem> fileFields) {
098        StringBuilder result = new StringBuilder();
099        for( Map.Entry<String,FileItem> entry : fileFields.entrySet() ) {
100          FileItem fileItem = entry.getValue();
101          String fieldName = entry.getKey();
102          result.append( fieldName );
103          result.append( "=");
104          String fileName = fileItem.getName();
105          result.append( fileName );
106          result.append( ";");
107        }
108        return result.toString();
109      }
110    
111      public static ServletFileUpload createFileUploader() {
112        // Create a factory for disk-based file items
113        DiskFileItemFactory2 factory = new DiskFileItemFactory2();
114        // Set factory constraints so that files are never written to disk
115        final int MAX_UPLOAD_MEMORY_SIZE = Integer.MAX_VALUE;
116        // If request size bigger than this, store files to disk
117        factory.setSizeThreshold(MAX_UPLOAD_MEMORY_SIZE); 
118         // Avoid creating a cleaning thread which Google AppEngine will not like!
119        factory.setFileCleaningTracker(null); 
120        // Create a new file upload handler
121        ServletFileUpload upload = new ServletFileUpload(factory);
122    
123        // Set upload handler limits
124        upload.setSizeMax(MAX_UPLOAD_MEMORY_SIZE);
125        upload.setFileSizeMax(MAX_UPLOAD_MEMORY_SIZE);
126        return upload;
127      }
128    
129      public void handleFileUploadException(FileUploadException e) {
130        assert e != null;
131        
132        com.softwarementors.extjs.djn.router.processor.standard.form.upload.FileUploadException ex = com.softwarementors.extjs.djn.router.processor.standard.form.upload.FileUploadException.forFileUploadException(e);
133        logger.error( ex.getMessage(), ex);
134        throw ex;
135      }
136      
137    }