/** * Copyright 2010 Marko Lavikainen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package net.contextfw.web.application; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import net.contextfw.web.application.component.Component; import net.contextfw.web.application.component.ComponentRegister; import net.contextfw.web.application.configuration.BindableProperty; import net.contextfw.web.application.configuration.Configuration; import net.contextfw.web.application.development.DevelopmentTools; import net.contextfw.web.application.internal.WebApplicationServletModule; import net.contextfw.web.application.internal.component.AutoRegisterListener; import net.contextfw.web.application.internal.component.InternalComponentRegister; import net.contextfw.web.application.internal.configuration.KeyValue; import net.contextfw.web.application.internal.development.DevelopmentToolsImpl; import net.contextfw.web.application.internal.development.InternalDevelopmentTools; import net.contextfw.web.application.internal.page.PageScope; import net.contextfw.web.application.internal.service.DirectoryWatcher; import net.contextfw.web.application.internal.service.WebApplicationConf; import net.contextfw.web.application.internal.util.AttributeHandler; import net.contextfw.web.application.internal.util.ObjectAttributeSerializer; import net.contextfw.web.application.lifecycle.LifecycleListener; import net.contextfw.web.application.lifecycle.PageScoped; import net.contextfw.web.application.lifecycle.RequestInvocationFilter; import net.contextfw.web.application.scope.WebApplicationStorage; import net.contextfw.web.application.serialize.AttributeJsonSerializer; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializer; import com.google.gson.JsonSerializer; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.TypeLiteral; import com.google.inject.matcher.Matchers; import com.google.inject.spi.TypeEncounter; import com.google.inject.spi.TypeListener; public final class WebApplicationModule extends AbstractModule { private final Configuration configuration; @SuppressWarnings("rawtypes") private AutoRegisterListener autoRegisterListener = new AutoRegisterListener(); private DevelopmentToolsImpl developmentTools; public WebApplicationModule(Configuration configuration) { this.configuration = configuration; } @SuppressWarnings("unchecked") private <T> void bind(Class<T> type, BindableProperty<T> property) { Object obj = configuration.get(property); if (obj instanceof Class<?>) { bind(type).to((Class<T>) obj); } else { bind(type).toInstance((T) obj); requestInjection(obj); } } @Override protected void configure() { handleDevelopmentTools(); bind(WebApplicationStorage.class, Configuration.WEB_APPLICATION_STORAGE); bind(LifecycleListener.class, Configuration.LIFECYCLE_LISTENER); PageScope pageScope = new PageScope(); requestInjection(pageScope); bindScope(PageScoped.class, pageScope); bind(PageScope.class).toInstance(pageScope); bind(PageContext.class).toProvider(pageScope.scope(Key.get(PageContext.class), null)); bind(PageHandle.class).toProvider(pageScope.scope(Key.get(PageHandle.class), null)); bind(ObjectAttributeSerializer.class).to(AttributeHandler.class); bind(Configuration.class).toInstance(configuration); bind(ComponentRegister.class).to(InternalComponentRegister.class); bind(PropertyProvider.class).toInstance(configuration.get(Configuration.PROPERTY_PROVIDER)); bind(RequestInvocationFilter.class).toInstance(configuration.get(Configuration.REQUEST_INVOCATION_FILTER)); this.bindListener(Matchers.any(), new TypeListener() { @SuppressWarnings("unchecked") @Override public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) { if (Component.class.isAssignableFrom(typeLiteral .getRawType())) { typeEncounter.register(autoRegisterListener); } } }); requestInjection(this); requestInjection(autoRegisterListener); WebApplicationServletModule servletModule = new WebApplicationServletModule(configuration, configuration.get(Configuration.PROPERTY_PROVIDER), pageScope, developmentTools); install(servletModule); } @Singleton @Provides public Gson provideGson(Injector injector) { GsonBuilder builder = new GsonBuilder(); for (KeyValue<Class<?>, Class<? extends JsonSerializer<?>>> entry : configuration .get(Configuration.JSON_SERIALIZER)) { builder.registerTypeAdapter(entry.getKey(), injector.getInstance(entry.getValue())); } for (KeyValue<Class<?>, Class<? extends JsonDeserializer<?>>> entry : configuration .get(Configuration.JSON_DESERIALIZER)) { builder.registerTypeAdapter(entry.getKey(), injector.getInstance(entry.getValue())); } for (KeyValue<Class<?>, Class<? extends AttributeJsonSerializer<?>>> entry : configuration .get(Configuration.ATTRIBUTE_JSON_SERIALIZER)) { builder.registerTypeAdapter(entry.getKey(), injector.getInstance(entry.getValue())); } return builder.create(); } @Provides @Singleton public DirectoryWatcher resourceDirectoryWatcher() { List<String> paths = null; if (configuration.get(Configuration.DEVELOPMENT_MODE)) { paths = new ArrayList<String>(); paths.addAll(configuration.get(Configuration.RESOURCE_PATH)); } Pattern matcher = Pattern.compile(".+\\.(xsl|css|js|properties)", Pattern.CASE_INSENSITIVE); if (!configuration.get(Configuration.CLASS_RELOADING_ENABLED)) { matcher = Pattern.compile(".+\\.(xsl|css|js|class|properties)", Pattern.CASE_INSENSITIVE); } return new DirectoryWatcher(paths, matcher); } @Provides @Singleton public WebApplicationConf provideWebApplicationConf() { return new WebApplicationConf( configuration.get(Configuration.DEVELOPMENT_MODE), configuration.get(Configuration.XML_PARAM_NAME), configuration.get(Configuration.NAMESPACE)); } private void handleDevelopmentTools() { developmentTools = new DevelopmentToolsImpl(configuration); } @Provides @Singleton public DevelopmentTools provideDevelopmentTools() { return developmentTools; } @Provides @Singleton public InternalDevelopmentTools provideInternalDevelopmentTools() { return developmentTools; } }