/**
* 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.analysis.astAnalyzer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.androidtransfuse.adapter.*;
import org.androidtransfuse.analysis.AnalysisContext;
import org.androidtransfuse.analysis.repository.RegistrationGeneratorFactory;
import org.androidtransfuse.annotations.RegisterListener;
import org.androidtransfuse.gen.componentBuilder.RegistrationGenerator;
import org.androidtransfuse.model.InjectionNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author John Ericksen
*/
public class RegistrationAnalyzer implements ASTAnalysis {
private ImmutableMap<ASTType, RegistrationGeneratorFactory> generatorFactories;
public RegistrationAnalyzer(ImmutableMap<ASTType, RegistrationGeneratorFactory> generatorFactories) {
this.generatorFactories = generatorFactories;
}
@Override
public void analyzeType(InjectionNode injectionNode, final ASTType astType, AnalysisContext context) {
analyze(astType, astType, injectionNode, context);
}
@Override
public void analyzeMethod(InjectionNode injectionNode, ASTType concreteType, final ASTMethod astMethod, AnalysisContext context) {
analyze(astMethod, astMethod.getReturnType(), injectionNode, context);
}
@Override
public void analyzeField(InjectionNode injectionNode, ASTType concreteType, final ASTField astField, AnalysisContext context) {
analyze(astField, astField.getASTType(), injectionNode, context);
}
private <T> void analyze(ASTBase astBase, ASTType astType, InjectionNode injectionNode, AnalysisContext context) {
if (astBase.isAnnotated(RegisterListener.class)) {
ASTAnnotation registerAnnotation = astBase.getASTAnnotation(RegisterListener.class);
ASTType[] interfaces = registerAnnotation.getProperty("interfaces", ASTType[].class);
List<ASTType> interfaceList = new ArrayList<ASTType>();
if (interfaces != null) {
interfaceList.addAll(Arrays.asList(interfaces));
}
List<RegistrationGenerator> generators = getRegistrationGenerators(injectionNode, astBase, astType, interfaceList, registerAnnotation, context);
if (!generators.isEmpty()) {
RegistrationAspect registrationAspect = getRegistrationAspect(injectionNode);
registrationAspect.addRegistrationBuilders(generators);
}
}
}
private ImmutableList<RegistrationGenerator> getRegistrationGenerators(InjectionNode injectionNode, ASTBase astBase, ASTType astType, List<ASTType> interfaceList, ASTAnnotation registerAnnotation, AnalysisContext context) {
ImmutableList.Builder<RegistrationGenerator> generators = ImmutableList.builder();
for (Map.Entry<ASTType, RegistrationGeneratorFactory> generatorFactoryEntry : generatorFactories.entrySet()) {
if ((interfaceList.isEmpty() || interfaceList.contains(generatorFactoryEntry.getKey()))
&& astType.inherits(generatorFactoryEntry.getKey())) {
generators.add(generatorFactoryEntry.getValue().buildRegistrationGenerator(injectionNode, astBase, registerAnnotation, context));
}
}
return generators.build();
}
private RegistrationAspect getRegistrationAspect(InjectionNode injectionNode) {
if (!injectionNode.containsAspect(RegistrationAspect.class)) {
injectionNode.addAspect(new RegistrationAspect());
}
return injectionNode.getAspect(RegistrationAspect.class);
}
}