/** * Copyright 2011-2015 John Ericksen * * 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 org.androidtransfuse.config; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; import org.androidtransfuse.CodeGenerationScope; import org.androidtransfuse.ConfigurationRepository; import org.androidtransfuse.ConfigurationScope; import org.androidtransfuse.TransfuseAnnotationProcessor; import org.androidtransfuse.adapter.ASTFactory; import org.androidtransfuse.adapter.ASTPrimitiveType; import org.androidtransfuse.adapter.ASTType; import org.androidtransfuse.adapter.classes.ASTClassFactory; import org.androidtransfuse.analysis.ConfigurationRepositoryImpl; import org.androidtransfuse.analysis.module.ModuleRepository; import org.androidtransfuse.analysis.repository.*; import org.androidtransfuse.annotations.*; import org.androidtransfuse.bootstrap.BootstrapModule; import org.androidtransfuse.bootstrap.Namespace; import org.androidtransfuse.gen.ClassGenerationStrategy; import org.androidtransfuse.gen.InjectionBuilderContextFactory; import org.androidtransfuse.gen.InstantiationStrategyFactory; import org.androidtransfuse.gen.invocationBuilder.DefaultInvocationBuilderStrategy; import org.androidtransfuse.gen.invocationBuilder.InvocationBuilderStrategy; import org.androidtransfuse.gen.variableDecorator.ExpressionDecoratorFactory; import org.androidtransfuse.gen.variableDecorator.VariableExpressionBuilder; import org.androidtransfuse.gen.variableDecorator.VariableExpressionBuilderFactory; import org.androidtransfuse.model.manifest.Manifest; import org.androidtransfuse.model.r.RResource; import org.androidtransfuse.processor.*; import org.androidtransfuse.transaction.ScopedTransactionBuilder; import org.androidtransfuse.transaction.TransactionProcessor; import org.androidtransfuse.transaction.TransactionProcessorChannel; import org.androidtransfuse.transaction.TransactionProcessorPool; import org.androidtransfuse.util.*; import org.androidtransfuse.util.matcher.InheritsMatcher; import org.androidtransfuse.util.matcher.Matchers; import org.androidtransfuse.validation.Validator; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import javax.lang.model.util.Elements; import javax.xml.bind.JAXBContext; import java.io.File; import java.io.Serializable; import java.util.Map; @BootstrapModule @DefineScopes({ @DefineScope(annotation = CodeGenerationScope.class, scope = ThreadLocalScope.class), @DefineScope(annotation = ConfigurationScope.class, scope = MapScope.class) }) @Bindings({ @Bind(type = ModuleRepository.class, to = InjectionNodeBuilderRepositoryFactory.class), @Bind(type = InvocationBuilderStrategy.class, to = DefaultInvocationBuilderStrategy.class) }) @BindProviders({ @BindProvider(type = JAXBContext.class, provider = JAXBContextProvider.class), @BindProvider(type = VariableExpressionBuilder.class, provider = ExpressionDecoratorFactory.class), @BindProvider(type = GeneratorRepository.class, provider = GeneratorRepositoryProvider.class), @BindProvider(type = InjectionNodeBuilderRepository.class, provider = InjectionNodeBuilderRepositoryProvider.class) }) @Install({ ASTFactory.class, InjectionNodeBuilderRepositoryFactory.class, VariableExpressionBuilderFactory.class, InjectionBuilderContextFactory.class, InstantiationStrategyFactory.class}) @Namespace("Transfuse") public class TransfuseAndroidModule { public static final String ORIGINAL_MANIFEST = "originalManifest"; public static final String MANIFEST_FILE = "manifestFile"; public static final String STACKTRACE = "transfuseStacktrace"; public static final String DEBUG = "transfuseDebugLogging"; @Provides @CodeGenerationScope public Validator provideValidator(@Named(Validator.LOG_PREPEND) String prepend, Messager messager){ return new Validator(prepend, messager); } @Provides @Singleton public ConfigurationRepository getRepository(ConfigurationRepositoryImpl repository){ return repository; } @Provides public ClassGenerationStrategy getClassGenerationStrategy(){ return new ClassGenerationStrategy(Generated.class, TransfuseAnnotationProcessor.class.getName()); } @Provides @CodeGenerationScope public JCodeModel getJCodeModel(){ return new JCodeModel(); } @Provides @Singleton public Elements getElements(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getElementUtils(); } @Provides @Singleton public Messager getMessenger(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getMessager(); } @Provides @Singleton public Logger getLogger(ProcessingEnvironment processingEnvironment, @Named(DEBUG) boolean debug){ return new MessagerLogger(getLogPrepend(), processingEnvironment.getMessager(), debug); } @Provides @Named(Validator.LOG_PREPEND) public String getLogPrepend(){ return "Transfuse: "; } @Provides @Singleton public Filer getFiler(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getFiler(); } @Provides @Named(ManifestLocator.ANDROID_MANIFEST_FILE_OPTION) public String getManifestFileLocation(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getOptions().get(ManifestLocator.ANDROID_MANIFEST_FILE_OPTION); } @Provides @Named(STACKTRACE) public boolean getStacktraceParameter(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getOptions().containsKey(STACKTRACE); } @Provides @Named(GenerateModuleProcessor.MANIFEST_PROCESSING_OPTION) public String getManifestProcessing(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getOptions().get(GenerateModuleProcessor.MANIFEST_PROCESSING_OPTION); } @Provides @Named(DEBUG) public boolean getDebugOption(ProcessingEnvironment processingEnvironment){ return processingEnvironment.getOptions().containsKey(DEBUG); } @Provides @Singleton public ProcessingEnvironment getProcessingEnvironment(){ throw new OutOfScopeException("Expected seeded object, unable to construct directly."); } @Provides @ConfigurationScope public RResource getRResource(){ throw new OutOfScopeException("Expected seeded object, unable to construct directly."); } @Provides @ConfigurationScope @Named(MANIFEST_FILE) public File getManifestFile(){ throw new OutOfScopeException("Expected seeded object, unable to construct directly."); } @Provides @ConfigurationScope @Named(ORIGINAL_MANIFEST) public Manifest getManifest(){ throw new OutOfScopeException("Expected seeded object, unable to construct directly."); } @Provides public FactoryProcessor getFactoryProcessor(Provider<FactoryTransactionWorker> factoryTransactionWorkerProvider, Provider<FactoriesTransactionWorker> factoriesTransactionWorkerProvider, ScopedTransactionBuilder scopedTransactionBuilder) { TransactionProcessorPool<Provider<ASTType>, JDefinedClass> factoryProcessor = new TransactionProcessorPool<Provider<ASTType>, JDefinedClass>(); TransactionProcessorPool<Map<Provider<ASTType>, JDefinedClass>, Void> factoriesProcessor = new TransactionProcessorPool<Map<Provider<ASTType>, JDefinedClass>, Void>(); TransactionProcessor processor = new TransactionProcessorChannel<Provider<ASTType>, JDefinedClass, Void>( factoryProcessor, factoriesProcessor, scopedTransactionBuilder.buildFactory(factoriesTransactionWorkerProvider)); return new FactoryProcessor(processor, factoryProcessor, scopedTransactionBuilder.buildFactory(factoryTransactionWorkerProvider)); } @Provides @Singleton public BundlePropertyBuilderRepository getBundlePropertyRepository(ASTClassFactory astClassFactory, ParcelerPropertyBuilder parcelerPropertyBuilder){ BundlePropertyBuilderRepository repository = new BundlePropertyBuilderRepository(); for (ASTPrimitiveType astPrimitiveType : ASTPrimitiveType.values()) { String upperFirst = StringUtil.upperFirst(astPrimitiveType.getName()); String getter = "get" + upperFirst; String setter = "put" + upperFirst; repository.add(Matchers.type(astPrimitiveType).build(), new SimplePropertyBuilder(getter, setter)); repository.add(Matchers.type(astClassFactory.getType(astPrimitiveType.getObjectClass())).build(), new SimplePropertyBuilder(getter, setter)); } repository.add(Matchers.type(astClassFactory.getType(String.class)).build(), new SimplePropertyBuilder("getString", "putString")); repository.add(new InheritsMatcher(AndroidLiterals.PARCELABLE), new SimplePropertyBuilder("getParcelable", "putParcelable")); repository.add(new ParcelMatcher(), parcelerPropertyBuilder); repository.add(new InheritsMatcher(astClassFactory.getType(Serializable.class)), new SimplePropertyBuilder("getSerializable", "putSerializable")); return repository; } }