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.analysis.astAnalyzer; 017 018import com.google.common.collect.ImmutableList; 019import com.google.common.collect.ImmutableMap; 020import org.androidtransfuse.adapter.*; 021import org.androidtransfuse.analysis.AnalysisContext; 022import org.androidtransfuse.analysis.repository.RegistrationGeneratorFactory; 023import org.androidtransfuse.annotations.RegisterListener; 024import org.androidtransfuse.gen.componentBuilder.RegistrationGenerator; 025import org.androidtransfuse.model.InjectionNode; 026 027import java.util.ArrayList; 028import java.util.Arrays; 029import java.util.List; 030import java.util.Map; 031 032/** 033 * @author John Ericksen 034 */ 035public class RegistrationAnalyzer implements ASTAnalysis { 036 037 private ImmutableMap<ASTType, RegistrationGeneratorFactory> generatorFactories; 038 039 public RegistrationAnalyzer(ImmutableMap<ASTType, RegistrationGeneratorFactory> generatorFactories) { 040 this.generatorFactories = generatorFactories; 041 } 042 043 @Override 044 public void analyzeType(InjectionNode injectionNode, final ASTType astType, AnalysisContext context) { 045 analyze(astType, astType, injectionNode, context); 046 } 047 048 @Override 049 public void analyzeMethod(InjectionNode injectionNode, ASTType concreteType, final ASTMethod astMethod, AnalysisContext context) { 050 analyze(astMethod, astMethod.getReturnType(), injectionNode, context); 051 } 052 053 @Override 054 public void analyzeField(InjectionNode injectionNode, ASTType concreteType, final ASTField astField, AnalysisContext context) { 055 analyze(astField, astField.getASTType(), injectionNode, context); 056 } 057 058 private <T> void analyze(ASTBase astBase, ASTType astType, InjectionNode injectionNode, AnalysisContext context) { 059 if (astBase.isAnnotated(RegisterListener.class)) { 060 ASTAnnotation registerAnnotation = astBase.getASTAnnotation(RegisterListener.class); 061 062 ASTType[] interfaces = registerAnnotation.getProperty("interfaces", ASTType[].class); 063 064 List<ASTType> interfaceList = new ArrayList<ASTType>(); 065 if (interfaces != null) { 066 interfaceList.addAll(Arrays.asList(interfaces)); 067 } 068 069 List<RegistrationGenerator> generators = getRegistrationGenerators(injectionNode, astBase, astType, interfaceList, registerAnnotation, context); 070 071 if (!generators.isEmpty()) { 072 RegistrationAspect registrationAspect = getRegistrationAspect(injectionNode); 073 registrationAspect.addRegistrationBuilders(generators); 074 } 075 } 076 } 077 078 private ImmutableList<RegistrationGenerator> getRegistrationGenerators(InjectionNode injectionNode, ASTBase astBase, ASTType astType, List<ASTType> interfaceList, ASTAnnotation registerAnnotation, AnalysisContext context) { 079 080 ImmutableList.Builder<RegistrationGenerator> generators = ImmutableList.builder(); 081 082 for (Map.Entry<ASTType, RegistrationGeneratorFactory> generatorFactoryEntry : generatorFactories.entrySet()) { 083 if ((interfaceList.isEmpty() || interfaceList.contains(generatorFactoryEntry.getKey())) 084 && astType.inheritsFrom(generatorFactoryEntry.getKey())) { 085 generators.add(generatorFactoryEntry.getValue().buildRegistrationGenerator(injectionNode, astBase, registerAnnotation, context)); 086 } 087 } 088 089 return generators.build(); 090 } 091 092 private RegistrationAspect getRegistrationAspect(InjectionNode injectionNode) { 093 if (!injectionNode.containsAspect(RegistrationAspect.class)) { 094 injectionNode.addAspect(new RegistrationAspect()); 095 } 096 return injectionNode.getAspect(RegistrationAspect.class); 097 } 098}