View Javadoc

1   package org.appfuse.webapp.server;
2   
3   import java.lang.reflect.Method;
4   
5   import javax.servlet.http.HttpServletResponse;
6   
7   import org.springframework.context.ApplicationContext;
8   import org.springframework.security.access.AccessDeniedException;
9   import org.springframework.security.core.AuthenticationException;
10  import org.springframework.web.context.support.WebApplicationContextUtils;
11  
12  import com.google.web.bindery.requestfactory.server.DefaultExceptionHandler;
13  import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;
14  import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator;
15  import com.google.web.bindery.requestfactory.server.impl.FindService;
16  import com.google.web.bindery.requestfactory.shared.Locator;
17  import com.google.web.bindery.requestfactory.shared.ServerFailure;
18  
19  public class CustomRequestFactoryServlet extends RequestFactoryServlet {
20  
21      private static final long serialVersionUID = -4245826401547466758L;
22  
23      public CustomRequestFactoryServlet() {
24          super(new CustomExceptionHandler(), new ServiceLayerDecorator() {
25  
26              @Override
27              public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
28                  ApplicationContext context = WebApplicationContextUtils
29                          .getWebApplicationContext(CustomRequestFactoryServlet.getThreadLocalServletContext());
30                  return context.getBean(clazz);
31              }
32  
33              @Override
34              public Object invoke(Method domainMethod, Object... args) {
35                  if (FindService.class.equals(domainMethod.getDeclaringClass())) {
36                      // Entities should only be accessed through secured
37                      // RequestService methods (do not use find)
38                      throw new AccessDeniedException("Access is disabled through FindService.find() method");
39                      // FIXME this exception is not gracefully handled by
40                      // CustomExceptionHandler, but at least we are safer
41                  }
42                  return super.invoke(domainMethod, args);
43              }
44          });
45      }
46  
47      /**
48  	 * 
49  	 *
50  	 */
51      private static class CustomExceptionHandler extends DefaultExceptionHandler {
52          /**
53           * 
54           * @see com.google.web.bindery.requestfactory.server.DefaultExceptionHandler#createServerFailure(java.lang.Throwable)
55           */
56          @Override
57          public ServerFailure createServerFailure(Throwable throwable) {
58              try {
59                  return createCustomServerFailure(throwable);
60              } catch (Exception e) {
61                  return super.createServerFailure(throwable);
62              }
63          }
64  
65          /**
66           * 
67           * @param throwable
68           * @return
69           * @throws Exception
70           */
71          private ServerFailure createCustomServerFailure(Throwable throwable) throws Exception {
72              if (throwable instanceof AuthenticationException) {
73                  getServletResponse().sendError(HttpServletResponse.SC_UNAUTHORIZED);
74                  return null;
75              }
76              if (throwable instanceof AccessDeniedException) {
77                  if (!RequestFactoryServlet.getThreadLocalRequest().isRequestedSessionIdValid()) {
78                      // if session has expired send a 401 error code instead of
79                      // 403
80                      getServletResponse().sendError(HttpServletResponse.SC_UNAUTHORIZED);
81                      return null;
82                  }
83                  getServletResponse().sendError(HttpServletResponse.SC_FORBIDDEN);
84                  return null;
85              }
86              return super.createServerFailure(throwable);
87          }
88  
89          private HttpServletResponse getServletResponse() {
90              return RequestFactoryServlet.getThreadLocalResponse();
91          }
92      }
93  }