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.registration; 017 018import com.google.common.collect.ImmutableSet; 019import org.androidtransfuse.TransfuseAnalysisException; 020import org.androidtransfuse.adapter.*; 021import org.androidtransfuse.adapter.classes.ASTClassFactory; 022import org.androidtransfuse.analysis.AnalysisContext; 023import org.androidtransfuse.analysis.InjectionPointFactory; 024import org.androidtransfuse.analysis.ListenableMethod; 025import org.androidtransfuse.analysis.repository.RegistrationGeneratorFactory; 026import org.androidtransfuse.gen.componentBuilder.ComponentBuilderFactory; 027import org.androidtransfuse.gen.componentBuilder.RegistrationGenerator; 028import org.androidtransfuse.gen.componentBuilder.ViewRegistrationInvocationBuilder; 029import org.androidtransfuse.gen.componentBuilder.ViewTypeRegistrationInvocationBuilderImpl; 030import org.androidtransfuse.model.InjectionNode; 031 032import javax.inject.Inject; 033import java.util.Collections; 034 035public final class ViewRegistrationGeneratorFactory implements RegistrationGeneratorFactory { 036 037 private final InjectionPointFactory injectionPointFactory; 038 private final ASTClassFactory astClassFactory; 039 private final ComponentBuilderFactory componentBuilderFactory; 040 private final ListenableMethod listenerMethod; 041 042 @Inject 043 private ViewRegistrationGeneratorFactory(/*@Assisted*/ ListenableMethod listenerMethod, InjectionPointFactory injectionPointFactory, ASTClassFactory astClassFactory, ComponentBuilderFactory componentBuilderFactory) { 044 this.injectionPointFactory = injectionPointFactory; 045 this.astClassFactory = astClassFactory; 046 this.componentBuilderFactory = componentBuilderFactory; 047 this.listenerMethod = listenerMethod; 048 } 049 050 @Override 051 public RegistrationGenerator buildRegistrationGenerator(InjectionNode injectionNode, ASTBase astBase, ASTAnnotation registerAnnotation, AnalysisContext context) { 052 053 InjectionNode viewInjectionNode = buildViewInjectionNode(registerAnnotation, context); 054 055 ViewRegistrationInvocationBuilder invocationBuilder; 056 if (astBase instanceof ASTType) { 057 invocationBuilder = new ViewTypeRegistrationInvocationBuilderImpl(); 058 } else if (astBase instanceof ASTMethod) { 059 invocationBuilder = componentBuilderFactory.buildViewMethodRegistrationInvocationBuilder((ASTMethod) astBase); 060 } else if (astBase instanceof ASTField) { 061 invocationBuilder = componentBuilderFactory.buildViewFieldRegistrationInvocationBuilder((ASTField) astBase); 062 } else { 063 throw new TransfuseAnalysisException("ASTBase type not mapped"); 064 } 065 066 return componentBuilderFactory.buildViewRegistrationGenerator(viewInjectionNode, listenerMethod.getMethod(), injectionNode, invocationBuilder); 067 } 068 069 private InjectionNode buildViewInjectionNode(final ASTAnnotation registerAnnotation, AnalysisContext context) { 070 071 ASTType atViewType = astClassFactory.getType(org.androidtransfuse.annotations.View.class); 072 ASTAnnotation viewRegistrationAnnotation = new ASTAnnotationPropertyReplacement(registerAnnotation, atViewType); 073 074 return injectionPointFactory.buildInjectionNode(Collections.singleton(viewRegistrationAnnotation), listenerMethod.getListenable(), listenerMethod.getListenable(), context); 075 } 076 077 private static final class ASTAnnotationPropertyReplacement implements ASTAnnotation { 078 079 private final ASTAnnotation annotation; 080 private final ASTType astType; 081 082 private ASTAnnotationPropertyReplacement(ASTAnnotation annotation, ASTType astType) { 083 this.annotation = annotation; 084 this.astType = astType; 085 } 086 087 @Override 088 public <T> T getProperty(String name, Class<T> type) { 089 return annotation.getProperty(name, type); 090 } 091 092 @Override 093 public ASTType getASTType() { 094 return astType; 095 } 096 097 @Override 098 public ImmutableSet<String> getPropertyNames() { 099 return annotation.getPropertyNames(); 100 } 101 } 102}