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.experiment.generators;
017
018import com.sun.codemodel.JBlock;
019import com.sun.codemodel.JExpr;
020import com.sun.codemodel.JInvocation;
021import org.androidtransfuse.adapter.ASTMethod;
022import org.androidtransfuse.adapter.ASTParameter;
023import org.androidtransfuse.adapter.MethodSignature;
024import org.androidtransfuse.analysis.astAnalyzer.ManualSuperAspect;
025import org.androidtransfuse.annotations.Factory;
026import org.androidtransfuse.experiment.ComponentBuilder;
027import org.androidtransfuse.experiment.ComponentDescriptor;
028import org.androidtransfuse.experiment.ComponentMethodGenerator;
029import org.androidtransfuse.experiment.Generation;
030import org.androidtransfuse.model.InjectionNode;
031import org.androidtransfuse.model.MethodDescriptor;
032
033import javax.inject.Inject;
034import java.util.List;
035import java.util.Set;
036
037/**
038 * @author John Ericksen
039 */
040public class SuperGenerator implements Generation {
041
042    public
043    @Factory
044    interface SuperGeneratorFactory {
045        SuperGenerator build(ASTMethod method);
046    }
047
048    private final ASTMethod method;
049
050    @Inject
051    public SuperGenerator(ASTMethod method) {
052        this.method = method;
053    }
054
055    @Override
056    public void schedule(final ComponentBuilder builder, ComponentDescriptor descriptor) {
057        builder.addLazy(method, new ComponentMethodGenerator() {
058            @Override
059            public void generate(MethodDescriptor methodDescriptor, JBlock block) {
060                if(!isSuperCanceled(builder.getExpressionMap().keySet())) {
061                    JInvocation invocation = block.invoke(JExpr._super(), method.getName());
062
063                    List<ASTParameter> parameters = methodDescriptor.getASTMethod().getParameters();
064
065                    for (ASTParameter parameter : parameters) {
066                        invocation.arg(methodDescriptor.getParameter(parameter).getExpression());
067                    }
068                }
069            }
070        });
071    }
072
073    private boolean isSuperCanceled(Set<InjectionNode> injectionNodes){
074
075        MethodSignature signature = new MethodSignature(method);
076        for (InjectionNode injectionNode : injectionNodes) {
077            if(injectionNode.containsAspect(ManualSuperAspect.class)){
078                ManualSuperAspect aspect = injectionNode.getAspect(ManualSuperAspect.class);
079
080                for (ManualSuperAspect.Method manualSuperMethod : aspect.getMethods()) {
081                    MethodSignature manualSuperMethodSignature = new MethodSignature(method.getReturnType(), manualSuperMethod.getName(), manualSuperMethod.getParameters());
082                    if(signature.equals(manualSuperMethodSignature)){
083                        return true;
084                    }
085                }
086            }
087        }
088
089        return false;
090    }
091}