source: tapas/web/src/com/ether/ControllerEther.java @ 414

Last change on this file since 414 was 414, checked in by vmipsl, 12 years ago

login application
servlet data
ControllerEponge?

File size: 12.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 com.ether.user.User;
8import net.sf.json.JSON;
9import net.sf.json.JSONArray;
10import net.sf.json.JSONNull;
11import net.sf.json.JSONObject;
12import net.sf.json.util.JSONUtils;
13import org.apache.commons.logging.Log;
14import org.apache.commons.logging.LogFactory;
15import org.jetbrains.annotations.NotNull;
16import org.jetbrains.annotations.Nullable;
17import org.springframework.beans.factory.annotation.Required;
18import org.springframework.web.servlet.ModelAndView;
19import org.springframework.web.servlet.mvc.AbstractController;
20import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;
21import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
22
23import javax.servlet.http.HttpServletRequest;
24import javax.servlet.http.HttpServletResponse;
25import java.io.IOException;
26import java.io.UnsupportedEncodingException;
27import java.lang.annotation.Annotation;
28import java.lang.reflect.Method;
29import java.security.InvalidParameterException;
30import java.util.ArrayList;
31import java.util.Collection;
32import java.util.Date;
33import java.util.HashMap;
34import java.util.List;
35import java.util.Map;
36
37public class ControllerEther
38        extends AbstractController
39{
40    /**
41     * This method is used to change Locale with the framework Spring
42     *
43     * @throws WebException
44     */
45    @ControllerMethod()
46    public void setLocale()
47            throws WebException
48    {
49    }
50
51    @Override
52    @Nullable
53    protected ModelAndView handleRequestInternal( @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
54            throws WebException
55    {
56        try
57        {
58            if( !_initialized )
59                initialize();
60
61            request.setCharacterEncoding( UTF8Charset.getEncoding() );
62
63            // Get method to call
64            final String methodName = _methodNameResolver.getHandlerMethodName( request );
65
66            final MethodDescription methodDescription = _methods.get( methodName );
67            if( null == methodDescription )
68            {
69                WebHelper.displayAjaxError( response, methodName );
70                if( LOGGER.isWarnEnabled() )
71                    LOGGER.warn( String.format( "Controller=%1$s Method=%2$s METHOD NOT FOUND", getClass().getSimpleName(), methodName ) );
72                return null;
73            }
74
75            return invokeMethod( methodDescription, request, response );
76        }
77        catch( UnsupportedEncodingException e )
78        {
79            throw new WebException( WebException.WebCode.ERROR_UNSUPPORTED_UTF8_ENCODING, e );
80        }
81        catch( NoSuchRequestHandlingMethodException e )
82        {
83            throw new WebException( WebException.WebCode.ERROR_NO_REQUEST_HANDLING_METHOD, e );
84        }
85    }
86
87    @Nullable
88    private ModelAndView invokeMethod( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
89            throws WebException
90    {
91        try
92        {
93            // Parse parameters
94            final Object[] params = buildParams( methodDescription, request );
95
96            if( methodDescription.isRequestMandatory() )
97                params[params.length - 1] = request;
98
99            if( methodDescription.isBackofficeMethod() )
100            {
101                final String defaultView = null != methodDescription.getDefaultView() ? methodDescription.getDefaultView() : methodDescription.getView();
102                final User user = (User) request.getSession().getAttribute( "SES_USER" );
103                if( null == user )
104                {
105                    return new ModelAndView( defaultView, "errors", "login.error.unknown" );
106                }
107                else if( null != user && !user.isAccessToBO() )
108                {
109                    return new ModelAndView( defaultView, "errors", "login.error.bo.notAccepted" );
110                }
111            }
112
113            final Object result;
114            try
115            {
116                // Invoke method (go to controller)
117                result = methodDescription.getMethod().invoke( this, params );
118            }
119            catch( Throwable e )
120            {
121                sendSerializedException( response, e.getCause() );
122                return null;
123            }
124
125            // Return result
126            if( !methodDescription.getView().isEmpty() )
127            {
128                response.setStatus( HttpServletResponse.SC_OK );
129                if( result instanceof Map )
130                    return new ModelAndView( methodDescription.getView(), (Map) result );
131                else
132                    return new ModelAndView( methodDescription.getView(), "result", result );
133            }
134            else if( methodDescription.isJsonResult() )
135            {
136                response.setStatus( HttpServletResponse.SC_OK );
137                final String jsonResult = convertToJson( result );
138                WebHelper.writeJsonToResponse( response, jsonResult );
139                return null;
140            }
141            else
142            {
143                response.setStatus( HttpServletResponse.SC_NO_CONTENT );
144                return null;
145            }
146        }
147        catch( Throwable e )
148        {
149            throw new WebException( e );
150        }
151    }
152
153    private void sendSerializedException( @NotNull final HttpServletResponse response, @NotNull final Throwable exception )
154            throws IOException
155    {
156        response.setStatus( WebHelper.STATUS_CODE_SERVICE_EXCEPTION );
157
158        if( exception.getCause().equals( WebException.getExceptionThrowable() ) )
159            WebHelper.writeJsonToResponse( response, exception.getLocalizedMessage() );
160        else
161            WebHelper.writeJsonToResponse( response, _jsonHelper.toJSONObject( exception ).toString() );
162    }
163
164    @NotNull
165    private String convertToJson( @Nullable final Object object )
166    {
167        if( null == object )
168            return JSONNull.getInstance().toString();
169        if( object instanceof JSON )
170            return object.toString();
171        if( object instanceof Collection )
172            return _jsonHelper.toJSON( (Collection) object ).toString();
173        if( object.getClass().isArray() )
174            return _jsonHelper.toJSON( object ).toString();
175        if( object instanceof Number || object instanceof Boolean || object instanceof String )
176            return JSONUtils.valueToString( object );
177        return _jsonHelper.toJSON( object ).toString();
178    }
179
180    @NotNull
181    private Object[] buildParams( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request )
182            throws InvalidParameterException
183    {
184        final List<Object> params = new ArrayList<Object>();
185        for( final ParamDescription paramDescription : methodDescription.getParams() )
186        {
187            if( null == paramDescription )
188            {
189                params.add( null );
190                continue;
191            }
192            final boolean canBeNull = !paramDescription.isPrimitive() && !paramDescription.isMandatory();
193            final String paramValue = WebHelper.getRequestParameter( request, paramDescription.getName(), null, canBeNull );
194            final boolean useJSON = paramDescription.isUsingJSON();
195            params.add( convertParameter( paramDescription.getType(), paramValue, useJSON ) );
196        }
197        return params.toArray( new Object[params.size()] );
198    }
199
200    @Nullable
201    private Object convertParameter( @NotNull final Class paramType, @Nullable final String paramValue, final boolean useJSON )
202    {
203        if( null == paramValue )
204            return null;
205        if( useJSON )
206            return _jsonHelper.fromJSON( _jsonHelper.toJSON( paramValue ), paramType );
207        if( JSONObject.class.equals( paramType ) )
208            return _jsonHelper.toJSON( paramValue );
209        if( JSONArray.class.equals( paramType ) )
210            return _jsonHelper.toJSON( paramValue );
211        if( String.class.equals( paramType ) )
212            return paramValue;
213        if( Boolean.TYPE.equals( paramType ) || Boolean.class.equals( paramType ) )
214            return Boolean.valueOf( paramValue );
215        if( Integer.TYPE.equals( paramType ) || Integer.class.equals( paramType ) )
216            return Integer.valueOf( paramValue );
217        if( Long.TYPE.equals( paramType ) || Long.class.equals( paramType ) )
218            return Long.valueOf( paramValue );
219        if( Float.TYPE.equals( paramType ) || Float.class.equals( paramType ) )
220            return Float.valueOf( paramValue );
221        if( Double.TYPE.equals( paramType ) || Double.class.equals( paramType ) )
222            return Double.valueOf( paramValue );
223        if( Date.class.isAssignableFrom( paramType ) )
224            return new Date( Long.valueOf( paramValue ) );
225        if( paramType.isEnum() )
226            return Enum.valueOf( paramType, paramValue );
227        if( Map.class.isAssignableFrom( paramType ) )
228            return JSONObject.fromObject( paramValue );
229
230        throw new UnsupportedOperationException( "Unsupported: cast parameter to " + paramType.getName() );
231    }
232
233    private void initialize()
234            throws WebException
235    {
236        for( final Method method : getClass().getMethods() )
237        {
238            final ControllerMethod annotation = method.getAnnotation( ControllerMethod.class );
239            if( null != annotation )
240            {
241                final MethodDescription methodDescription = new MethodDescription( method, annotation );
242                fillMethodDescription( method, methodDescription );
243                _methods.put( method.getName(), methodDescription );
244            }
245        }
246
247        _initialized = true;
248    }
249
250    private void fillMethodDescription( @NotNull final Method method, @NotNull final MethodDescription methodDescription )
251            throws WebException
252    {
253        final Class<?>[] paramTypes = method.getParameterTypes();
254        final Annotation[][] paramAnnotations = method.getParameterAnnotations();
255
256        if( paramTypes.length != paramAnnotations.length )
257            throw new WebException( WebException.WebCode.ERROR_NUMBER_OF_PARAM_TYPES_NOT_EQUAL_TO_PARAM_ANNOTATIONS, paramTypes.length + " " + paramAnnotations.length );
258
259        for( int i = 0; i < paramTypes.length; ++i )
260        {
261            ParamName paramNameAnnotation = null;
262            Mandatory mandatoryAnnotation = null;
263            UseJSON useJSONAnnotation = null;
264            for( final Annotation paramAnnotation : paramAnnotations[i] )
265            {
266                if( paramAnnotation instanceof ParamName )
267                    paramNameAnnotation = (ParamName) paramAnnotation;
268                if( paramAnnotation instanceof Mandatory )
269                    mandatoryAnnotation = (Mandatory) paramAnnotation;
270                if( paramAnnotation instanceof UseJSON )
271                    useJSONAnnotation = (UseJSON) paramAnnotation;
272            }
273            if( null == paramNameAnnotation )
274                methodDescription.addNullParam();
275            else
276            {
277                final boolean mandatory = ( null != mandatoryAnnotation );
278                final boolean useJSON = ( null != useJSONAnnotation );
279                methodDescription.addParam( paramNameAnnotation.value(), paramTypes[i], mandatory, useJSON );
280            }
281        }
282    }
283
284    @Required
285    public void setMethodNameResolver( final MethodNameResolver methodNameResolver )
286    {
287        _methodNameResolver = methodNameResolver;
288    }
289
290    protected JSONHelper getJsonHelper()
291    {
292        return _jsonHelper;
293    }
294
295    @Required
296    public void setJsonHelper( final JSONHelper jsonHelper )
297    {
298        _jsonHelper = jsonHelper;
299    }
300
301    protected Map<String, MethodDescription> getMethods()
302    {
303        return _methods;
304    }
305
306    @Required
307    public void setTapasService( @NotNull final TapasService tapasService )
308    {
309        _tapasService = tapasService;
310    }
311
312    public TapasService getTapasService()
313    {
314        return _tapasService;
315    }
316
317    private static final Log LOGGER = LogFactory.getLog( ControllerEther.class );
318
319    private JSONHelper _jsonHelper;
320    private MethodNameResolver _methodNameResolver;
321    private Map<String, MethodDescription> _methods = new HashMap<String, MethodDescription>();
322    private boolean _initialized; /*=false*/
323
324    private TapasService _tapasService;
325}
Note: See TracBrowser for help on using the repository browser.