/** * 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.gen.variableBuilder; import com.sun.codemodel.*; import org.androidtransfuse.TransfuseAnalysisException; import org.androidtransfuse.adapter.ASTJDefinedClassType; import org.androidtransfuse.analysis.astAnalyzer.ASTInjectionAspect; import org.androidtransfuse.gen.*; import org.androidtransfuse.gen.variableDecorator.TypedExpressionFactory; import org.androidtransfuse.model.FieldInjectionPoint; import org.androidtransfuse.model.InjectionNode; import org.androidtransfuse.model.MethodInjectionPoint; import org.androidtransfuse.model.TypedExpression; import org.androidtransfuse.model.r.RResource; import org.androidtransfuse.model.r.RResourceReferenceBuilder; import org.androidtransfuse.model.r.ResourceIdentifier; import org.androidtransfuse.util.AndroidLiterals; import javax.inject.Inject; public class FragmentViewVariableBuilder extends ConsistentTypeVariableBuilder { private static final String FIND_VIEW_BY_ID = "findViewById"; private static final String FIND_VIEW_BY_TAG = "findViewWithTag"; private final JType viewType; private final Integer viewId; private final String viewTag; private final InjectionNode viewInjectionNode; private final InjectionExpressionBuilder injectionExpressionBuilder; private final RResourceReferenceBuilder rResourceReferenceBuilder; private final ClassGenerationUtil generationUtil; private final UniqueVariableNamer variableNamer; private final InvocationBuilder injectionInvocationBuilder; private final RResource rResource; private final ExpressionMatchingListFactory generatorFactory; @Inject public FragmentViewVariableBuilder(/*@Assisted*/ /*@Nullable*/ Integer viewId, /*@Assisted*/ /*@Nullable*/ String viewTag, /*@Assisted*/ InjectionNode viewInjectionNode, /*@Assisted*/ JType viewType, InjectionExpressionBuilder injectionExpressionBuilder, RResourceReferenceBuilder rResourceReferenceBuilder, ClassGenerationUtil generationUtil, InvocationBuilder injectionInvocationBuilder, UniqueVariableNamer variableNamer, RResource rResource, TypedExpressionFactory typedExpressionFactory, ExpressionMatchingListFactory generatorFactory) { super(AndroidLiterals.VIEW, typedExpressionFactory); this.viewId = viewId; this.viewTag = viewTag; this.viewInjectionNode = viewInjectionNode; this.viewType = viewType; this.injectionExpressionBuilder = injectionExpressionBuilder; this.rResourceReferenceBuilder = rResourceReferenceBuilder; this.generationUtil = generationUtil; this.injectionInvocationBuilder = injectionInvocationBuilder; this.variableNamer = variableNamer; this.rResource = rResource; this.generatorFactory = generatorFactory; } @Override public JExpression buildExpression(InjectionBuilderContext injectionBuilderContext, InjectionNode injectionNode) { try { injectionExpressionBuilder.setupInjectionRequirements(injectionBuilderContext, injectionNode); TypedExpression contextVar = injectionExpressionBuilder.buildVariable(injectionBuilderContext, viewInjectionNode); JExpression viewExpression; if (viewId != null) { ResourceIdentifier viewResourceIdentifier = rResource.getResourceIdentifier(viewId); JExpression viewIdRef = rResourceReferenceBuilder.buildReference(viewResourceIdentifier); viewExpression = contextVar.getExpression().invoke(FIND_VIEW_BY_ID).arg(viewIdRef); } else { //viewTag is not null //<Fragment>.getView().findViewWithTag(...) viewExpression = contextVar.getExpression().invoke(FIND_VIEW_BY_TAG).arg(JExpr.lit(viewTag)); } if (injectionNode.containsAspect(ASTInjectionAspect.class)) { return inject(injectionNode.getAspect(ASTInjectionAspect.class), injectionBuilderContext, injectionNode, viewExpression); } else { return viewExpression; } } catch (JClassAlreadyExistsException e) { throw new TransfuseAnalysisException("JClassAlreadyExistsException while generating injection: " + injectionNode.getClassName(), e); } } public JVar inject(ASTInjectionAspect injectionAspect, InjectionBuilderContext injectionBuilderContext, InjectionNode injectionNode, JExpression viewExpression) throws JClassAlreadyExistsException { JVar variableRef; JType nodeType = generationUtil.type(injectionNode.getASTType()); if (injectionAspect.getAssignmentType().equals(ASTInjectionAspect.InjectionAssignmentType.LOCAL)) { variableRef = injectionBuilderContext.getBlock().decl(nodeType, variableNamer.generateName(injectionNode)); } else { variableRef = injectionBuilderContext.getDefinedClass().field(JMod.PRIVATE, nodeType, variableNamer.generateName(injectionNode)); } JBlock block = injectionBuilderContext.getBlock(); block.assign(variableRef, JExpr.cast(viewType, viewExpression)); for (ASTInjectionAspect.InjectionGroup injectionGroup : injectionAspect.getGroups()) { //field injection for (FieldInjectionPoint fieldInjectionPoint : injectionGroup.getFieldInjectionPoints()) { block.add( injectionInvocationBuilder.buildFieldSet( new ASTJDefinedClassType(injectionBuilderContext.getDefinedClass()), injectionBuilderContext.getVariableMap().get(fieldInjectionPoint.getInjectionNode()), fieldInjectionPoint, variableRef)); } //method injection for (MethodInjectionPoint methodInjectionPoint : injectionGroup.getMethodInjectionPoints()) { block.add( injectionInvocationBuilder.buildMethodCall( new ASTJDefinedClassType(injectionBuilderContext.getDefinedClass()), methodInjectionPoint.getRootContainingType(), methodInjectionPoint.getMethod(), generatorFactory.build(injectionBuilderContext.getVariableMap(), methodInjectionPoint.getInjectionNodes()), new TypedExpression(methodInjectionPoint.getContainingType(), variableRef))); } } return variableRef; } }