001/** 002 * Copyright 2013 John Ericksen 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.androidtransfuse.config; 017 018import com.sun.codemodel.JCodeModel; 019import com.sun.codemodel.JDefinedClass; 020import org.androidtransfuse.CodeGenerationScope; 021import org.androidtransfuse.ConfigurationRepository; 022import org.androidtransfuse.ConfigurationScope; 023import org.androidtransfuse.TransfuseAnnotationProcessor; 024import org.androidtransfuse.adapter.ASTFactory; 025import org.androidtransfuse.adapter.ASTType; 026import org.androidtransfuse.analysis.ConfigurationRepositoryImpl; 027import org.androidtransfuse.analysis.module.ModuleRepository; 028import org.androidtransfuse.analysis.repository.InjectionNodeBuilderRepository; 029import org.androidtransfuse.analysis.repository.InjectionNodeBuilderRepositoryFactory; 030import org.androidtransfuse.analysis.repository.InjectionNodeBuilderRepositoryProvider; 031import org.androidtransfuse.annotations.*; 032import org.androidtransfuse.bootstrap.BootstrapModule; 033import org.androidtransfuse.bootstrap.Namespace; 034import org.androidtransfuse.gen.ClassGenerationStrategy; 035import org.androidtransfuse.gen.InjectionBuilderContextFactory; 036import org.androidtransfuse.gen.InstantiationStrategyFactory; 037import org.androidtransfuse.gen.invocationBuilder.DefaultInvocationBuilderStrategy; 038import org.androidtransfuse.gen.invocationBuilder.InvocationBuilderStrategy; 039import org.androidtransfuse.gen.variableDecorator.ExpressionDecoratorFactory; 040import org.androidtransfuse.gen.variableDecorator.VariableExpressionBuilder; 041import org.androidtransfuse.gen.variableDecorator.VariableExpressionBuilderFactory; 042import org.androidtransfuse.model.manifest.Manifest; 043import org.androidtransfuse.model.r.RResource; 044import org.androidtransfuse.processor.*; 045import org.androidtransfuse.transaction.ScopedTransactionBuilder; 046import org.androidtransfuse.transaction.TransactionProcessor; 047import org.androidtransfuse.transaction.TransactionProcessorChannel; 048import org.androidtransfuse.transaction.TransactionProcessorPool; 049import org.androidtransfuse.util.Generated; 050import org.androidtransfuse.util.Logger; 051import org.androidtransfuse.util.ManifestLocator; 052import org.androidtransfuse.util.MessagerLogger; 053import org.androidtransfuse.validation.Validator; 054 055import javax.annotation.processing.Filer; 056import javax.annotation.processing.Messager; 057import javax.annotation.processing.ProcessingEnvironment; 058import javax.inject.Named; 059import javax.inject.Provider; 060import javax.inject.Singleton; 061import javax.lang.model.util.Elements; 062import javax.xml.bind.JAXBContext; 063import java.io.File; 064import java.util.Map; 065 066@BootstrapModule 067@DefineScopes({ 068 @DefineScope(annotation = CodeGenerationScope.class, scope = ThreadLocalScope.class), 069 @DefineScope(annotation = ConfigurationScope.class, scope = MapScope.class) 070}) 071@Bindings({ 072 @Bind(type = ModuleRepository.class, to = InjectionNodeBuilderRepositoryFactory.class), 073 @Bind(type = InvocationBuilderStrategy.class, to = DefaultInvocationBuilderStrategy.class) 074}) 075@BindProviders({ 076 @BindProvider(type = JAXBContext.class, provider = JAXBContextProvider.class), 077 @BindProvider(type = VariableExpressionBuilder.class, provider = ExpressionDecoratorFactory.class), 078 @BindProvider(type = GeneratorRepository.class, provider = GeneratorRepositoryProvider.class), 079 @BindProvider(type = InjectionNodeBuilderRepository.class, provider = InjectionNodeBuilderRepositoryProvider.class) 080}) 081@Install({ 082 ASTFactory.class, 083 InjectionNodeBuilderRepositoryFactory.class, 084 VariableExpressionBuilderFactory.class, 085 InjectionBuilderContextFactory.class, 086 InstantiationStrategyFactory.class}) 087@Namespace("Transfuse") 088public class TransfuseAndroidModule { 089 090 public static final String ORIGINAL_MANIFEST = "originalManifest"; 091 public static final String MANIFEST_FILE = "manifestFile"; 092 093 @Provides 094 @CodeGenerationScope 095 public Validator provideValidator(@Named(Validator.LOG_PREPEND) String prepend, Messager messager){ 096 return new Validator(prepend, messager); 097 } 098 099 @Provides 100 @Singleton 101 public ConfigurationRepository getRepository(ConfigurationRepositoryImpl repository){ 102 return repository; 103 } 104 105 @Provides 106 public ClassGenerationStrategy getClassGenerationStrategy(){ 107 return new ClassGenerationStrategy(Generated.class, TransfuseAnnotationProcessor.class.getName()); 108 } 109 110 @Provides 111 @CodeGenerationScope 112 public JCodeModel getJCodeModel(){ 113 return new JCodeModel(); 114 } 115 116 @Provides 117 @Singleton 118 public Elements getElements(ProcessingEnvironment processingEnvironment){ 119 return processingEnvironment.getElementUtils(); 120 } 121 122 @Provides 123 @Singleton 124 public Messager getMessenger(ProcessingEnvironment processingEnvironment){ 125 return processingEnvironment.getMessager(); 126 } 127 128 @Provides 129 @Singleton 130 public Logger getLogger(ProcessingEnvironment processingEnvironment){ 131 return new MessagerLogger(getLogPreprend(), processingEnvironment.getMessager()); 132 } 133 134 @Provides 135 @Named(Validator.LOG_PREPEND) 136 public String getLogPreprend(){ 137 return "Transfuse: "; 138 } 139 140 @Provides 141 @Singleton 142 public Filer getFiler(ProcessingEnvironment processingEnvironment){ 143 return new SynchronizedFiler(processingEnvironment.getFiler()); 144 } 145 146 @Provides 147 @Named(ManifestLocator.ANDROID_MANIFEST_FILE_OPTION) 148 public String getManifestFileLocation(ProcessingEnvironment processingEnvironment){ 149 return processingEnvironment.getOptions().get(ManifestLocator.ANDROID_MANIFEST_FILE_OPTION); 150 } 151 152 @Provides 153 @Named(GenerateModuleProcessor.MANIFEST_PROCESSING_OPTION) 154 public String getManifestProcessing(ProcessingEnvironment processingEnvironment){ 155 return processingEnvironment.getOptions().get(GenerateModuleProcessor.MANIFEST_PROCESSING_OPTION); 156 } 157 158 @Provides 159 @Singleton 160 public ProcessingEnvironment getProcessingEnvironment(){ 161 throw new OutOfScopeException("Expected seeded object, unable to construct directly."); 162 } 163 164 @Provides 165 @ConfigurationScope 166 public RResource getRResource(){ 167 throw new OutOfScopeException("Expected seeded object, unable to construct directly."); 168 } 169 170 @Provides 171 @ConfigurationScope 172 @Named(MANIFEST_FILE) 173 public File getManifestFile(){ 174 throw new OutOfScopeException("Expected seeded object, unable to construct directly."); 175 } 176 177 @Provides 178 @ConfigurationScope 179 @Named(ORIGINAL_MANIFEST) 180 public Manifest getManifest(){ 181 throw new OutOfScopeException("Expected seeded object, unable to construct directly."); 182 } 183 184 @Provides 185 public FactoryProcessor getFactoryProcessor(Provider<FactoryTransactionWorker> factoryTransactionWorkerProvider, 186 Provider<FactoriesTransactionWorker> factoriesTransactionWorkerProvider, 187 ScopedTransactionBuilder scopedTransactionBuilder) { 188 TransactionProcessorPool<Provider<ASTType>, JDefinedClass> factoryProcessor = 189 new TransactionProcessorPool<Provider<ASTType>, JDefinedClass>(); 190 TransactionProcessorPool<Map<Provider<ASTType>, JDefinedClass>, Void> factoriesProcessor = 191 new TransactionProcessorPool<Map<Provider<ASTType>, JDefinedClass>, Void>(); 192 193 TransactionProcessor processor = 194 new TransactionProcessorChannel<Provider<ASTType>, JDefinedClass, Void>( 195 factoryProcessor, 196 factoriesProcessor, 197 scopedTransactionBuilder.buildFactory(factoriesTransactionWorkerProvider)); 198 199 return new FactoryProcessor(processor, factoryProcessor, scopedTransactionBuilder.buildFactory(factoryTransactionWorkerProvider)); 200 } 201}