source: ether_ndacc/trunk/web/src/com/ether/ControllerEther.java @ 364

Last change on this file since 364 was 364, checked in by rboipsl, 12 years ago

ajout umkehr

File size: 9.3 KB
Line 
1package com.ether;
2
3import com.ether.annotation.ControllerMethod;
4import com.ether.annotation.Mandatory;
5import com.ether.annotation.ParamName;
6import com.ether.annotation.UseJSON;
7import net.sf.json.JSON;
8import net.sf.json.JSONArray;
9import net.sf.json.JSONNull;
10import net.sf.json.JSONObject;
11import net.sf.json.util.JSONUtils;
12import org.apache.commons.logging.Log;
13import org.apache.commons.logging.LogFactory;
14import org.jetbrains.annotations.NotNull;
15import org.jetbrains.annotations.Nullable;
16import org.springframework.beans.factory.annotation.Required;
17import org.springframework.web.servlet.ModelAndView;
18import org.springframework.web.servlet.mvc.AbstractController;
19import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;
20import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
21
22import javax.servlet.http.HttpServletRequest;
23import javax.servlet.http.HttpServletResponse;
24import java.io.UnsupportedEncodingException;
25import java.lang.annotation.Annotation;
26import java.lang.reflect.Method;
27import java.security.InvalidParameterException;
28import java.util.ArrayList;
29import java.util.Collection;
30import java.util.Date;
31import java.util.HashMap;
32import java.util.List;
33import java.util.Map;
34
35public class ControllerEther
36        extends AbstractController
37{
38        @Override
39        @Nullable
40        protected ModelAndView handleRequestInternal(@NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response)
41            throws WebException, EtherException
42    {
43                try {
44                        if (!_initialized)
45                                initialize();
46
47
48                        request.setCharacterEncoding(UTF8Charset.getEncoding());
49
50                        final String methodName = _methodNameResolver.getHandlerMethodName(request);
51
52                        final MethodDescription methodDescription = _methods.get(methodName);
53                        if (null == methodDescription) {
54                                WebHelper.displayError( response, methodName );
55                                return null;
56                        }
57
58                        return invokeMethod(methodDescription, request, response);
59                } catch (UnsupportedEncodingException e) {
60                        throw new WebException( WebException.WebCode.ERROR_UNSUPPORTED_UTF8_ENCODING, e);
61                } catch (NoSuchRequestHandlingMethodException e) {
62                        throw new WebException( WebException.WebCode.ERROR_NO_REQUEST_HANDLING_METHOD, e);
63                }
64        }
65
66        @Nullable
67        private ModelAndView invokeMethod( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response)
68                throws WebException
69        {
70                try {
71                        // Parse parameters
72                        final Object[] params = buildParams(methodDescription, request);
73
74                        // Invoke method (go to controller)
75                        final Object result = methodDescription.getMethod().invoke(this, params);
76
77                        if (!methodDescription.getView().isEmpty()) {
78                                response.setStatus(HttpServletResponse.SC_OK);
79                                if (result instanceof Map)
80                                        return new ModelAndView(methodDescription.getView(), (Map) result);
81                                else
82                                        return new ModelAndView(methodDescription.getView(), "result", result);
83
84                        } else if (methodDescription.isJsonResult()) {
85                                response.setStatus(HttpServletResponse.SC_OK);
86                                final String jsonResult = convertToJson(result);
87                                WebHelper.writeJsonToResponse(response, jsonResult);
88                                return null;
89                        } else {
90                                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
91                                return null;
92                        }
93                } catch (Throwable e) {
94                        throw new WebException(e);
95                }
96        }
97
98        @NotNull
99        private String convertToJson( @Nullable final Object object )
100    {
101        if( null == object)
102            return JSONNull.getInstance().toString();
103        if( object instanceof JSON )
104            return object.toString();
105        if( object instanceof Collection )
106            return _jsonHelper.toJSON( (Collection) object ).toString();
107        if( object.getClass().isArray() )
108            return _jsonHelper.toJSON( object ).toString();
109        if( object instanceof Number || object instanceof Boolean || object instanceof String )
110            return JSONUtils.valueToString( object );
111        return _jsonHelper.toJSON( object ).toString();
112    }
113
114        @NotNull
115        private Object[] buildParams(@NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request)
116                throws InvalidParameterException
117        {
118                final List<Object> params = new ArrayList<Object>();
119                for (final ParamDescription paramDescription : methodDescription.getParams()) {
120                        if (null == paramDescription) {
121                                params.add(null);
122                                continue;
123                        }
124                        final boolean canBeNull = !paramDescription.isPrimitive() && !paramDescription.isMandatory();
125                        final String paramValue = WebHelper.getRequestParameter(request, paramDescription.getName(), null, canBeNull);
126                        final boolean useJSON = paramDescription.isUsingJSON();
127                        params.add(convertParameter(paramDescription.getType(), paramValue, useJSON));
128                }
129                return params.toArray(new Object[params.size()]);
130        }
131
132        @Nullable
133        private Object convertParameter( @NotNull final Class paramType, @Nullable final String paramValue, final boolean useJSON )
134    {
135        if( null == paramValue )
136            return null;
137        if( useJSON )
138            return _jsonHelper.fromJSON( _jsonHelper.toJSON( paramValue ), paramType );
139        if( JSONObject.class.equals( paramType ) )
140            return _jsonHelper.toJSON( paramValue );
141        if( JSONArray.class.equals( paramType ) )
142            return _jsonHelper.toJSON( paramValue );
143        if( String.class .equals( paramType ) )
144            return paramValue;
145        if( Boolean.TYPE.equals( paramType ) || Boolean.class.equals( paramType ) )
146            return Boolean.valueOf( paramValue );
147        if( Integer.TYPE.equals( paramType ) || Integer.class.equals( paramType ) )
148            return Integer.valueOf( paramValue );
149        if( Long.TYPE.equals( paramType ) || Long.class.equals( paramType ) )
150            return Long.valueOf( paramValue );
151        if( Float.TYPE.equals( paramType ) || Float.class.equals( paramType ) )
152            return Float.valueOf( paramValue );
153        if( Double.TYPE.equals( paramType ) || Double.class.equals( paramType ) )
154            return Double.valueOf( paramValue );
155        if( Date.class.isAssignableFrom( paramType ) )
156            return new Date( Long.valueOf( paramValue ) );
157        if( paramType.isEnum() )
158            return Enum.valueOf( paramType, paramValue );
159        if( Map.class.isAssignableFrom( paramType ) )
160            return JSONObject.fromObject( paramValue );
161
162        throw new UnsupportedOperationException( "Unsupported: cast parameter to " + paramType.getName() );
163    }
164
165    private void initialize()
166        throws WebException
167    {
168        for( final Method method : getClass().getMethods() )
169        {
170            final ControllerMethod annotation = method.getAnnotation( ControllerMethod.class );
171            if( null != annotation )
172            {
173                final MethodDescription methodDescription = new MethodDescription( method, annotation );
174                fillMethodDescription( method, methodDescription );
175                _methods.put( method.getName(), methodDescription );
176            }
177        }
178
179        _initialized = true;
180    }
181
182    private void fillMethodDescription( @NotNull final Method method, @NotNull final MethodDescription methodDescription )
183        throws WebException
184    {
185        final Class<?>[] paramTypes = method.getParameterTypes();
186        final Annotation[][] paramAnnotations = method.getParameterAnnotations();
187
188        if(paramTypes.length != paramAnnotations.length)
189                throw new WebException( WebException.WebCode.ERROR_NUMBER_OF_PARAM_TYPES_NOT_EQUAL_TO_PARAM_ANNOTATIONS, paramTypes.length+" "+paramAnnotations.length);
190
191        for( int i = 0; i < paramTypes.length; ++i )
192        {
193            ParamName paramNameAnnotation = null;
194            Mandatory mandatoryAnnotation = null;
195            UseJSON useJSONAnnotation = null;
196            for( final Annotation paramAnnotation : paramAnnotations[i] )
197            {
198                if( paramAnnotation instanceof ParamName )
199                    paramNameAnnotation = (ParamName) paramAnnotation;
200                if( paramAnnotation instanceof Mandatory )
201                    mandatoryAnnotation = (Mandatory) paramAnnotation;
202                if( paramAnnotation instanceof UseJSON )
203                    useJSONAnnotation = (UseJSON) paramAnnotation;
204            }
205            if( null == paramNameAnnotation )
206                methodDescription.addNullParam();
207            else
208            {
209                final boolean mandatory = ( null != mandatoryAnnotation );
210                final boolean useJSON = ( null != useJSONAnnotation );
211                methodDescription.addParam( paramNameAnnotation.value(), paramTypes[i], mandatory, useJSON );
212            }
213        }
214    }
215
216    @Required
217    public void setMethodNameResolver( final MethodNameResolver methodNameResolver )
218    {
219        _methodNameResolver = methodNameResolver;
220    }
221
222    protected JSONHelper getJsonHelper()
223    {
224        return _jsonHelper;
225    }
226
227    @Required
228    public void setJsonHelper( final JSONHelper jsonHelper )
229    {
230        _jsonHelper = jsonHelper;
231    }
232
233    protected Map<String, MethodDescription> getMethods()
234    {
235        return _methods;
236    }
237
238    private static final Log LOGGER = LogFactory.getLog( ControllerEther.class );
239
240    private JSONHelper _jsonHelper;
241    private MethodNameResolver _methodNameResolver;
242    private Map<String, MethodDescription> _methods = new HashMap<String, MethodDescription>();
243    private boolean _initialized; /*=false*/
244}
Note: See TracBrowser for help on using the repository browser.