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.sun.codemodel.JExpr;
019import com.sun.codemodel.JExpression;
020import org.androidtransfuse.TransfuseAnalysisException;
021import org.androidtransfuse.adapter.ASTType;
022import org.androidtransfuse.adapter.classes.ASTClassFactory;
023import org.androidtransfuse.gen.InjectionBuilderContext;
024import org.androidtransfuse.gen.InjectionExpressionBuilder;
025import org.androidtransfuse.gen.variableDecorator.TypedExpressionFactory;
026import org.androidtransfuse.model.InjectionNode;
027import org.androidtransfuse.model.TypedExpression;
028
029import javax.inject.Inject;
030import java.util.HashMap;
031import java.util.Map;
032
033/**
034 * @author John Ericksen
035 */
036public class PreferenceVariableBuilder implements VariableBuilder {
037
038    private final ASTType preferenceType;
039    private final String preferenceName;
040    private final InjectionNode preferenceManagerInjectionNode;
041    private final TypedExpressionFactory typedExpressionFactory;
042    private final InjectionExpressionBuilder injectionExpressionBuilder;
043
044    private Map<ASTType, PrefGetBuilder> accessorMethods = new HashMap<ASTType, PrefGetBuilder>();
045
046    @Inject
047    public PreferenceVariableBuilder(/*@Assisted*/ ASTType preferenceType,
048                                     /*@Assisted*/ String preferenceName,
049                                     /*@Assisted*/ InjectionNode preferenceManagerInjectionNode,
050                                     TypedExpressionFactory typedExpressionFactory, InjectionExpressionBuilder injectionExpressionBuilder, ASTClassFactory astClassFactory) {
051        this.preferenceName = preferenceName;
052        this.preferenceManagerInjectionNode = preferenceManagerInjectionNode;
053        this.typedExpressionFactory = typedExpressionFactory;
054        this.injectionExpressionBuilder = injectionExpressionBuilder;
055        this.preferenceType = preferenceType;
056
057        accessorMethods.put(astClassFactory.getType(String.class), new PrefGetBuilder("getString", JExpr.lit("")));
058        accessorMethods.put(astClassFactory.getType(long.class), new PrefGetBuilder("getLong", JExpr.lit(0L)));
059        accessorMethods.put(astClassFactory.getType(int.class), new PrefGetBuilder("getInt", JExpr.lit(0)));
060        accessorMethods.put(astClassFactory.getType(float.class), new PrefGetBuilder("getFloat", JExpr.lit(0F)));
061        accessorMethods.put(astClassFactory.getType(boolean.class), new PrefGetBuilder("getBoolean", JExpr.lit(false)));
062        accessorMethods.put(astClassFactory.getType(Long.class), new PrefGetBuilder("getLong", JExpr.lit(0L)));
063        accessorMethods.put(astClassFactory.getType(Integer.class), new PrefGetBuilder("getInt", JExpr.lit(0)));
064        accessorMethods.put(astClassFactory.getType(Float.class), new PrefGetBuilder("getFloat", JExpr.lit(0F)));
065        accessorMethods.put(astClassFactory.getType(Boolean.class), new PrefGetBuilder("getBoolean", JExpr.lit(false)));
066    }
067
068    @Override
069    public TypedExpression buildVariable(InjectionBuilderContext injectionBuilderContext, InjectionNode injectionNode) {
070        TypedExpression preferenceManagerExpression = injectionExpressionBuilder.buildVariable(injectionBuilderContext, preferenceManagerInjectionNode);
071
072        JExpression expression = invokePreferenceMethod(preferenceManagerExpression.getExpression());
073        return typedExpressionFactory.build(preferenceType, expression);
074    }
075
076    private JExpression invokePreferenceMethod(JExpression preferences) {
077        if (accessorMethods.containsKey(preferenceType)) {
078            PrefGetBuilder getBuilder = accessorMethods.get(preferenceType);
079            return preferences.invoke(getBuilder.getName()).arg(preferenceName).arg(getBuilder.getLit());
080        }
081
082        throw new TransfuseAnalysisException("Unable to find preference accessor method for " + preferenceType);
083    }
084
085    private static final class PrefGetBuilder {
086        private String name;
087        private JExpression lit;
088
089        private PrefGetBuilder(String name, JExpression lit) {
090            this.name = name;
091            this.lit = lit;
092        }
093
094        public JExpression getLit() {
095            return lit;
096        }
097
098        public String getName() {
099            return name;
100        }
101    }
102}