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.gen.variableBuilder;
017
018import org.androidtransfuse.adapter.ASTAnnotation;
019import org.androidtransfuse.adapter.ASTBase;
020import org.androidtransfuse.adapter.ASTPrimitiveType;
021import org.androidtransfuse.adapter.ASTUtils;
022import org.androidtransfuse.analysis.AnalysisContext;
023import org.androidtransfuse.analysis.Analyzer;
024import org.androidtransfuse.analysis.InjectionPointFactory;
025import org.androidtransfuse.analysis.astAnalyzer.IntentFactoryExtraAspect;
026import org.androidtransfuse.annotations.Extra;
027import org.androidtransfuse.model.InjectionNode;
028import org.androidtransfuse.model.InjectionSignature;
029import org.androidtransfuse.util.AndroidLiterals;
030import org.androidtransfuse.validation.Validator;
031
032import javax.inject.Inject;
033
034/**
035 * @author John Ericksen
036 */
037public class ExtraInjectionNodeBuilder extends InjectionNodeBuilderSingleAnnotationAdapter {
038
039    private final InjectionPointFactory injectionPointFactory;
040    private final VariableInjectionBuilderFactory variableInjectionBuilderFactory;
041    private final Analyzer analyzer;
042    private final Validator validator;
043
044    @Inject
045    public ExtraInjectionNodeBuilder(InjectionPointFactory injectionPointFactory,
046                                     VariableInjectionBuilderFactory variableInjectionBuilderFactory,
047                                     Analyzer analyzer,
048                                     Validator validator) {
049        super(Extra.class);
050        this.injectionPointFactory = injectionPointFactory;
051        this.variableInjectionBuilderFactory = variableInjectionBuilderFactory;
052        this.analyzer = analyzer;
053        this.validator = validator;
054    }
055
056    @Override
057    public InjectionNode buildInjectionNode(ASTBase target, InjectionSignature signature, AnalysisContext context, ASTAnnotation annotation) {
058        String extraId = annotation.getProperty("value", String.class);
059        Boolean optional = annotation.getProperty("optional", Boolean.class);
060
061        if (optional == null) {
062            optional = false;
063        }
064
065        boolean wrapped = ASTUtils.getInstance().isAnnotated(signature.getType(), "org.parceler.Parcel");
066
067        InjectionNode injectionNode = analyzer.analyze(signature, context);
068
069        if(optional && signature.getType() instanceof ASTPrimitiveType){
070            validator.error("@Extra marked with optional=true must not annotate a primitive type.")
071                    .element(target)
072                    .annotation(annotation)
073                    .build();
074        }
075        else {
076
077            InjectionNode activityInjectionNode = injectionPointFactory.buildInjectionNode(AndroidLiterals.ACTIVITY, context);
078
079            injectionNode.addAspect(IntentFactoryExtraAspect.class, new IntentFactoryExtraAspect(!optional, extraId, signature.getType()));
080
081            injectionNode.addAspect(VariableBuilder.class, variableInjectionBuilderFactory.buildExtraVariableBuilder(extraId, activityInjectionNode, optional, wrapped));
082        }
083
084        return injectionNode;
085    }
086}