001    /*
002     * Copyright © 2008, 2009 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 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 General Public License for more details.
018     *
019     * You should have received a copy of the GNU 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.RequestProcessorBase;
042    import com.softwarementors.extjs.djn.router.processor.ResponseBase;
043    import com.softwarementors.extjs.djn.router.processor.standard.JsonErrorResponse;
044    import com.softwarementors.extjs.djn.router.processor.standard.JsonSuccessResponse;
045    
046    public abstract class FormPostRequestProcessorBase extends RequestProcessorBase {
047      
048      private static Logger logger = Logger.getLogger( FormPostRequestProcessorBase.class );
049      
050      protected FormPostRequestProcessorBase( Registry registry, Dispatcher dispatcher, GlobalConfiguration globalConfiguration ) {
051        super( registry, dispatcher, globalConfiguration);
052      }
053      
054      protected String process(Map<String,String> formParameters, Map<String, FileItem> fileFields) {
055        assert formParameters != null;
056        assert fileFields != null;
057         
058        checkNoMissingParameters(formParameters);
059        FormPostRequest request = createRequestObject(formParameters, fileFields);
060    
061        ResponseBase response = processRequest( request );
062        StringBuilder result = new StringBuilder();
063        appendIndividualResponseJsonString(response, result);
064        
065        return result.toString();
066      }
067    
068      private static String getAndRemove( Map<String, String> keyValues, String key) {
069        String result = keyValues.get(key);
070        keyValues.remove(key);
071        return result;
072      }
073      
074      private FormPostRequest createRequestObject(Map<String, String> formParameters, Map<String, FileItem> fileFields) {
075        assert formParameters != null;
076        assert fileFields != null;
077        
078        Map<String,String> parameters = new HashMap<String,String>(formParameters);
079        
080        String type = getAndRemove(parameters,  FormPostRequest.TYPE_ELEMENT);
081        String action = getAndRemove( parameters, FormPostRequest.ACTION_ELEMENT );
082        String method = getAndRemove(parameters,  FormPostRequest.METHOD_ELEMENT );
083        Long tid = new Long( Long.parseLong( getAndRemove(parameters,  FormPostRequest.TID_ELEMENT)) );
084        boolean isUpload = Boolean.parseBoolean(getAndRemove(parameters, FormPostRequest.UPLOAD_ELEMENT) );   
085       
086        return new FormPostRequest( type, action, method, tid, isUpload, parameters, fileFields);
087      }
088    
089      private void checkNoMissingParameters(Map<String, String> parameters) {
090        assert parameters != null;
091        
092        List<String> missingParameters = new ArrayList<String>();
093        addParameterIfMissing( parameters, FormPostRequest.ACTION_ELEMENT, missingParameters );
094        addParameterIfMissing( parameters, FormPostRequest.METHOD_ELEMENT, missingParameters );
095        addParameterIfMissing( parameters, FormPostRequest.TYPE_ELEMENT, missingParameters );
096        addParameterIfMissing( parameters, FormPostRequest.TID_ELEMENT, missingParameters );
097        addParameterIfMissing( parameters, FormPostRequest.UPLOAD_ELEMENT, missingParameters );
098        
099        if( !missingParameters.isEmpty() ) {
100          RequestException ex = RequestException.forFormPostMissingParameters( missingParameters );
101          logger.error( ex.getMessage(), ex ); 
102          throw ex;
103        }
104      }
105    
106      private void addParameterIfMissing( Map<String, String> parameters, String parameterName, List<String> missingParameters ) {
107        assert parameters != null;
108        assert !StringUtils.isEmpty(parameterName);
109        assert missingParameters != null;
110        
111        if( !parameters.containsKey(parameterName)) {
112          missingParameters.add( parameterName );
113        }
114      }
115      
116      private ResponseBase processRequest( FormPostRequest request ) {
117        assert request != null;
118        
119        try {
120          Object[] parameters;
121          parameters = new Object[] {request.getFormParameters(), request.getFileFields()};      
122          Object result = dispatch( request.getAction(), request.getMethod(), parameters );
123          JsonSuccessResponse response = new JsonSuccessResponse( request.getTid(), request.getAction(), request.getMethod(), result);
124          return response;
125        }
126        catch( Throwable t ) {        
127          JsonErrorResponse response = createJsonServerErrorResponse(request, t);
128          logger.error( "(Controlled) server error: " + t.getMessage() + " for Form Post Method " + request.getAction() + "." + request.getMethod(), t); 
129          return response;
130        }  
131      }
132      
133    }