package org.appfuse.webapp.services; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ValueEncoder; import org.apache.tapestry5.annotations.Path; import org.apache.tapestry5.ioc.MappedConfiguration; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.ioc.ServiceBinder; import org.apache.tapestry5.ioc.annotations.Contribute; import org.apache.tapestry5.ioc.annotations.ImportModule; import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.services.*; import org.apache.tapestry5.services.javascript.JavaScriptModuleConfiguration; import org.apache.tapestry5.services.javascript.ModuleManager; import org.apache.tapestry5.upload.services.UploadSymbols; import org.appfuse.model.Role; import org.appfuse.model.User; import org.appfuse.service.RoleManager; import org.appfuse.service.UserManager; import org.appfuse.webapp.AppFuseSymbolConstants; import org.appfuse.webapp.data.FileData; import org.appfuse.webapp.modules.EnableJQueryModule; import org.appfuse.webapp.services.impl.*; import org.slf4j.Logger; import java.io.IOException; /** * Application global configurations * * @author Serge Eby * @version $Id: AppModule.java 5 2008-08-30 09:59:21Z serge.eby $ */ @ImportModule({EnableJQueryModule.class}) public class AppModule { public static void bind(ServiceBinder binder) { binder.bind(SecurityContext.class, SpringSecurityContext.class); binder.bind(CountryService.class, CountryServiceImpl.class); binder.bind(EmailService.class, EmailServiceImpl.class); } public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) { configuration.add(SymbolConstants.SUPPORTED_LOCALES, "de,en,es,fr,it,ko,nl,no,pt_BR,pt,tr,zh_CN,zh_TW,en_US"); // Turn off GZip Compression since it causes issues with SiteMesh configuration.add(SymbolConstants.GZIP_COMPRESSION_ENABLED, "false"); // The factory default is true but during the early stages of an application // overriding to false is a good idea. In addition, this is often overridden // on the command line as -Dtapestry.production-mode=false configuration.add(SymbolConstants.PRODUCTION_MODE, "false"); // Maximum upload size is 2MB (size is in bytes) configuration.add(UploadSymbols.FILESIZE_MAX, "2048000"); // HHAC recommended for better security as of Tapestry 5.3.6 configuration.add(SymbolConstants.HMAC_PASSPHRASE, "AppFuse Tapestry is Great"); // Workaround for Bootstrap buttons tied together // See thread on SO here: http://stackoverflow.com/questions/9689584/buttons-run-together-in-bootstrap-2-0-1 // Commented out as this break the unit tests // configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false"); // Spring Security configuration.add(AppFuseSymbolConstants.SECURITY_URL, "/j_security_check"); // Combine JS configuration.add(SymbolConstants.COMBINE_SCRIPTS, "true"); } @Contribute(ValueEncoderSource.class) public static void provideEncoders( MappedConfiguration<Class, ValueEncoderFactory> configuration, UserManager userManager, RoleManager roleManager) { contributeEncoder(configuration, User.class, new UserEncoder(userManager)); contributeEncoder(configuration, Role.class, new RoleEncoder(roleManager)); contributeEncoder(configuration, FileData.class, new FileDataEncoder()); } private static <T> void contributeEncoder(MappedConfiguration<Class, ValueEncoderFactory> configuration, Class<T> clazz, final ValueEncoder<T> encoder) { ValueEncoderFactory<T> factory = new ValueEncoderFactory<T>() { public ValueEncoder<T> create(Class<T> clazz) { return encoder; } }; configuration.add(clazz, factory); } /** * Decorate Error page * * @param logger * @param renderer * @param componentSource * @param productionMode * @param service * @return */ public RequestExceptionHandler decorateRequestExceptionHandler( final Logger logger, final ResponseRenderer renderer, final ComponentSource componentSource, @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode, Object service) { if (!productionMode) { return null; } return new RequestExceptionHandler() { public void handleRequestException(Throwable exception) throws IOException { logger.error("Unexpected runtime exception: " + exception.getMessage(), exception); ExceptionReporter error = (ExceptionReporter) componentSource.getPage("Error"); error.reportException(exception); renderer.renderPageMarkupResponse("Error"); } }; } public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration) { configuration.add("webjars", "META-INF/resources/webjars"); configuration.add("modules", "META-INF/modules"); } @Contribute(ModuleManager.class) public static void setupModule(MappedConfiguration<String, Object> configuration, @Path("META-INF/modules/app/login.js") Resource appLogin) { configuration.add("app/login", new JavaScriptModuleConfiguration(appLogin) .dependsOn("jquery").dependsOn("t5/core/console")); } }