View Javadoc

1   package org.appfuse.webapp.services;
2   
3   import org.apache.tapestry5.SymbolConstants;
4   import org.apache.tapestry5.ValueEncoder;
5   import org.apache.tapestry5.annotations.Path;
6   import org.apache.tapestry5.ioc.MappedConfiguration;
7   import org.apache.tapestry5.ioc.Resource;
8   import org.apache.tapestry5.ioc.ServiceBinder;
9   import org.apache.tapestry5.ioc.annotations.Contribute;
10  import org.apache.tapestry5.ioc.annotations.ImportModule;
11  import org.apache.tapestry5.ioc.annotations.Symbol;
12  import org.apache.tapestry5.services.*;
13  import org.apache.tapestry5.services.javascript.JavaScriptModuleConfiguration;
14  import org.apache.tapestry5.services.javascript.ModuleManager;
15  import org.apache.tapestry5.upload.services.UploadSymbols;
16  import org.appfuse.model.Role;
17  import org.appfuse.model.User;
18  import org.appfuse.service.RoleManager;
19  import org.appfuse.service.UserManager;
20  import org.appfuse.webapp.AppFuseSymbolConstants;
21  import org.appfuse.webapp.data.FileData;
22  import org.appfuse.webapp.modules.EnableJQueryModule;
23  import org.appfuse.webapp.services.impl.*;
24  import org.slf4j.Logger;
25  
26  import java.io.IOException;
27  
28  
29  /**
30   * Application global configurations
31   *
32   * @author Serge Eby
33   * @version $Id: AppModule.java 5 2008-08-30 09:59:21Z serge.eby $
34   */
35  @ImportModule({EnableJQueryModule.class})
36  public class AppModule {
37  
38      public static void bind(ServiceBinder binder) {
39          binder.bind(SecurityContext.class, SpringSecurityContext.class);
40          binder.bind(CountryService.class, CountryServiceImpl.class);
41          binder.bind(EmailService.class, EmailServiceImpl.class);
42      }
43  
44      public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
45          configuration.add(SymbolConstants.SUPPORTED_LOCALES,
46              "de,en,es,fr,it,ko,nl,no,pt_BR,pt,tr,zh_CN,zh_TW,en_US");
47  
48          // Turn off GZip Compression since it causes issues with SiteMesh
49          configuration.add(SymbolConstants.GZIP_COMPRESSION_ENABLED, "false");
50  
51          // The factory default is true but during the early stages of an application
52          // overriding to false is a good idea. In addition, this is often overridden
53          // on the command line as -Dtapestry.production-mode=false
54          configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
55  
56          // Maximum upload size is 2MB (size is in bytes)
57          configuration.add(UploadSymbols.FILESIZE_MAX, "2048000");
58  
59          // HHAC recommended for better security as of Tapestry 5.3.6
60          configuration.add(SymbolConstants.HMAC_PASSPHRASE, "AppFuse Tapestry is Great");
61  
62          // Workaround for Bootstrap buttons tied together
63          // See thread on SO here: http://stackoverflow.com/questions/9689584/buttons-run-together-in-bootstrap-2-0-1
64          // Commented out as this break the unit tests
65          // configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false");
66  
67          // Spring Security
68          configuration.add(AppFuseSymbolConstants.SECURITY_URL, "/j_security_check");
69  
70          // Combine JS
71          configuration.add(SymbolConstants.COMBINE_SCRIPTS, "true");
72  
73      }
74  
75      @Contribute(ValueEncoderSource.class)
76      public static void provideEncoders(
77          MappedConfiguration<Class, ValueEncoderFactory> configuration,
78          UserManager userManager,
79          RoleManager roleManager) {
80  
81          contributeEncoder(configuration, User.class, new UserEncoder(userManager));
82          contributeEncoder(configuration, Role.class, new RoleEncoder(roleManager));
83          contributeEncoder(configuration, FileData.class, new FileDataEncoder());
84      }
85  
86      private static <T> void contributeEncoder(MappedConfiguration<Class, ValueEncoderFactory> configuration,
87                                                Class<T> clazz, final ValueEncoder<T> encoder) {
88  
89          ValueEncoderFactory<T> factory = new ValueEncoderFactory<T>() {
90  
91              public ValueEncoder<T> create(Class<T> clazz) {
92                  return encoder;
93              }
94          };
95  
96          configuration.add(clazz, factory);
97      }
98  
99  
100     /**
101      * Decorate Error page
102      *
103      * @param logger
104      * @param renderer
105      * @param componentSource
106      * @param productionMode
107      * @param service
108      * @return
109      */
110     public RequestExceptionHandler decorateRequestExceptionHandler(
111         final Logger logger, final ResponseRenderer renderer,
112         final ComponentSource componentSource,
113         @Symbol(SymbolConstants.PRODUCTION_MODE)
114         boolean productionMode,
115         Object service) {
116 
117         if (!productionMode) {
118             return null;
119         }
120 
121         return new RequestExceptionHandler() {
122             public void handleRequestException(Throwable exception) throws IOException {
123                 logger.error("Unexpected runtime exception: " + exception.getMessage(), exception);
124                 ExceptionReporter error = (ExceptionReporter) componentSource.getPage("Error");
125                 error.reportException(exception);
126                 renderer.renderPageMarkupResponse("Error");
127             }
128         };
129     }
130 
131     public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration) {
132         configuration.add("webjars", "META-INF/resources/webjars");
133         configuration.add("modules", "META-INF/modules");
134     }
135 
136     @Contribute(ModuleManager.class)
137     public static void setupModule(MappedConfiguration<String, Object> configuration,
138                                    @Path("META-INF/modules/app/login.js") Resource appLogin) {
139         configuration.add("app/login", new JavaScriptModuleConfiguration(appLogin)
140             .dependsOn("jquery").dependsOn("t5/core/console"));
141     }
142 }