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

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

BO gestion login
clean parameter

File size: 14.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    /**
52     * This method logs a user
53     *
54     * @param login
55     * @param password
56     * @param request
57     * @return
58     * @throws ServiceException
59     */
60    @ControllerMethod(requestMandatory = true, jsonResult = true)
61    public JSONObject login( @ParamName(ParameterConstants.PARAMETER_LOGIN) final String login,
62                             @ParamName(ParameterConstants.PARAMETER_PWD) final String password,
63                             @NotNull final HttpServletRequest request )
64            throws ServiceException
65    {
66        final JSONObject jSONUser = new JSONObject();
67        final JSONObject result = new JSONObject();
68
69        if( login != null && password != null )
70        {
71            try
72            {
73                final User user = _tapasService.getUserByEmail( login );
74                final String encryptedPassword = EtherHelper.encryptPassword( password );
75                if( user == null )
76                    result.put( "errors", "login.error.notFound" );
77                else if( !encryptedPassword.equals( user.getPassword() ) )
78                    result.put( "errors", "login.error.wrongPassword" );
79                else
80                {
81                    request.getSession().setAttribute( "SES_USER", user );
82                    jSONUser.put( "name", user.getLastName() );
83                    jSONUser.put( "firstName", user.getFirstName() );
84                    jSONUser.put( "role", user.getRole().name() );
85                }
86            }
87            catch( Exception e )
88            {
89                result.put( "errors", "login.error.failed" );
90            }
91        }
92
93        if( !jSONUser.isEmpty() )
94            result.put( "jSONUser", jSONUser );
95        return result;
96    }
97
98    @ControllerMethod(requestMandatory = true, jsonResult = true)
99    public JSONObject logout( @NotNull final HttpServletRequest request )
100            throws ServiceException
101    {
102        request.getSession().setAttribute( "SES_USER", null );
103        request.getSession().invalidate();
104
105        return new JSONObject();
106    }
107
108    @Override
109    @Nullable
110    protected ModelAndView handleRequestInternal( @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
111            throws WebException
112    {
113        try
114        {
115            if( !_initialized )
116                initialize();
117
118            request.setCharacterEncoding( UTF8Charset.getEncoding() );
119
120            // Get method to call
121            final String methodName = _methodNameResolver.getHandlerMethodName( request );
122
123            final MethodDescription methodDescription = _methods.get( methodName );
124            if( null == methodDescription )
125            {
126                WebHelper.displayAjaxError( response, methodName );
127                if( LOGGER.isWarnEnabled() )
128                    LOGGER.warn( String.format( "Controller=%1$s Method=%2$s METHOD NOT FOUND", getClass().getSimpleName(), methodName ) );
129                return null;
130            }
131
132            return invokeMethod( methodDescription, request, response );
133        }
134        catch( UnsupportedEncodingException e )
135        {
136            throw new WebException( WebException.WebCode.ERROR_UNSUPPORTED_UTF8_ENCODING, e );
137        }
138        catch( NoSuchRequestHandlingMethodException e )
139        {
140            throw new WebException( WebException.WebCode.ERROR_NO_REQUEST_HANDLING_METHOD, e );
141        }
142    }
143
144    @Nullable
145    private ModelAndView invokeMethod( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
146            throws WebException
147    {
148        try
149        {
150            // Parse parameters
151            final Object[] params = buildParams( methodDescription, request );
152
153            if( methodDescription.isRequestMandatory() )
154                params[params.length - 1] = request;
155
156            if( methodDescription.isBackofficeMethod() )
157            {
158                final String defaultView = null != methodDescription.getDefaultView() ? methodDescription.getDefaultView() : methodDescription.getView();
159                final User user = (User) request.getSession().getAttribute( "SES_USER" );
160                if( null == user )
161                {
162                    return new ModelAndView( defaultView, "errors", "login.error.unknown" );
163                }
164                else if( null != user && !user.isAccessToBO() )
165                {
166                    return new ModelAndView( defaultView, "errors", "login.error.bo.notAccepted" );
167                }
168            }
169
170            final Object result;
171            try
172            {
173                // Invoke method (go to controller)
174                result = methodDescription.getMethod().invoke( this, params );
175            }
176            catch( Throwable e )
177            {
178                sendSerializedException( response, e.getCause() );
179                return null;
180            }
181
182            // Return result
183            if( !methodDescription.getView().isEmpty() )
184            {
185                response.setStatus( HttpServletResponse.SC_OK );
186                if( result instanceof Map )
187                    return new ModelAndView( methodDescription.getView(), (Map) result );
188                else
189                    return new ModelAndView( methodDescription.getView(), "result", result );
190            }
191            else if( methodDescription.isJsonResult() )
192            {
193                response.setStatus( HttpServletResponse.SC_OK );
194                final String jsonResult = convertToJson( result );
195                WebHelper.writeJsonToResponse( response, jsonResult );
196                return null;
197            }
198            else
199            {
200                response.setStatus( HttpServletResponse.SC_NO_CONTENT );
201                return null;
202            }
203        }
204        catch( Throwable e )
205        {
206            throw new WebException( e );
207        }
208    }
209
210    private void sendSerializedException( @NotNull final HttpServletResponse response, @NotNull final Throwable exception )
211            throws IOException
212    {
213        response.setStatus( WebHelper.STATUS_CODE_SERVICE_EXCEPTION );
214
215        if( exception.getCause().equals( WebException.getExceptionThrowable() ) )
216            WebHelper.writeJsonToResponse( response, exception.getLocalizedMessage() );
217        else
218            WebHelper.writeJsonToResponse( response, _jsonHelper.toJSONObject( exception ).toString() );
219    }
220
221    @NotNull
222    private String convertToJson( @Nullable final Object object )
223    {
224        if( null == object )
225            return JSONNull.getInstance().toString();
226        if( object instanceof JSON )
227            return object.toString();
228        if( object instanceof Collection )
229            return _jsonHelper.toJSON( (Collection) object ).toString();
230        if( object.getClass().isArray() )
231            return _jsonHelper.toJSON( object ).toString();
232        if( object instanceof Number || object instanceof Boolean || object instanceof String )
233            return JSONUtils.valueToString( object );
234        return _jsonHelper.toJSON( object ).toString();
235    }
236
237    @NotNull
238    private Object[] buildParams( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request )
239            throws InvalidParameterException
240    {
241        final List<Object> params = new ArrayList<Object>();
242        for( final ParamDescription paramDescription : methodDescription.getParams() )
243        {
244            if( null == paramDescription )
245            {
246                params.add( null );
247                continue;
248            }
249            final boolean canBeNull = !paramDescription.isPrimitive() && !paramDescription.isMandatory();
250            final String paramValue = WebHelper.getRequestParameter( request, paramDescription.getName(), null, canBeNull );
251            final boolean useJSON = paramDescription.isUsingJSON();
252            params.add( convertParameter( paramDescription.getType(), paramValue, useJSON ) );
253        }
254        return params.toArray( new Object[params.size()] );
255    }
256
257    @Nullable
258    private Object convertParameter( @NotNull final Class paramType, @Nullable final String paramValue, final boolean useJSON )
259    {
260        if( null == paramValue )
261            return null;
262        if( useJSON )
263            return _jsonHelper.fromJSON( _jsonHelper.toJSON( paramValue ), paramType );
264        if( JSONObject.class.equals( paramType ) )
265            return _jsonHelper.toJSON( paramValue );
266        if( JSONArray.class.equals( paramType ) )
267            return _jsonHelper.toJSON( paramValue );
268        if( String.class.equals( paramType ) )
269            return paramValue;
270        if( Boolean.TYPE.equals( paramType ) || Boolean.class.equals( paramType ) )
271            return Boolean.valueOf( paramValue );
272        if( Integer.TYPE.equals( paramType ) || Integer.class.equals( paramType ) )
273            return Integer.valueOf( paramValue );
274        if( Long.TYPE.equals( paramType ) || Long.class.equals( paramType ) )
275            return Long.valueOf( paramValue );
276        if( Float.TYPE.equals( paramType ) || Float.class.equals( paramType ) )
277            return Float.valueOf( paramValue );
278        if( Double.TYPE.equals( paramType ) || Double.class.equals( paramType ) )
279            return Double.valueOf( paramValue );
280        if( Date.class.isAssignableFrom( paramType ) )
281            return new Date( Long.valueOf( paramValue ) );
282        if( paramType.isEnum() )
283            return Enum.valueOf( paramType, paramValue );
284        if( Map.class.isAssignableFrom( paramType ) )
285            return JSONObject.fromObject( paramValue );
286
287        throw new UnsupportedOperationException( "Unsupported: cast parameter to " + paramType.getName() );
288    }
289
290    private void initialize()
291            throws WebException
292    {
293        for( final Method method : getClass().getMethods() )
294        {
295            final ControllerMethod annotation = method.getAnnotation( ControllerMethod.class );
296            if( null != annotation )
297            {
298                final MethodDescription methodDescription = new MethodDescription( method, annotation );
299                fillMethodDescription( method, methodDescription );
300                _methods.put( method.getName(), methodDescription );
301            }
302        }
303
304        _initialized = true;
305    }
306
307    private void fillMethodDescription( @NotNull final Method method, @NotNull final MethodDescription methodDescription )
308            throws WebException
309    {
310        final Class<?>[] paramTypes = method.getParameterTypes();
311        final Annotation[][] paramAnnotations = method.getParameterAnnotations();
312
313        if( paramTypes.length != paramAnnotations.length )
314            throw new WebException( WebException.WebCode.ERROR_NUMBER_OF_PARAM_TYPES_NOT_EQUAL_TO_PARAM_ANNOTATIONS, paramTypes.length + " " + paramAnnotations.length );
315
316        for( int i = 0; i < paramTypes.length; ++i )
317        {
318            ParamName paramNameAnnotation = null;
319            Mandatory mandatoryAnnotation = null;
320            UseJSON useJSONAnnotation = null;
321            for( final Annotation paramAnnotation : paramAnnotations[i] )
322            {
323                if( paramAnnotation instanceof ParamName )
324                    paramNameAnnotation = (ParamName) paramAnnotation;
325                if( paramAnnotation instanceof Mandatory )
326                    mandatoryAnnotation = (Mandatory) paramAnnotation;
327                if( paramAnnotation instanceof UseJSON )
328                    useJSONAnnotation = (UseJSON) paramAnnotation;
329            }
330            if( null == paramNameAnnotation )
331                methodDescription.addNullParam();
332            else
333            {
334                final boolean mandatory = ( null != mandatoryAnnotation );
335                final boolean useJSON = ( null != useJSONAnnotation );
336                methodDescription.addParam( paramNameAnnotation.value(), paramTypes[i], mandatory, useJSON );
337            }
338        }
339    }
340
341    @Required
342    public void setMethodNameResolver( final MethodNameResolver methodNameResolver )
343    {
344        _methodNameResolver = methodNameResolver;
345    }
346
347    protected JSONHelper getJsonHelper()
348    {
349        return _jsonHelper;
350    }
351
352    @Required
353    public void setJsonHelper( final JSONHelper jsonHelper )
354    {
355        _jsonHelper = jsonHelper;
356    }
357
358    protected Map<String, MethodDescription> getMethods()
359    {
360        return _methods;
361    }
362
363    @Required
364    public void setTapasService( @NotNull final TapasService tapasService )
365    {
366        _tapasService = tapasService;
367    }
368
369    public TapasService getTapasService()
370    {
371        return _tapasService;
372    }
373
374    private static final Log LOGGER = LogFactory.getLog( ControllerEther.class );
375
376    private JSONHelper _jsonHelper;
377    private MethodNameResolver _methodNameResolver;
378    private Map<String, MethodDescription> _methods = new HashMap<String, MethodDescription>();
379    private boolean _initialized; /*=false*/
380
381    private TapasService _tapasService;
382}
Note: See TracBrowser for help on using the repository browser.