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

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

getMessage récup du texte ds messages.properties

File size: 15.5 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.BufferedInputStream;
26import java.io.File;
27import java.io.FileInputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.OutputStream;
31import java.io.UnsupportedEncodingException;
32import java.lang.annotation.Annotation;
33import java.lang.reflect.Method;
34import java.security.InvalidParameterException;
35import java.util.ArrayList;
36import java.util.Collection;
37import java.util.Date;
38import java.util.HashMap;
39import java.util.List;
40import java.util.Map;
41
42public class ControllerEther
43        extends AbstractController
44{
45    /**
46     * This method is used to change Locale with the framework Spring
47     *
48     * @throws WebException
49     */
50    @ControllerMethod()
51    public void setLocale()
52            throws WebException
53    {
54    }
55
56    /**
57     * This method returns a property writed in the properties file
58     *
59     * @return
60     * @throws WebException
61     */
62    public String getProperty( @NotNull final String property )
63            throws WebException
64    {
65        try
66        {
67            final String webInfPath = getServletContext().getRealPath( "WEB-INF" );
68            return WebHelper.getProperty( webInfPath + "/classes/", WebHelper.PROPERTIES_FILE, property );
69        }
70        catch( IOException e )
71        {
72            throw new WebException( WebException.WebCode.ERROR_TO_READ_FILE_PROPERTIES, e );
73        }
74    }
75
76    @Override
77    @Nullable
78    protected ModelAndView handleRequestInternal( @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
79            throws WebException
80    {
81        try
82        {
83            if( !_initialized )
84                initialize();
85
86            request.setCharacterEncoding( UTF8Charset.getEncoding() );
87
88            // Get method to call
89            final String methodName = _methodNameResolver.getHandlerMethodName( request );
90
91            final MethodDescription methodDescription = _methods.get( methodName );
92            if( null == methodDescription )
93            {
94                WebHelper.displayAjaxError( response, methodName );
95                if( LOGGER.isWarnEnabled() )
96                    LOGGER.warn( String.format( "Controller=%1$s Method=%2$s METHOD NOT FOUND", getClass().getSimpleName(), methodName ) );
97                return null;
98            }
99
100            return invokeMethod( methodDescription, request, response );
101        }
102        catch( UnsupportedEncodingException e )
103        {
104            throw new WebException( WebException.WebCode.ERROR_UNSUPPORTED_UTF8_ENCODING, e );
105        }
106        catch( NoSuchRequestHandlingMethodException e )
107        {
108            throw new WebException( WebException.WebCode.ERROR_NO_REQUEST_HANDLING_METHOD, e );
109        }
110    }
111
112    @Nullable
113    private ModelAndView invokeMethod( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response )
114            throws WebException
115    {
116        try
117        {
118            // Parse parameters
119            final Object[] params = buildParams( methodDescription, request );
120            final String defaultView = ( null != methodDescription.getDefaultView() && !"".equals( methodDescription.getDefaultView() ) ) ? methodDescription.getDefaultView() : methodDescription.getView();
121
122
123            if( methodDescription.isRequestMandatory() )
124                params[params.length - 1] = request; //params = parametre de la methode du Controller
125
126
127            if( methodDescription.isLoginMandatory() )
128            {
129                final User user = (User) request.getSession().getAttribute( "SES_USER" );
130                if( null == user )
131                    return new ModelAndView( defaultView, "errors", "login.error.unknown" );
132            }
133
134            if( methodDescription.isUserMandatory() )
135            {
136                final User user = (User) request.getSession().getAttribute( "SES_USER" );
137                if( null == user )
138                    return new ModelAndView( defaultView, "errors", "login.error.unknown" );
139                else
140                    params[params.length - 1] = user;
141            }
142
143            if( methodDescription.isBackofficeMethod() )
144            {
145                final User user = (User) request.getSession().getAttribute( "SES_USER" );
146                if( null == user )
147                {
148                    return new ModelAndView( defaultView, "errors", "login.error.unknown" );
149                }
150                else if( null != user && !user.isAccessToBO() )
151                {
152                    return new ModelAndView( defaultView, "errors", "login.error.bo.notAccepted" );
153                }
154            }
155
156            final Object result;
157            try
158            {
159                // Invoke method (go to controller)
160                result = methodDescription.getMethod().invoke( this, params );
161            }
162            catch( Throwable e )
163            {
164                sendSerializedException( response, e.getCause() );
165                return null;
166            }
167
168            // Return result
169            if( !methodDescription.getView().isEmpty() )
170            {
171                response.setStatus( HttpServletResponse.SC_OK );
172                if( result instanceof Map )
173                    return new ModelAndView( methodDescription.getView(), (Map) result );
174                else
175                    return new ModelAndView( methodDescription.getView(), "result", result );
176            }
177            else if( methodDescription.isJsonResult() )
178            {
179                response.setStatus( HttpServletResponse.SC_OK );
180                final String jsonResult = convertToJson( result );
181                WebHelper.writeJsonToResponse( response, jsonResult );
182                return null;
183            }
184            else if( null != methodDescription.getDownloadFile() && !"".equals( methodDescription.getDownloadFile() ) )
185            {
186                final String fileName = methodDescription.getDownloadFile();
187                final String downloadPath = getProperty( "downloadPath" );
188
189                response.setContentType( "multipart/zip" );
190                response.setHeader( "Content-Disposition", "attachment; filename=\"" + fileName.trim() + "\";" );
191
192                final File file = new File( downloadPath + fileName );
193                if( !file.exists() )
194                    throw new WebException( WebException.WebCode.ERROR_TO_DOWNLOAD_FILE, file.getPath() );
195
196                response.setContentLength( (int) file.length() );
197                try
198                {
199                    final OutputStream outputStream = response.getOutputStream();
200                    final FileInputStream fileInputStream = new FileInputStream( file );
201
202                    final BufferedInputStream bufferedInputStream = new BufferedInputStream( fileInputStream );
203                    final InputStream inputStream = new BufferedInputStream( bufferedInputStream );
204
205                    int count;
206                    final byte[] buf = new byte[4096];
207                    while( ( count = inputStream.read( buf ) ) > -1 )
208                        outputStream.write( buf, 0, count );
209                    inputStream.close();
210                    outputStream.close();
211                }
212                catch( Exception ex )
213                {
214                    throw new WebException( WebException.WebCode.ERROR_TO_DOWNLOAD_FILE, ex );
215                }
216                return null;
217            }
218            else
219            {
220                response.setStatus( HttpServletResponse.SC_NO_CONTENT );
221                return null;
222            }
223        }
224        catch( Throwable e )
225        {
226            throw new WebException( e );
227        }
228    }
229
230    private void sendSerializedException( @NotNull final HttpServletResponse response, @NotNull final Throwable exception )
231            throws IOException
232    {
233        response.setStatus( WebHelper.STATUS_CODE_SERVICE_EXCEPTION );
234
235        if( exception.getCause().equals( WebException.getExceptionThrowable() ) )
236            WebHelper.writeJsonToResponse( response, exception.getLocalizedMessage() );
237        else
238            WebHelper.writeJsonToResponse( response, _jsonHelper.toJSONObject( exception ).toString() );
239    }
240
241    @NotNull
242    private String convertToJson( @Nullable final Object object )
243    {
244        if( null == object )
245            return JSONNull.getInstance().toString();
246        if( object instanceof JSON )
247            return object.toString();
248        if( object instanceof Collection )
249            return _jsonHelper.toJSON( (Collection) object ).toString();
250        if( object.getClass().isArray() )
251            return _jsonHelper.toJSON( object ).toString();
252        if( object instanceof Number || object instanceof Boolean || object instanceof String )
253            return JSONUtils.valueToString( object );
254        return _jsonHelper.toJSON( object ).toString();
255    }
256
257    @NotNull
258    private Object[] buildParams( @NotNull final MethodDescription methodDescription, @NotNull final HttpServletRequest request )
259            throws InvalidParameterException
260    {
261        final List<Object> params = new ArrayList<Object>();
262        for( final ParamDescription paramDescription : methodDescription.getParams() )
263        {
264            if( null == paramDescription )
265            {
266                params.add( null );
267                continue;
268            }
269            final boolean canBeNull = !paramDescription.isPrimitive() && !paramDescription.isMandatory();
270            final String paramValue = WebHelper.getRequestParameter( request, paramDescription.getName(), null, canBeNull );
271            final boolean useJSON = paramDescription.isUsingJSON();
272            params.add( convertParameter( paramDescription.getType(), paramValue, useJSON ) );
273        }
274        return params.toArray( new Object[params.size()] );
275    }
276
277    @Nullable
278    private Object convertParameter( @NotNull final Class paramType, @Nullable final String paramValue, final boolean useJSON )
279    {
280        if( null == paramValue )
281            return null;
282        if( useJSON )
283            return _jsonHelper.fromJSON( _jsonHelper.toJSON( paramValue ), paramType );
284        if( JSONObject.class.equals( paramType ) )
285            return _jsonHelper.toJSON( paramValue );
286        if( JSONArray.class.equals( paramType ) )
287            return _jsonHelper.toJSON( paramValue );
288        if( String.class.equals( paramType ) )
289            return paramValue;
290        if( Boolean.TYPE.equals( paramType ) || Boolean.class.equals( paramType ) )
291            return Boolean.valueOf( paramValue );
292        if( Integer.TYPE.equals( paramType ) || Integer.class.equals( paramType ) )
293            return Integer.valueOf( paramValue );
294        if( Long.TYPE.equals( paramType ) || Long.class.equals( paramType ) )
295            return Long.valueOf( paramValue );
296        if( Float.TYPE.equals( paramType ) || Float.class.equals( paramType ) )
297            return Float.valueOf( paramValue );
298        if( Double.TYPE.equals( paramType ) || Double.class.equals( paramType ) )
299            return Double.valueOf( paramValue );
300        if( Date.class.isAssignableFrom( paramType ) )
301            return new Date( Long.valueOf( paramValue ) );
302        if( paramType.isEnum() )
303            return Enum.valueOf( paramType, paramValue );
304        if( Map.class.isAssignableFrom( paramType ) )
305            return JSONObject.fromObject( paramValue );
306
307        throw new UnsupportedOperationException( "Unsupported: cast parameter to " + paramType.getName() );
308    }
309
310    private void initialize()
311            throws WebException
312    {
313        for( final Method method : getClass().getMethods() )
314        {
315            final ControllerMethod annotation = method.getAnnotation( ControllerMethod.class );
316            if( null != annotation )
317            {
318                final MethodDescription methodDescription = new MethodDescription( method, annotation );
319                fillMethodDescription( method, methodDescription );
320                _methods.put( method.getName(), methodDescription );
321            }
322        }
323
324        _initialized = true;
325    }
326
327    private void fillMethodDescription( @NotNull final Method method, @NotNull final MethodDescription methodDescription )
328            throws WebException
329    {
330        final Class<?>[] paramTypes = method.getParameterTypes();
331        final Annotation[][] paramAnnotations = method.getParameterAnnotations();
332
333        if( paramTypes.length != paramAnnotations.length )
334            throw new WebException( WebException.WebCode.ERROR_NUMBER_OF_PARAM_TYPES_NOT_EQUAL_TO_PARAM_ANNOTATIONS, paramTypes.length + " " + paramAnnotations.length );
335
336        for( int i = 0; i < paramTypes.length; ++i )
337        {
338            ParamName paramNameAnnotation = null;
339            Mandatory mandatoryAnnotation = null;
340            UseJSON useJSONAnnotation = null;
341            for( final Annotation paramAnnotation : paramAnnotations[i] )
342            {
343                if( paramAnnotation instanceof ParamName )
344                    paramNameAnnotation = (ParamName) paramAnnotation;
345                if( paramAnnotation instanceof Mandatory )
346                    mandatoryAnnotation = (Mandatory) paramAnnotation;
347                if( paramAnnotation instanceof UseJSON )
348                    useJSONAnnotation = (UseJSON) paramAnnotation;
349            }
350            if( null == paramNameAnnotation )
351                methodDescription.addNullParam();
352            else
353            {
354                final boolean mandatory = ( null != mandatoryAnnotation );
355                final boolean useJSON = ( null != useJSONAnnotation );
356                methodDescription.addParam( paramNameAnnotation.value(), paramTypes[i], mandatory, useJSON );
357            }
358        }
359    }
360
361    @Required
362    public void setMethodNameResolver( final MethodNameResolver methodNameResolver )
363    {
364        _methodNameResolver = methodNameResolver;
365    }
366
367    protected JSONHelper getJsonHelper()
368    {
369        return _jsonHelper;
370    }
371
372    @Required
373    public void setJsonHelper( final JSONHelper jsonHelper )
374    {
375        _jsonHelper = jsonHelper;
376    }
377
378    protected Map<String, MethodDescription> getMethods()
379    {
380        return _methods;
381    }
382
383    @Required
384    public void setTapasService( @NotNull final TapasService tapasService )
385    {
386        _tapasService = tapasService;
387    }
388
389    public TapasService getTapasService()
390    {
391        return _tapasService;
392    }
393
394    private static final Log LOGGER = LogFactory.getLog( ControllerEther.class );
395
396    private JSONHelper _jsonHelper;
397    private MethodNameResolver _methodNameResolver;
398    private Map<String, MethodDescription> _methods = new HashMap<String, MethodDescription>();
399    private boolean _initialized; /*=false*/
400
401    private TapasService _tapasService;
402}
Note: See TracBrowser for help on using the repository browser.