/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.gen.lang.builders;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.whole.gen.lang.LanguageGenerator;
import org.whole.gen.lang.visitors.AbstractVisitorCompilationUnitBuilder;
import org.whole.lang.builders.BuilderConstants;
import org.whole.lang.builders.GenericIdentityBuilder;
import org.whole.lang.contexts.IEntityContext;
import org.whole.lang.model.EnumValue;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.FeatureDescriptor;
import org.whole.lang.util.StringUtils;
/**
* @author Riccardo Solmi
*/
public class GenericBuilderAdapterBuilder extends AbstractVisitorCompilationUnitBuilder {
public GenericBuilderAdapterBuilder(LanguageGenerator generator) {
super(generator);
addClassDeclaration(generator.genericBuilderAdapterName(), GenericIdentityBuilder.class.getName());
addBodyDeclaration(newFieldDeclaration(generator.specificBuilderInterfaceName(), "specificBuilder"));
//costructors
MethodDeclaration constructor = addConstructorDeclaration();
constructor.parameters().add(newSingleVariableDeclaration(generator.specificBuilderInterfaceName(), "specificBuilder"));
addStatement(constructor, newAssignment(newFieldAccess(ast.newThisExpression(), "specificBuilder"), ast.newSimpleName("specificBuilder")));
constructor = addConstructorDeclaration();
constructor.parameters().add(newSingleVariableDeclaration(generator.specificBuilderInterfaceName(), "specificBuilder"));
constructor.parameters().add(newSingleVariableDeclaration(IEntityContext.class.getName(), "entityContext"));
addStatement(constructor, newConstructorInvocation(ast.newSimpleName("specificBuilder")));
addStatement(constructor, newMethodInvocation("wSetEntityContext", ast.newSimpleName("entityContext")));
// generic visit
addBodyDeclaration(newMethodDeclaration("void", "visit"));
}
public MethodDeclaration addSimpleEntity(String type) {
addSwitchCase(getMethodSwitch("wEntity"), type, BuilderConstants.buildName(type));
addSwitchCase(getMethodSwitch("wEntity_"), type, BuilderConstants.startBuildName(type));
addSwitchCase(getMethodSwitch("_wEntity"), type, BuilderConstants.endBuildName(type));
return null;
}
public MethodDeclaration addCompositeEntity(String type, String componentType, boolean isOrdered, boolean isByReference) {
addSwitchCase(getMethodSwitch("wEntity"), type, BuilderConstants.buildName(type));
addSwitchCase(getMethodSwitch("wEntity_"), type, BuilderConstants.startBuildName(type));
addSwitchCase(getCompositeMethodSwitch("wEntity_"), type, BuilderConstants.startBuildName(type), "initialCapacity");
addSwitchCase(getMethodSwitch("_wEntity"), type, BuilderConstants.endBuildName(type));
return null;
}
public void addStructuralFeature(String eName, String fType, String fName, String name, boolean isByReference) {
addFeatureSwitchCase(getFeatureMethodSwitch("wFeature"), fName, fName);
}
public MethodDeclaration addPrimitiveEntity(String type) {
return null;
}
public void addPrimitiveFeature(String type, String primitiveType, String name) {
addDataSwitchCase(getDataMethodSwitch(type, primitiveType), type);
}
public void addEnumEntity(String type, String primitiveType, String name) {
addEnumSwitchCase(getEnumMethodSwitch(type), type, primitiveType);
}
public MethodDeclaration addResolverEntity(String type) {
return null;
}
List enumCases;
protected List getEnumMethodSwitch(String type) {
if (enumCases == null) {
MethodDeclaration method = newMethodDeclaration("void", "wEntity",
newSingleVariableDeclaration(
newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc"),
newSingleVariableDeclaration(EnumValue.class.getName(), "value"));
SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal"));
method.getBody().statements().add(switchStm);
addBodyDeclaration(method);
enumCases = switchStm.statements();
}
return enumCases;
}
public void addEnumSwitchCase(List switchList, String type, String valueType) {
switchList.add(newCaseStatement(newFieldAccess(((LanguageGenerator) generator).specificEntityDescriptorEnumName(), StringUtils.toSimpleName(type)+"_ord")));
switchList.add(newExpressionStatement(newMethodInvocation(
ast.newSimpleName("specificBuilder"),
type, newCastExpression(valueType, ast.newSimpleName("value")))));
switchList.add(ast.newBreakStatement());
}
private Map/*<String, List>*/ dataSwitchMap = new HashMap();
protected List getDataMethodSwitch(String type, String valueType) {
List cases = (List) dataSwitchMap.get(valueType);
if (cases == null) {
MethodDeclaration method = newMethodDeclaration("void", "wEntity",
newSingleVariableDeclaration(
newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc"),
newSingleVariableDeclaration(valueType, "value"));
SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal"));
method.getBody().statements().add(switchStm);
addBodyDeclaration(method);
dataSwitchMap.put(valueType, cases = switchStm.statements());
}
return cases;
}
public void addDataSwitchCase(List switchList, String type) {
switchList.add(newCaseStatement(newFieldAccess(((LanguageGenerator) generator).specificEntityDescriptorEnumName(), StringUtils.toSimpleName(type)+"_ord")));
switchList.add(newExpressionStatement(newMethodInvocation(
ast.newSimpleName("specificBuilder"),
type, ast.newSimpleName("value"))));
switchList.add(ast.newBreakStatement());
}
private Map<String, List> switchMap = new HashMap<String, List>();
protected List getMethodSwitch(String type) {
List cases = switchMap.get(type);
if (cases == null) {
MethodDeclaration method = newMethodDeclaration("void", type,
newSingleVariableDeclaration(
newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc"));
SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal"));
method.getBody().statements().add(switchStm);
addBodyDeclaration(method);
switchMap.put(type, cases = switchStm.statements());
}
return cases;
}
private Map<String, List> compositeSwitchMap = new HashMap<String, List>();
protected List getCompositeMethodSwitch(String type) {
List cases = compositeSwitchMap.get(type);
if (cases == null) {
MethodDeclaration method = newMethodDeclaration("void", type,
newSingleVariableDeclaration(
newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc"),
newSingleVariableDeclaration("int", "initialCapacity"));
SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal"));
method.getBody().statements().add(switchStm);
addBodyDeclaration(method);
compositeSwitchMap.put(type, cases = switchStm.statements());
}
return cases;
}
private Map<String, List> featureSwitchMap = new HashMap<String, List>();
protected List getFeatureMethodSwitch(String type) {
List cases = featureSwitchMap.get(type);
if (cases == null) {
MethodDeclaration method = newMethodDeclaration("void", type,
newSingleVariableDeclaration(FeatureDescriptor.class.getName(), "featureDesc"));
SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("featureDesc", "getOrdinal"));
method.getBody().statements().add(switchStm);
addBodyDeclaration(method);
featureSwitchMap.put(type, cases = switchStm.statements());
}
return cases;
}
public void addSwitchCase(List switchList, String type, String buildMethod) {
switchList.add(newCaseStatement(newFieldAccess(((LanguageGenerator) generator).specificEntityDescriptorEnumName(), StringUtils.toSimpleName(type)+"_ord")));
switchList.add(newExpressionStatement(newMethodInvocation(
ast.newSimpleName("specificBuilder"),
buildMethod)));
switchList.add(ast.newBreakStatement());
}
public void addSwitchCase(List switchList, String type, String buildMethod, String arg) {
switchList.add(newCaseStatement(newFieldAccess(((LanguageGenerator) generator).specificEntityDescriptorEnumName(), StringUtils.toSimpleName(type)+"_ord")));
switchList.add(newExpressionStatement(newMethodInvocation(
ast.newSimpleName("specificBuilder"),
buildMethod,
ast.newSimpleName(arg))));
switchList.add(ast.newBreakStatement());
}
private Set<String> features = new HashSet<String>();
public void addFeatureSwitchCase(List switchList, String type, String buildMethod) {
if (!features.add(type))
return;
switchList.add(newCaseStatement(newFieldAccess(((LanguageGenerator) generator).specificFeatureDescriptorEnumName(), StringUtils.toSimpleName(type)+"_ord")));
switchList.add(newExpressionStatement(newMethodInvocation(
ast.newSimpleName("specificBuilder"),
buildMethod)));
switchList.add(ast.newBreakStatement());
}
}