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 com.google.common.collect.ImmutableList;
019import com.sun.codemodel.JExpr;
020import com.sun.codemodel.JExpression;
021import org.androidtransfuse.adapter.ASTType;
022import org.androidtransfuse.adapter.classes.ASTClassFactory;
023import org.androidtransfuse.model.TypedExpression;
024
025import javax.inject.Inject;
026
027/**
028 * @author John Ericksen
029 */
030public class InjectionBindingBuilder {
031
032    private final VariableInjectionBuilderFactory variableInjectionBuilderFactory;
033    private final ASTClassFactory astClassFactory;
034
035    @Inject
036    public InjectionBindingBuilder(VariableInjectionBuilderFactory variableInjectionBuilderFactory, ASTClassFactory astClassFactory) {
037        this.variableInjectionBuilderFactory = variableInjectionBuilderFactory;
038        this.astClassFactory = astClassFactory;
039    }
040
041    public DependencyBindingBuilder dependency(Class clazz) {
042        return dependency(astClassFactory.getType(clazz));
043    }
044
045    public DependencyBindingBuilder dependency(ASTType type) {
046        return new DependencyBindingBuilder(type);
047    }
048
049    public StaticInvocationBindingBuilder staticInvoke(ASTType invocationTarget, ASTType returnType, String method) {
050        return new StaticInvocationBindingBuilder(invocationTarget, returnType, method);
051    }
052
053    public InjectionNodeBuilder buildThis(Class targetClass) {
054        ASTType astType = astClassFactory.getType(targetClass);
055        return buildThis(astType);
056    }
057
058    public InjectionNodeBuilder buildThis(ASTType targetType) {
059        return variableInjectionBuilderFactory.buildInjectionNodeBuilder(
060                variableInjectionBuilderFactory.buildIndependentVariableBuilderWrapper(targetType, JExpr._this()));
061    }
062
063    public InjectionNodeBuilder buildExpression(TypedExpression typedExpression) {
064        return variableInjectionBuilderFactory.buildInjectionNodeBuilder(
065                variableInjectionBuilderFactory.buildExpressionWrapper(typedExpression));
066    }
067
068    public final class StaticInvocationBindingBuilder {
069
070        private final ASTType invocationTarget;
071        private final ASTType returnType;
072        private final String method;
073
074        private StaticInvocationBindingBuilder(ASTType invocationTarget, ASTType returnType, String method) {
075            this.invocationTarget = invocationTarget;
076            this.returnType = returnType;
077            this.method = method;
078        }
079
080        public StaticInvocationBindingBuilderArgument dependencyArg(ASTType dependency) {
081            return new StaticInvocationBindingBuilderArgument(this, dependency);
082        }
083    }
084
085    public final class StaticInvocationBindingBuilderArgument {
086
087        private final StaticInvocationBindingBuilder parent;
088        private final ASTType dependency;
089
090        private StaticInvocationBindingBuilderArgument(StaticInvocationBindingBuilder parent, ASTType dependency) {
091            this.parent = parent;
092            this.dependency = dependency;
093        }
094
095        public InjectionNodeBuilder build() {
096            return variableInjectionBuilderFactory.buildDependentInjectionNodeBuilder(
097                    dependency,
098                    parent.returnType,
099                    variableInjectionBuilderFactory.buildStaticInvocationVariableBuilder(parent.invocationTarget, parent.method));
100        }
101    }
102
103    public final class DependencyBindingBuilder {
104
105        private final ASTType type;
106
107        private DependencyBindingBuilder(ASTType type) {
108            this.type = type;
109        }
110
111        public DependantVariableBuilderWrapper invoke(ASTType returnType, DependentVariableBuilder dependentVariableBuilder) {
112            return new DependantVariableBuilderWrapper(returnType, dependentVariableBuilder);
113        }
114
115        public DependencyArgumentBindingBuilder invoke(ASTType returnType, String methodName) {
116            return new DependencyArgumentBindingBuilder(type, returnType, methodName);
117        }
118
119        public final class DependencyArgumentBindingBuilder {
120
121            private final ASTType type;
122            private final ASTType returnType;
123            private final String methodName;
124            private final ImmutableList.Builder<JExpression> arguments = ImmutableList.builder();
125
126            private DependencyArgumentBindingBuilder(ASTType type, ASTType returnType, String methodName) {
127                this.type = type;
128                this.returnType = returnType;
129                this.methodName = methodName;
130            }
131
132            public DependencyArgumentBindingBuilder arg(JExpression value) {
133                arguments.add(value);
134                return this;
135            }
136
137            public InjectionNodeBuilder build() {
138                return variableInjectionBuilderFactory.buildDependentInjectionNodeBuilder(
139                        type,
140                        returnType,
141                        variableInjectionBuilderFactory.buildMethodCallVariableBuilder(methodName, arguments.build()));
142            }
143        }
144
145        public final class DependantVariableBuilderWrapper {
146            private final DependentVariableBuilder dependentVariableBuilder;
147            private final ASTType returnType;
148
149            private DependantVariableBuilderWrapper(ASTType returnType, DependentVariableBuilder dependentVariableBuilder) {
150                this.returnType = returnType;
151                this.dependentVariableBuilder = dependentVariableBuilder;
152            }
153
154            public InjectionNodeBuilder build() {
155                return variableInjectionBuilderFactory.buildDependentInjectionNodeBuilder(
156                        type,
157                        returnType,
158                        dependentVariableBuilder
159                );
160            }
161        }
162    }
163}