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;
027    
028    import java.util.ArrayList;
029    import java.util.HashMap;
030    import java.util.List;
031    import java.util.Map;
032    
033    import org.apache.commons.fileupload.FileItem;
034    import org.apache.log4j.Logger;
035    
036    import com.softwarementors.extjs.djn.StringUtils;
037    import com.softwarementors.extjs.djn.api.Registry;
038    import com.softwarementors.extjs.djn.config.GlobalConfiguration;
039    import com.softwarementors.extjs.djn.router.dispatcher.Dispatcher;
040    import com.softwarementors.extjs.djn.router.processor.RequestException;
041    import com.softwarementors.extjs.djn.router.processor.ResponseData;
042    import com.softwarementors.extjs.djn.router.processor.standard.StandardErrorResponseData;
043    import com.softwarementors.extjs.djn.router.processor.standard.StandardRequestProcessorBase;
044    import com.softwarementors.extjs.djn.router.processor.standard.StandardSuccessResponseData;
045    
046    import edu.umd.cs.findbugs.annotations.NonNull;
047    
048    public abstract class FormPostRequestProcessorBase extends StandardRequestProcessorBase {
049      
050      @NonNull
051      private static Logger logger = Logger.getLogger( FormPostRequestProcessorBase.class );
052      
053      protected FormPostRequestProcessorBase( Registry registry, Dispatcher dispatcher, GlobalConfiguration globalConfiguration ) {
054        super( registry, dispatcher, globalConfiguration);
055      }
056      
057      protected String process(Map<String,String> formParameters, Map<String, FileItem> fileFields) {
058        assert formParameters != null;
059        assert fileFields != null;
060         
061        checkNoMissingParameters(formParameters);
062        FormPostRequestData request = createRequestObject(formParameters, fileFields);
063    
064        ResponseData response = processRequest( request );
065        StringBuilder result = new StringBuilder();
066        appendIndividualResponseJsonString(response, result);
067        
068        return result.toString();
069      }
070    
071      private static String getAndRemove( Map<String, String> keyValues, String key) {
072        String result = keyValues.get(key);
073        keyValues.remove(key);
074        return result;
075      }
076      
077      private static FormPostRequestData createRequestObject(Map<String, String> formParameters, Map<String, FileItem> fileFields) {
078        assert formParameters != null;
079        assert fileFields != null;
080        
081        Map<String,String> parameters = new HashMap<String,String>(formParameters);
082        
083        String type = getAndRemove(parameters,  FormPostRequestData.TYPE_ELEMENT);
084        String action = getAndRemove( parameters, FormPostRequestData.ACTION_ELEMENT );
085        String method = getAndRemove(parameters,  FormPostRequestData.METHOD_ELEMENT );
086        Long tid = Long.valueOf( Long.parseLong( getAndRemove(parameters,  FormPostRequestData.TID_ELEMENT)) );
087        boolean isUpload = Boolean.parseBoolean(getAndRemove(parameters, FormPostRequestData.UPLOAD_ELEMENT) );   
088       
089        return new FormPostRequestData( type, action, method, tid, isUpload, parameters, fileFields);
090      }
091    
092      private static void checkNoMissingParameters(Map<String, String> parameters) {
093        assert parameters != null;
094        
095        List<String> missingParameters = new ArrayList<String>();
096        addParameterIfMissing( parameters, FormPostRequestData.ACTION_ELEMENT, missingParameters );
097        addParameterIfMissing( parameters, FormPostRequestData.METHOD_ELEMENT, missingParameters );
098        addParameterIfMissing( parameters, FormPostRequestData.TYPE_ELEMENT, missingParameters );
099        addParameterIfMissing( parameters, FormPostRequestData.TID_ELEMENT, missingParameters );
100        addParameterIfMissing( parameters, FormPostRequestData.UPLOAD_ELEMENT, missingParameters );
101        
102        if( !missingParameters.isEmpty() ) {
103          RequestException ex = RequestException.forFormPostMissingParameters( missingParameters );
104          logger.error( ex.getMessage(), ex ); 
105          throw ex;
106        }
107      }
108    
109      private static void addParameterIfMissing( Map<String, String> parameters, String parameterName, List<String> missingParameters ) {
110        assert parameters != null;
111        assert !StringUtils.isEmpty(parameterName);
112        assert missingParameters != null;
113        
114        if( !parameters.containsKey(parameterName)) {
115          missingParameters.add( parameterName );
116        }
117      }
118      
119      private ResponseData processRequest( FormPostRequestData request ) {
120        assert request != null;
121        
122        try {
123          Object[] parameters;
124          parameters = new Object[] {request.getFormParameters(), request.getFileFields()};      
125          Object result = dispatchStandardMethod( request.getAction(), request.getMethod(), parameters );
126          StandardSuccessResponseData response = new StandardSuccessResponseData( request.getTid(), request.getAction(), request.getMethod() );
127          response.setResult( result);
128          return response;
129        }
130        catch( Exception t ) {        
131          StandardErrorResponseData response = createJsonServerErrorResponse(request, t);
132          logger.error( "(Controlled) server error: " + t.getMessage() + " for Form Post Method " + request.getFullMethodName(), t); 
133          return response;
134        }  
135      }
136      
137    }