diff --git a/AlgebraicDataflowArchitectureModel/models/WeatherObservationSystem.model b/AlgebraicDataflowArchitectureModel/models/WeatherObservationSystem.model new file mode 100644 index 0000000..a13a38b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/WeatherObservationSystem.model @@ -0,0 +1,11 @@ +channel CIO { + out temp_f(p:Int, observe(x)) == x +} +channel C1{ + in temp_f(q:Int, conversion(y)) == y + out temp_c(r:Int, conversion(z)) == (z-32) / 1.8 +} +channel C2{ + in temp_f(q:Int, update(y)) == y + out highest(r:Int, update(z)) == if(gt(z, r), z, r) +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/CodeGenerator.java deleted file mode 100644 index 56b8baf..0000000 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/CodeGenerator.java +++ /dev/null @@ -1,350 +0,0 @@ -package algorithms; - -import java.util.ArrayList; -import java.util.HashSet; - -import code.ast.Block; -import code.ast.CompilationUnit; -import code.ast.FieldDeclaration; -import code.ast.ImportDeclaration; -import code.ast.MethodDeclaration; -import code.ast.TypeDeclaration; -import code.ast.VariableDeclaration; -import models.Edge; -import models.Node; -import models.algebra.Expression; -import models.algebra.Field; -import models.algebra.Parameter; -import models.algebra.Symbol; -import models.algebra.Term; -import models.algebra.Type; -import models.dataConstraintModel.ChannelGenerator; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.DataConstraintModel; -import models.dataConstraintModel.IdentifierTemplate; -import models.dataFlowModel.DataFlowModel; -import models.dataFlowModel.DataflowChannelGenerator.IResourceStateAccessor; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.PushPullValue; -import models.dataFlowModel.ResourceDependency; -import models.dataFlowModel.ResourceDependencyGraph; -import models.dataFlowModel.ResourceNode; -import models.dataFlowModel.StoreAttribute; - -public class CodeGenerator { - public static final Type typeVoid = new Type("Void", "void"); - private static String defaultMainTypeName = "Main"; - static String mainTypeName = defaultMainTypeName; - - public static String getMainTypeName() { - return mainTypeName; - } - - public static void setMainTypeName(String mainTypeName) { - CodeGenerator.mainTypeName = mainTypeName; - } - - public static void resetMainTypeName() { - CodeGenerator.mainTypeName = defaultMainTypeName; - } - - static public ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { - ArrayList codes = new ArrayList<>(); - ArrayList resources = StoreResourceCheck(graph); - - TypeDeclaration mainType = new TypeDeclaration(mainTypeName); - CompilationUnit mainCU = new CompilationUnit(mainType); - mainCU.addImport(new ImportDeclaration("java.util.*")); - codes.add(mainCU); - for (ResourceNode rn : resources) { - boolean f = false; - String name = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() - + rn.getIdentifierTemplate().getResourceName().substring(1); - String consstr = "new " + name + "("; - TypeDeclaration type = new TypeDeclaration(name); - for (Edge e : rn.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - consstr += rename.toLowerCase() + ","; - f = true; - } - } - for (Edge e : rn.getInEdges()) { - ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - consstr += rename.toLowerCase() + ","; - f = true; - } else { - if (rn.getIndegree() > 1) - type.addField(new FieldDeclaration( - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); - } - } - if (f) - consstr = consstr.substring(0, consstr.length() - 1); - consstr += ")"; - FieldDeclaration field = new FieldDeclaration(new Type(name, name), - rn.getIdentifierTemplate().getResourceName(), consstr); - mainType.addField(field); - MethodDeclaration cons = new MethodDeclaration(name, true); - Block block = new Block(); - for (Edge e : rn.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - type.addField(new FieldDeclaration(new Type(rename, rename), - ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); - cons.addParameter(new VariableDeclaration(new Type(rename, rename), - ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); - block.addStatement("this." + rename.toLowerCase() + " = " + rename.toLowerCase() + ";"); - cons.setBody(block); - } - } - block = new Block(); - for (Edge e : rn.getInEdges()) { - ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - type.addField(new FieldDeclaration(new Type(rename, rename), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); - cons.addParameter(new VariableDeclaration(new Type(rename, rename), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); - block.addStatement("this." + rename.toLowerCase() + " = " + rename.toLowerCase() + ";"); - cons.setBody(block); - } else { - ArrayList vars = new ArrayList<>(); - vars.add(new VariableDeclaration( - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); - type.addMethod(new MethodDeclaration("update" + rename, false, typeVoid, vars)); - } - } - if (cons.getParameters() != null) - type.addMethod(cons); - for (ChannelGenerator cg : model.getIOChannelGenerators()) { - for (ChannelMember cm : cg.getChannelMembers()) { - if (cm.getIdentifierTemplate().getResourceName().equals(type.getTypeName().toLowerCase())) { - if (cm.getStateTransition().getMessageExpression().getClass() == Term.class) { - ArrayList params = new ArrayList<>(); - params.add(new VariableDeclaration(cm.getIdentifierTemplate().getResourceStateType(), - cm.getIdentifierTemplate().getResourceName())); - MethodDeclaration io = new MethodDeclaration( - ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), - false, typeVoid, params); - type.addMethod(io); - String str; - str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); - io = new MethodDeclaration(str, false, typeVoid, params); - mainType.addMethod(io); - } - } - } - } - if (((StoreAttribute) rn.getAttribute()).isStored()) { - String str = "new " + rn.getIdentifierTemplate().getResourceStateType().getImplementationTypeName() - + "()"; - if (!rn.getIdentifierTemplate().getResourceStateType().getTypeName().contains("List")) - str = null; - type.addField(new FieldDeclaration(rn.getIdentifierTemplate().getResourceStateType(), - rn.getIdentifierTemplate().getResourceName(), str)); - } - type.addMethod(new MethodDeclaration("get" + type.getTypeName(), - rn.getIdentifierTemplate().getResourceStateType())); - CompilationUnit cu = new CompilationUnit(type); - cu.addImport(new ImportDeclaration("java.util.*")); - codes.add(cu); - } - for (Node n : graph.getNodes()) { - ResourceNode rn = (ResourceNode) n; - MethodDeclaration get = new MethodDeclaration( - "get" + rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() - + rn.getIdentifierTemplate().getResourceName().substring(1), - rn.getIdentifierTemplate().getResourceStateType()); - get.setBody(new Block()); - get.getBody().addStatement( - "return " + rn.getIdentifierTemplate().getResourceName() + "." + get.getName() + "();"); - mainType.addMethod(get); - } - HashSet tmps = new HashSet<>(); - HashSet cont = new HashSet<>(); - for (MethodDeclaration method : mainType.getMethods()) { - if (!tmps.contains(method.getName())) - tmps.add(method.getName()); - else - cont.add(method.getName()); - } - for (MethodDeclaration method : mainType.getMethods()) { - if (cont.contains(method.getName())) { - method.setName(method.getName() + method.getParameters().get(0).getName().substring(0, 1).toUpperCase() - + method.getParameters().get(0).getName().substring(1)); - } - } - return codes; - } - - static public ArrayList getCodes(ArrayList codeTree) { - ArrayList codes = new ArrayList<>(); - for (TypeDeclaration type : codeTree) { - codes.add("public class " + type.getTypeName() + "{"); - for (FieldDeclaration field : type.getFields()) { - if (type.getTypeName() != mainTypeName) { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " - + field.getName(); - if (field.getType().equals(DataConstraintModel.typeList)) - cons += " = new ArrayList<>()"; - cons += ";"; - codes.add(cons); - } else { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " - + field.getName() + " = new " + field.getType().getTypeName() + "("; - for (TypeDeclaration tree : codeTree) { - if (field.getType().getTypeName() == tree.getTypeName()) { - for (VariableDeclaration var : tree.getConstructors()) { - cons += var.getName() + ","; - } - if (!tree.getConstructors().isEmpty()) - cons = cons.substring(0, cons.length() - 1); - break; - } - } - cons += ");"; - codes.add(cons); - } - } - codes.add(""); - if (type.getTypeName() != mainTypeName) { - if (!type.getConstructors().isEmpty()) { - String cons = "\t" + "public " + type.getTypeName() + "("; - for (VariableDeclaration constructor : type.getConstructors()) { - cons += constructor.getType().getTypeName() + " " + constructor.getName() + ","; - } - if (!type.getConstructors().isEmpty()) - cons = cons.substring(0, cons.length() - 1); - cons += "){"; - codes.add(cons); - for (FieldDeclaration field : type.getFields()) { - for (VariableDeclaration vari : type.getConstructors()) { - if (field.getType().getTypeName().equals(vari.getType().getTypeName())) { - codes.add("\t\t" + "this." + field.getName() + " = " + field.getName() + ";"); - } - } - } - codes.add("\t" + "}"); - codes.add(""); - } - } - for (MethodDeclaration method : type.getMethods()) { - String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " - + method.getName() + "("; - if (method.getParameters() != null) { - for (VariableDeclaration var : method.getParameters()) { - varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; - } - if (!method.getParameters().isEmpty()) - varstr = varstr.substring(0, varstr.length() - 1); - } - if (method.getBody() != null) { - for (String str : method.getBody().getStatements()) { - codes.add("\t\t" + str + ";"); - } - } - codes.add(varstr + ")" + "{"); - codes.add("\t" + "}"); - codes.add(""); - } - codes.add("}"); - codes.add(""); - } - return codes; - } - - static private ArrayList StoreResourceCheck(ResourceDependencyGraph graph) { - ArrayList resources = new ArrayList<>(); - for (Node n : graph.getNodes()) { - ResourceNode rn = (ResourceNode) n; - boolean flag = true; - for (Edge e : rn.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - flag = false; - } - } - for (Edge e : rn.getInEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - flag = false; - } - } - if (flag) - resources.add(rn); - } - trackNode(resources.get(0), resources); - return resources; - } - - static private void trackNode(ResourceNode current, ArrayList resources) { - if (!resources.contains(current)) - resources.add(current); - for (Edge e : current.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - trackNode((ResourceNode) re.getDestination(), resources); - } - } - for (Edge e : current.getInEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - trackNode((ResourceNode) re.getSource(), resources); - } - } - } - - static public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { - if (target.equals(from)) { - return new Field(target.getResourceName(), - target.getResourceStateType() != null ? target.getResourceStateType() - : DataConstraintModel.typeInt); - } - return null; - } - - @Override - public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { - return new Parameter(target.getResourceName(), - target.getResourceStateType() != null ? target.getResourceStateType() - : DataConstraintModel.typeInt); - } - }; - static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { - if (target.equals(from)) { - return new Field(target.getResourceName(), - target.getResourceStateType() != null ? target.getResourceStateType() - : DataConstraintModel.typeInt); - } - return null; - } - - @Override - public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { - Term getter = new Term(new Symbol("get" + target.getResourceName().substring(0, 1).toUpperCase() - + target.getResourceName().substring(1), 1, Symbol.Type.METHOD)); - getter.addChild(new Field(target.getResourceName(), target.getResourceStateType())); - return getter; - } - }; -} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java new file mode 100644 index 0000000..83a1e19 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -0,0 +1,375 @@ +package algorithms; + +import java.util.ArrayList; +import java.util.HashSet; + +import code.ast.Block; +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.ImportDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.Parameter; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.DataflowChannelGenerator.IResourceStateAccessor; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceDependency; +import models.dataFlowModel.ResourceDependencyGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; + +/** + * Generator for plain Java prototypes + * + * @author Nitta + * + */ +public class JavaCodeGenerator { + public static final Type typeVoid = new Type("Void", "void"); + private static String defaultMainTypeName = "Main"; + static String mainTypeName = defaultMainTypeName; + + public static String getMainTypeName() { + return mainTypeName; + } + + public static void setMainTypeName(String mainTypeName) { + JavaCodeGenerator.mainTypeName = mainTypeName; + } + + public static void resetMainTypeName() { + JavaCodeGenerator.mainTypeName = defaultMainTypeName; + } + + static public ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { + ArrayList codes = new ArrayList<>(); + ArrayList resources = StoreResourceCheck(graph); + + TypeDeclaration mainType = new TypeDeclaration(mainTypeName); + CompilationUnit mainCU = new CompilationUnit(mainType); + mainCU.addImport(new ImportDeclaration("java.util.*")); + codes.add(mainCU); + for (ResourceNode rn : resources) { + boolean f = false; + String resourceName = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + + rn.getIdentifierTemplate().getResourceName().substring(1); + TypeDeclaration type = new TypeDeclaration(resourceName); + + // Declare the field to refer each resource in the main type. + String fieldInitializer = "new " + resourceName + "("; + for (Edge e : rn.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + String rename = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() + .substring(0, 1).toUpperCase() + + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + fieldInitializer += rename.toLowerCase() + ","; + f = true; + } + } + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + String rename = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() + .substring(0, 1).toUpperCase() + + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + fieldInitializer += rename.toLowerCase() + ","; + f = true; + } else { + if (rn.getIndegree() > 1) + type.addField(new FieldDeclaration( + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + } + } + if (f) + fieldInitializer = fieldInitializer.substring(0, fieldInitializer.length() - 1); + fieldInitializer += ")"; + FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), + rn.getIdentifierTemplate().getResourceName(), fieldInitializer); + mainType.addField(field); + + // Declare a constructor, fields and update methods in the type of each resource. + MethodDeclaration constructor = new MethodDeclaration(resourceName, true); + Block block = new Block(); + for (Edge e : rn.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + String dstResName = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() + .substring(0, 1).toUpperCase() + + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // Declare a field to refer to the destination resource of push transfer. + type.addField(new FieldDeclaration(new Type(dstResName, dstResName), + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); + constructor.addParameter(new VariableDeclaration(new Type(dstResName, dstResName), + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); + block.addStatement("this." + dstResName.toLowerCase() + " = " + dstResName.toLowerCase() + ";"); + constructor.setBody(block); + } + } + block = new Block(); + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + String srcResName = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() + .substring(0, 1).toUpperCase() + + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + // Declare a field to refer to the source resource of pull transfer. + type.addField(new FieldDeclaration(new Type(srcResName, srcResName), + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + constructor.addParameter(new VariableDeclaration(new Type(srcResName, srcResName), + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + block.addStatement("this." + srcResName.toLowerCase() + " = " + srcResName.toLowerCase() + ";"); + constructor.setBody(block); + } else { + // Declare an update method in the type of each resource. + ArrayList vars = new ArrayList<>(); + vars.add(new VariableDeclaration( + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + type.addMethod(new MethodDeclaration("update" + srcResName, false, typeVoid, vars)); + } + } + if (constructor.getParameters() != null) + type.addMethod(constructor); + + // Declare input methods in resources and the main type. + for (ChannelGenerator cg : model.getIOChannelGenerators()) { + for (ChannelMember cm : cg.getChannelMembers()) { + if (cm.getIdentifierTemplate().getResourceName().equals(type.getTypeName().toLowerCase())) { + if (cm.getStateTransition().getMessageExpression().getClass() == Term.class) { + ArrayList params = new ArrayList<>(); + params.add(new VariableDeclaration(cm.getIdentifierTemplate().getResourceStateType(), + cm.getIdentifierTemplate().getResourceName())); + MethodDeclaration input = new MethodDeclaration( + ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), + false, typeVoid, params); + type.addMethod(input); + String str; + str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); + input = new MethodDeclaration(str, false, typeVoid, params); + mainType.addMethod(input); + } + } + } + } + + // Declare the field to store the state in the type of each resource. + if (((StoreAttribute) rn.getAttribute()).isStored()) { + String str = "new " + rn.getIdentifierTemplate().getResourceStateType().getImplementationTypeName() + + "()"; + if (!rn.getIdentifierTemplate().getResourceStateType().getTypeName().contains("List")) + str = null; + type.addField(new FieldDeclaration(rn.getIdentifierTemplate().getResourceStateType(), + rn.getIdentifierTemplate().getResourceName(), str)); + } + + // Declare the getter method to obtain the state in the type of each resource. + type.addMethod(new MethodDeclaration("get" + type.getTypeName(), + rn.getIdentifierTemplate().getResourceStateType())); + + // Add compilation unit for each resource. + CompilationUnit cu = new CompilationUnit(type); + cu.addImport(new ImportDeclaration("java.util.*")); + codes.add(cu); + } + + // Declare getter methods in the main type. + for (Node n : graph.getNodes()) { + ResourceNode rn = (ResourceNode) n; + MethodDeclaration getter = new MethodDeclaration( + "get" + rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + + rn.getIdentifierTemplate().getResourceName().substring(1), + rn.getIdentifierTemplate().getResourceStateType()); + getter.setBody(new Block()); + getter.getBody().addStatement( + "return " + rn.getIdentifierTemplate().getResourceName() + "." + getter.getName() + "();"); + mainType.addMethod(getter); + } + + + HashSet tmps = new HashSet<>(); + HashSet cont = new HashSet<>(); + for (MethodDeclaration method : mainType.getMethods()) { + if (!tmps.contains(method.getName())) + tmps.add(method.getName()); + else + cont.add(method.getName()); + } + for (MethodDeclaration method : mainType.getMethods()) { + if (cont.contains(method.getName())) { + method.setName(method.getName() + method.getParameters().get(0).getName().substring(0, 1).toUpperCase() + + method.getParameters().get(0).getName().substring(1)); + } + } + return codes; + } + + static public ArrayList getCodes(ArrayList codeTree) { + ArrayList codes = new ArrayList<>(); + for (TypeDeclaration type : codeTree) { + codes.add("public class " + type.getTypeName() + "{"); + for (FieldDeclaration field : type.getFields()) { + if (type.getTypeName() != mainTypeName) { + String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + + field.getName(); + if (field.getType().equals(DataConstraintModel.typeList)) + cons += " = new ArrayList<>()"; + cons += ";"; + codes.add(cons); + } else { + String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + + field.getName() + " = new " + field.getType().getTypeName() + "("; + for (TypeDeclaration tree : codeTree) { + if (field.getType().getTypeName() == tree.getTypeName()) { + for (VariableDeclaration var : tree.getConstructors()) { + cons += var.getName() + ","; + } + if (!tree.getConstructors().isEmpty()) + cons = cons.substring(0, cons.length() - 1); + break; + } + } + cons += ");"; + codes.add(cons); + } + } + codes.add(""); + if (type.getTypeName() != mainTypeName) { + if (!type.getConstructors().isEmpty()) { + String cons = "\t" + "public " + type.getTypeName() + "("; + for (VariableDeclaration constructor : type.getConstructors()) { + cons += constructor.getType().getTypeName() + " " + constructor.getName() + ","; + } + if (!type.getConstructors().isEmpty()) + cons = cons.substring(0, cons.length() - 1); + cons += "){"; + codes.add(cons); + for (FieldDeclaration field : type.getFields()) { + for (VariableDeclaration vari : type.getConstructors()) { + if (field.getType().getTypeName().equals(vari.getType().getTypeName())) { + codes.add("\t\t" + "this." + field.getName() + " = " + field.getName() + ";"); + } + } + } + codes.add("\t" + "}"); + codes.add(""); + } + } + for (MethodDeclaration method : type.getMethods()) { + String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + + method.getName() + "("; + if (method.getParameters() != null) { + for (VariableDeclaration var : method.getParameters()) { + varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; + } + if (!method.getParameters().isEmpty()) + varstr = varstr.substring(0, varstr.length() - 1); + } + if (method.getBody() != null) { + for (String str : method.getBody().getStatements()) { + codes.add("\t\t" + str + ";"); + } + } + codes.add(varstr + ")" + "{"); + codes.add("\t" + "}"); + codes.add(""); + } + codes.add("}"); + codes.add(""); + } + return codes; + } + + static private ArrayList StoreResourceCheck(ResourceDependencyGraph graph) { + ArrayList resources = new ArrayList<>(); + for (Node n : graph.getNodes()) { + ResourceNode rn = (ResourceNode) n; + boolean flag = true; + for (Edge e : rn.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + flag = false; + } + } + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + flag = false; + } + } + if (flag) + resources.add(rn); + } + trackNode(resources.get(0), resources); + return resources; + } + + static private void trackNode(ResourceNode current, ArrayList resources) { + if (!resources.contains(current)) + resources.add(current); + for (Edge e : current.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + trackNode((ResourceNode) re.getDestination(), resources); + } + } + for (Edge e : current.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + trackNode((ResourceNode) re.getSource(), resources); + } + } + } + + static public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + Term getter = new Term(new Symbol("get" + target.getResourceName().substring(0, 1).toUpperCase() + + target.getResourceName().substring(1), 1, Symbol.Type.METHOD)); + getter.addChild(new Field(target.getResourceName(), target.getResourceStateType())); + return getter; + } + }; +} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java new file mode 100644 index 0000000..1e84b8f --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -0,0 +1,230 @@ +package algorithms; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import code.ast.CompilationUnit; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.DataflowChannelGenerator; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ResourceDependency; +import models.dataFlowModel.ResourceDependencyGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; + +public class JavaMethodBodyGenerator { + public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList codes) { + Symbol floor = model.getSymbol("floor"); + Symbol.Memento floorMem = null; + if (floor != null) { + floorMem = floor.createMemento(); + floor.setImplName("(int)Math.floor"); + floor.setImplOperatorType(Symbol.Type.PREFIX); + } + Symbol sum = model.getSymbol("sum"); + Symbol.Memento sumMem = null; + if (sum != null) { + sumMem = sum.createMemento(); + sum.setImplName("stream().mapToInt(x->x).sum"); + sum.setImplOperatorType(Symbol.Type.METHOD); + } + + // Create a map from type names (lower case) to their types. + Map typeMap = new HashMap<>(); + for (CompilationUnit code: codes) { + for (TypeDeclaration type: code.types()) { + typeMap.put(type.getTypeName().substring(0,1).toLowerCase() + type.getTypeName().substring(1), type); + } + } + + // Generate the body of each update or getter method. + try { + for (Edge e: graph.getEdges()) { + ResourceDependency d = (ResourceDependency) e; + PushPullAttribute pushPull = (PushPullAttribute) d.getAttribute(); + ResourceNode src = (ResourceNode) d.getSource(); + ResourceNode dst = (ResourceNode) d.getDestination(); + String srcResourceName = src.getIdentifierTemplate().getResourceName(); + String dstResourceName = dst.getIdentifierTemplate().getResourceName(); + TypeDeclaration srcType = typeMap.get(srcResourceName); + TypeDeclaration dstType = typeMap.get(dstResourceName); + for (ChannelMember out: d.getChannelGenerator().getOutputChannelMembers()) { + if (out.getIdentifierTemplate() == dst.getIdentifierTemplate()) { + if (pushPull.getOptions().get(0) == PushPullValue.PUSH && srcType != null) { + // for push data transfer + MethodDeclaration update = getUpdateMethod(dstType, srcType); + if (((StoreAttribute) dst.getAttribute()).isStored()) { + // update stored state of dst resource (when every incoming edge is in push style) + Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + String curState = updateExp.toImplementation(); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { + updateStatement = curState + ";"; + } else { + updateStatement = dstResourceName + " = " + curState + ";"; + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } + } + if (dst.getIndegree() > 1) { + // update a cash of src resource (when incoming edges are multiple) + String cashStatement = "this." + srcResourceName + " = " + srcResourceName + ";"; + if (update.getBody() == null || !update.getBody().getStatements().contains(cashStatement)) { + update.addFirstStatement(cashStatement); + } + } + MethodDeclaration getter = getGetterMethod(dstType); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement("return " + dstResourceName + ";"); + } + // src side (for a chain of update method invocations) + for (MethodDeclaration srcUpdate: getUpdateMethods(srcType)) { + srcUpdate.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(" + srcResourceName + ");"); + } + MethodDeclaration srcInput = getInputMethod(srcType, src, model); + if (srcInput != null) srcInput.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(" + srcResourceName + ");"); + } else { + // for pull (or push/pull) data transfer + MethodDeclaration getter = getGetterMethod(dstType); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pullAccessor).toImplementation(); + getter.addStatement("return " + curState + ";"); + } + } + } + } + } + // for source nodes + String mainTypeName = JavaCodeGenerator.mainTypeName.substring(0,1).toLowerCase() + JavaCodeGenerator.mainTypeName.substring(1); + TypeDeclaration mainType = typeMap.get(mainTypeName); + for (Node n: graph.getNodes()) { + ResourceNode resource = (ResourceNode) n; + String resourceName = resource.getIdentifierTemplate().getResourceName(); + TypeDeclaration type = typeMap.get(resourceName); + if (type != null) { + // getter method + MethodDeclaration getter = getGetterMethod(type); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); + } + // methods for input events + Map.Entry ioChannelAndMember = getIOChannelAndMember(resource, model); + if (ioChannelAndMember != null) { + ChannelMember out = ioChannelAndMember.getValue(); + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + if (input != null) { + Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + String newState = updateExp.toImplementation(); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { + updateStatement = newState + ";"; + } else { + updateStatement = "this." + resourceName + " = " + newState + ";"; + } + if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { + input.addFirstStatement(updateStatement); + } + if (mainType != null) { + MethodDeclaration mainInput = getMethod(mainType, input.getName()); + if (mainInput != null) { + mainInput.addStatement("this." + resourceName + "." + input.getName() + "(" + resourceName + ");"); + } + } + } + } + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e1) { + e1.printStackTrace(); + } + + if (floor != null) floor.setMemento(floorMem); + if (sum != null) sum.setMemento(sumMem); + return codes; + } + + private static MethodDeclaration getUpdateMethod(TypeDeclaration type, TypeDeclaration from) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().equals("update" + from.getTypeName())) return m; + } + return null; + } + + private static ArrayList getUpdateMethods(TypeDeclaration type) { + ArrayList updates = new ArrayList<>(); + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().startsWith("update")) { + updates.add(m); + } + } + return updates; + } + + private static MethodDeclaration getGetterMethod(TypeDeclaration type) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().startsWith("get")) return m; + } + return null; + } + + private static Map.Entry getIOChannelAndMember(ResourceNode resource, DataFlowModel model) { + for (ChannelGenerator c: model.getIOChannelGenerators()) { + DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + // I/O channel + for (ChannelMember out: channel.getOutputChannelMembers()) { + if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { + if (out.getStateTransition().getMessageExpression() instanceof Term) { + // not an identity element + return new AbstractMap.SimpleEntry<>(channel, out); + } + } + } + } + return null; + } + + private static MethodDeclaration getInputMethod(TypeDeclaration type, ResourceNode resource, DataFlowModel model) { + for (ChannelGenerator c: model.getIOChannelGenerators()) { + DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + // I/O channel + for (ChannelMember out: channel.getOutputChannelMembers()) { + if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { + if (out.getStateTransition().getMessageExpression() instanceof Term) { + // not an identity element + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + return input; + } + } + } + } + return null; + } + + private static MethodDeclaration getMethod(TypeDeclaration type, String methodName) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().equals(methodName)) return m; + } + return null; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java new file mode 100644 index 0000000..7df3af6 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java @@ -0,0 +1,309 @@ +package algorithms; + +import java.util.ArrayList; +import java.util.HashSet; + +import code.ast.Annotation; +import code.ast.Block; +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.ImportDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.Parameter; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.DataflowChannelGenerator.IResourceStateAccessor; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceDependency; +import models.dataFlowModel.ResourceDependencyGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; + +/** + * Generator for Jersey prototypes + * + * @author Nitta + * + */ +public class JerseyCodeGenerator { + public static final Type typeVoid = new Type("Void", "void"); + public static final Type typeClient = new Type("Client", "Client"); + private static String defaultMainTypeName = "Main"; + static String mainTypeName = defaultMainTypeName; + + public static String getMainTypeName() { + return mainTypeName; + } + + public static void setMainTypeName(String mainTypeName) { + JerseyCodeGenerator.mainTypeName = mainTypeName; + } + + public static void resetMainTypeName() { + JerseyCodeGenerator.mainTypeName = defaultMainTypeName; + } + + static public ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { + ArrayList codes = new ArrayList<>(); + ArrayList resources = StoreResourceCheck(graph); + + for (ResourceNode rn : resources) { + String resourceName = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + + rn.getIdentifierTemplate().getResourceName().substring(1); + + // Declare the field to refer each resource in the main type. + TypeDeclaration type = new TypeDeclaration(resourceName); +// type.addAnnotation(new Annotation("Component")); + type.addAnnotation(new Annotation("Path", "\"/" + rn.getIdentifierTemplate().getResourceName() + "\"")); + + + // Declare a client field and update methods from other resources. + boolean bDeclareClientField = false; + for (Edge e : rn.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (!bDeclareClientField && ((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // Declare a client field to connect to the destination resource of push transfer. + type.addField(new FieldDeclaration(typeClient, "client", "ClientBuilder.newClient()")); + bDeclareClientField = true; + } + } + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + String srcResName = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() + .substring(0, 1).toUpperCase() + + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); + if (!bDeclareClientField && ((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + // Declare a client field to connect to the source resource of pull transfer. + type.addField(new FieldDeclaration(typeClient, "client", "ClientBuilder.newClient()")); + bDeclareClientField = true; + } else { + // Declare an update method in the type of each resource. + ArrayList vars = new ArrayList<>(); + String srcName = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName(); + VariableDeclaration param = new VariableDeclaration(((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), srcName); + param.addAnnotation(new Annotation("FormParam", "\"" + srcName + "\"")); + vars.add(param); + MethodDeclaration update = new MethodDeclaration("update" + srcResName, false, typeVoid, vars); + if (((StoreAttribute) rn.getAttribute()).isNeeded()) { + update.addAnnotation(new Annotation("POST")); + } else { + update.addAnnotation(new Annotation("PUT")); + } + type.addMethod(update); + } + } + + // Declare input methods in resources. + for (ChannelGenerator cg : model.getIOChannelGenerators()) { + for (ChannelMember cm : cg.getChannelMembers()) { + if (cm.getIdentifierTemplate().getResourceName().equals(type.getTypeName().toLowerCase())) { + if (cm.getStateTransition().getMessageExpression().getClass() == Term.class) { + ArrayList params = new ArrayList<>(); + String paramName = cm.getIdentifierTemplate().getResourceName(); + VariableDeclaration param = new VariableDeclaration(cm.getIdentifierTemplate().getResourceStateType(), paramName); + param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); + params.add(param); + MethodDeclaration input = new MethodDeclaration( + ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), + false, typeVoid, params); + input.addAnnotation(new Annotation("PUT")); + type.addMethod(input); + } + } + } + } + + // Declare the field to store the state in the type of each resource. + if (((StoreAttribute) rn.getAttribute()).isStored()) { + String initializer = "new " + rn.getIdentifierTemplate().getResourceStateType().getImplementationTypeName() + "()"; + if (!rn.getIdentifierTemplate().getResourceStateType().getTypeName().contains("List")) + initializer = null; + type.addField(new FieldDeclaration(rn.getIdentifierTemplate().getResourceStateType(), + rn.getIdentifierTemplate().getResourceName(), initializer)); + } + + // Declare the getter method to obtain the state in the type of each resource. + MethodDeclaration getter = new MethodDeclaration("get" + type.getTypeName(), rn.getIdentifierTemplate().getResourceStateType()); + getter.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); + getter.addAnnotation(new Annotation("GET")); + type.addMethod(getter); + + // Add compilation unit for each resource. + CompilationUnit cu = new CompilationUnit(type); + cu.addImport(new ImportDeclaration("java.util.*")); + cu.addImport(new ImportDeclaration("javax.ws.rs.*")); + cu.addImport(new ImportDeclaration("javax.ws.rs.client.*")); + cu.addImport(new ImportDeclaration("javax.ws.rs.core.*")); + codes.add(cu); + } + + return codes; + } + + static public ArrayList getCodes(ArrayList codeTree) { + ArrayList codes = new ArrayList<>(); + for (TypeDeclaration type : codeTree) { + codes.add("public class " + type.getTypeName() + "{"); + for (FieldDeclaration field : type.getFields()) { + if (type.getTypeName() != mainTypeName) { + String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + + field.getName(); + if (field.getType().equals(DataConstraintModel.typeList)) + cons += " = new ArrayList<>()"; + cons += ";"; + codes.add(cons); + } else { + String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + + field.getName() + " = new " + field.getType().getTypeName() + "("; + for (TypeDeclaration tree : codeTree) { + if (field.getType().getTypeName() == tree.getTypeName()) { + for (VariableDeclaration var : tree.getConstructors()) { + cons += var.getName() + ","; + } + if (!tree.getConstructors().isEmpty()) + cons = cons.substring(0, cons.length() - 1); + break; + } + } + cons += ");"; + codes.add(cons); + } + } + codes.add(""); + if (type.getTypeName() != mainTypeName) { + if (!type.getConstructors().isEmpty()) { + String cons = "\t" + "public " + type.getTypeName() + "("; + for (VariableDeclaration constructor : type.getConstructors()) { + cons += constructor.getType().getTypeName() + " " + constructor.getName() + ","; + } + if (!type.getConstructors().isEmpty()) + cons = cons.substring(0, cons.length() - 1); + cons += "){"; + codes.add(cons); + for (FieldDeclaration field : type.getFields()) { + for (VariableDeclaration vari : type.getConstructors()) { + if (field.getType().getTypeName().equals(vari.getType().getTypeName())) { + codes.add("\t\t" + "this." + field.getName() + " = " + field.getName() + ";"); + } + } + } + codes.add("\t" + "}"); + codes.add(""); + } + } + for (MethodDeclaration method : type.getMethods()) { + String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + + method.getName() + "("; + if (method.getParameters() != null) { + for (VariableDeclaration var : method.getParameters()) { + varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; + } + if (!method.getParameters().isEmpty()) + varstr = varstr.substring(0, varstr.length() - 1); + } + if (method.getBody() != null) { + for (String str : method.getBody().getStatements()) { + codes.add("\t\t" + str + ";"); + } + } + codes.add(varstr + ")" + "{"); + codes.add("\t" + "}"); + codes.add(""); + } + codes.add("}"); + codes.add(""); + } + return codes; + } + + static private ArrayList StoreResourceCheck(ResourceDependencyGraph graph) { + ArrayList resources = new ArrayList<>(); + for (Node n : graph.getNodes()) { + ResourceNode rn = (ResourceNode) n; + boolean flag = true; + for (Edge e : rn.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + flag = false; + } + } + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + flag = false; + } + } + if (flag) + resources.add(rn); + } + trackNode(resources.get(0), resources); + return resources; + } + + static private void trackNode(ResourceNode current, ArrayList resources) { + if (!resources.contains(current)) + resources.add(current); + for (Edge e : current.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + trackNode((ResourceNode) re.getDestination(), resources); + } + } + for (Edge e : current.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + trackNode((ResourceNode) re.getSource(), resources); + } + } + } + + static public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; +} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java new file mode 100644 index 0000000..42c453a --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -0,0 +1,256 @@ +package algorithms; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import code.ast.CodeUtil; +import code.ast.CompilationUnit; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.DataflowChannelGenerator; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ResourceDependency; +import models.dataFlowModel.ResourceDependencyGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; + +public class JerseyMethodBodyGenerator { + public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList codes) { + Symbol floor = model.getSymbol("floor"); + Symbol.Memento floorMem = null; + if (floor != null) { + floorMem = floor.createMemento(); + floor.setImplName("(int)Math.floor"); + floor.setImplOperatorType(Symbol.Type.PREFIX); + } + Symbol sum = model.getSymbol("sum"); + Symbol.Memento sumMem = null; + if (sum != null) { + sumMem = sum.createMemento(); + sum.setImplName("stream().mapToInt(x->x).sum"); + sum.setImplOperatorType(Symbol.Type.METHOD); + } + + // Create a map from type names (lower case) to their types. + Map typeMap = new HashMap<>(); + for (CompilationUnit code: codes) { + for (TypeDeclaration type: code.types()) { + typeMap.put(type.getTypeName().substring(0,1).toLowerCase() + type.getTypeName().substring(1), type); + } + } + + // Generate the body of each update or getter method. + try { + Set chainedCalls = new HashSet<>(); + for (Edge e: graph.getEdges()) { + ResourceDependency d = (ResourceDependency) e; + PushPullAttribute pushPull = (PushPullAttribute) d.getAttribute(); + ResourceNode src = (ResourceNode) d.getSource(); + ResourceNode dst = (ResourceNode) d.getDestination(); + String srcResourceName = src.getIdentifierTemplate().getResourceName(); + String dstResourceName = dst.getIdentifierTemplate().getResourceName(); + TypeDeclaration srcType = typeMap.get(srcResourceName); + TypeDeclaration dstType = typeMap.get(dstResourceName); + for (ChannelMember out: d.getChannelGenerator().getOutputChannelMembers()) { + if (out.getIdentifierTemplate() == dst.getIdentifierTemplate()) { + if (pushPull.getOptions().get(0) == PushPullValue.PUSH && srcType != null) { + // for push data transfer + MethodDeclaration update = getUpdateMethod(dstType); + if (((StoreAttribute) dst.getAttribute()).isStored()) { + // update stored state of dst resource (when every incoming edge is in push style) + Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); + String curState = updateExp.toImplementation(); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { + updateStatement = curState + ";"; + } else { + updateStatement = dstResourceName + " = " + curState + ";"; + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } + } + if (dst.getIndegree() > 1) { + // update a cash of src resource (when incoming edges are multiple) + String cashStatement = "this." + srcResourceName + " = " + srcResourceName + ";"; + if (update.getBody() == null || !update.getBody().getStatements().contains(cashStatement)) { + update.addFirstStatement(cashStatement); + } + } + MethodDeclaration getter = getGetterMethod(dstType); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement("return " + dstResourceName + ";"); + } + // src side (for a chain of update method invocations) + String httpMethod = null; + if (((StoreAttribute) dst.getAttribute()).isNeeded()) { + httpMethod = "post"; + } else { + httpMethod = "put"; + } + MethodDeclaration srcUpdate = getUpdateMethod(srcType); + if (srcUpdate != null) { + if (!chainedCalls.contains(srcUpdate)) { + srcUpdate.addStatement(getHttpMethodParamsStatement(srcType.getTypeName(), src.getIdentifierTemplate().getResourceStateType(), srcResourceName)); + srcUpdate.addStatement("String result = " + getHttpMethodCallStatement("http://localhost:8080", dstResourceName, httpMethod)); + chainedCalls.add(srcUpdate); + } else { + srcUpdate.addStatement("result = " + getHttpMethodCallStatement("http://localhost:8080", dstResourceName, httpMethod)); + } + } + MethodDeclaration srcInput = getInputMethod(srcType, src, model); + if (srcInput != null) { + if (!chainedCalls.contains(srcInput)) { + srcInput.addStatement(getHttpMethodParamsStatement(srcType.getTypeName(), src.getIdentifierTemplate().getResourceStateType(), srcResourceName)); + srcInput.addStatement("String result = " + getHttpMethodCallStatement("http://localhost:8080", dstResourceName, httpMethod)); + chainedCalls.add(srcInput); + } else { + srcInput.addStatement("result = " + getHttpMethodCallStatement("http://localhost:8080", dstResourceName, httpMethod)); + } + } + } else { + // for pull (or push/pull) data transfer + MethodDeclaration getter = getGetterMethod(dstType); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement(getHttpMethodCallStatement("http://localhost:8080", srcResourceName, "get", src.getIdentifierTemplate().getResourceStateType())); + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pullAccessor).toImplementation(); + getter.addStatement("return " + curState + ";"); + } + } + } + } + } + // for source nodes + for (Node n: graph.getNodes()) { + ResourceNode resource = (ResourceNode) n; + String resourceName = resource.getIdentifierTemplate().getResourceName(); + TypeDeclaration type = typeMap.get(resourceName); + if (type != null) { + // getter method + MethodDeclaration getter = getGetterMethod(type); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); + } + // methods for input events + Map.Entry ioChannelAndMember = getIOChannelAndMember(resource, model); + if (ioChannelAndMember != null) { + ChannelMember out = ioChannelAndMember.getValue(); + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + if (input != null) { + Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); + String newState = updateExp.toImplementation(); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { + updateStatement = newState + ";"; + } else { + updateStatement = "this." + resourceName + " = " + newState + ";"; + } + if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { + input.addFirstStatement(updateStatement); + } + } + } + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e1) { + e1.printStackTrace(); + } + + if (floor != null) floor.setMemento(floorMem); + if (sum != null) sum.setMemento(sumMem); + return codes; + } + + private static String getHttpMethodParamsStatement(String callerResourceName, Type paramType, String paramName) { + return "Entity
entity = Entity.entity(new Form().param(\"" + paramName + "\", " + CodeUtil.getToStringExp(paramType.getImplementationTypeName(), paramName) + "), MediaType.APPLICATION_FORM_URLENCODED_TYPE);"; + } + + private static String getHttpMethodCallStatement(String baseURL, String resourceName, String httpMethod) { + return "client.target(\"" + baseURL + "\").path(\"/" + resourceName + "\").request()." + httpMethod + "(entity, String.class);"; + } + + private static String getHttpMethodCallStatement(String baseURL, String resourceName, String httpMethod, Type responseType) { + String responseTypeName = responseType.getImplementationTypeName(); + String responseShortTypeName = responseTypeName; + if (responseTypeName.contains("<")) { + responseShortTypeName = responseTypeName.substring(0, responseTypeName.indexOf("<")); + } + return responseTypeName + " " + resourceName + " = client.target(\"" + baseURL + "\").path(\"/" + resourceName + "\").request()." + httpMethod + "(" + responseShortTypeName + ".class);"; + } + + private static MethodDeclaration getUpdateMethod(TypeDeclaration type) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().startsWith("update")) return m; + } + return null; + } + + private static MethodDeclaration getGetterMethod(TypeDeclaration type) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().startsWith("get")) return m; + } + return null; + } + + private static Map.Entry getIOChannelAndMember(ResourceNode resource, DataFlowModel model) { + for (ChannelGenerator c: model.getIOChannelGenerators()) { + DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + // I/O channel + for (ChannelMember out: channel.getOutputChannelMembers()) { + if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { + if (out.getStateTransition().getMessageExpression() instanceof Term) { + // not an identity element + return new AbstractMap.SimpleEntry<>(channel, out); + } + } + } + } + return null; + } + + private static MethodDeclaration getInputMethod(TypeDeclaration type, ResourceNode resource, DataFlowModel model) { + for (ChannelGenerator c: model.getIOChannelGenerators()) { + DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + // I/O channel + for (ChannelMember out: channel.getOutputChannelMembers()) { + if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { + if (out.getStateTransition().getMessageExpression() instanceof Term) { + // not an identity element + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + return input; + } + } + } + } + return null; + } + + private static MethodDeclaration getMethod(TypeDeclaration type, String methodName) { + for (MethodDeclaration m: type.getMethods()) { + if (m.getName().equals(methodName)) return m; + } + return null; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java deleted file mode 100644 index c2c7d88..0000000 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java +++ /dev/null @@ -1,230 +0,0 @@ -package algorithms; - -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import code.ast.CompilationUnit; -import code.ast.MethodDeclaration; -import code.ast.TypeDeclaration; -import models.Edge; -import models.Node; -import models.algebra.Expression; -import models.algebra.InvalidMessage; -import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.Symbol; -import models.algebra.Term; -import models.algebra.UnificationFailed; -import models.algebra.ValueUndefined; -import models.dataConstraintModel.ChannelGenerator; -import models.dataConstraintModel.ChannelMember; -import models.dataFlowModel.DataFlowModel; -import models.dataFlowModel.DataflowChannelGenerator; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.PushPullValue; -import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; -import models.dataFlowModel.ResourceDependency; -import models.dataFlowModel.ResourceDependencyGraph; -import models.dataFlowModel.ResourceNode; -import models.dataFlowModel.StoreAttribute; - -public class MethodBodyGenerator { - public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList codes) { - Symbol floor = model.getSymbol("floor"); - Symbol.Memento floorMem = null; - if (floor != null) { - floorMem = floor.createMemento(); - floor.setImplName("(int)Math.floor"); - floor.setImplOperatorType(Symbol.Type.PREFIX); - } - Symbol sum = model.getSymbol("sum"); - Symbol.Memento sumMem = null; - if (sum != null) { - sumMem = sum.createMemento(); - sum.setImplName("stream().mapToInt(x->x).sum"); - sum.setImplOperatorType(Symbol.Type.METHOD); - } - - // Create a map from type names (lower case) to their types. - Map typeMap = new HashMap<>(); - for (CompilationUnit code: codes) { - for (TypeDeclaration type: code.types()) { - typeMap.put(type.getTypeName().substring(0,1).toLowerCase() + type.getTypeName().substring(1), type); - } - } - - // Generate the body of each update or getter method. - try { - for (Edge e: graph.getEdges()) { - ResourceDependency d = (ResourceDependency) e; - PushPullAttribute pushPull = (PushPullAttribute) d.getAttribute(); - ResourceNode src = (ResourceNode) d.getSource(); - ResourceNode dst = (ResourceNode) d.getDestination(); - String srcResourceName = src.getIdentifierTemplate().getResourceName(); - String dstResourceName = dst.getIdentifierTemplate().getResourceName(); - TypeDeclaration srcType = typeMap.get(srcResourceName); - TypeDeclaration dstType = typeMap.get(dstResourceName); - for (ChannelMember out: d.getChannelGenerator().getOutputChannelMembers()) { - if (out.getIdentifierTemplate() == dst.getIdentifierTemplate()) { - if (pushPull.getOptions().get(0) == PushPullValue.PUSH && srcType != null) { - // for push data transfer - MethodDeclaration update = getUpdateMethod(dstType, srcType); - if (((StoreAttribute) dst.getAttribute()).isStored()) { - // update stored state of dst resource (when every incoming edge is in push style) - Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, CodeGenerator.pushAccessor); - String curState = updateExp.toImplementation(); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { - updateStatement = curState + ";"; - } else { - updateStatement = dstResourceName + " = " + curState + ";"; - } - if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { - update.addFirstStatement(updateStatement); - } - } - if (dst.getIndegree() > 1) { - // update a cash of src resource (when incoming edges are multiple) - String cashStatement = "this." + srcResourceName + " = " + srcResourceName + ";"; - if (update.getBody() == null || !update.getBody().getStatements().contains(cashStatement)) { - update.addFirstStatement(cashStatement); - } - } - MethodDeclaration getter = getGetterMethod(dstType); - if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { - getter.addStatement("return " + dstResourceName + ";"); - } - // src side (for a chain of update method invocations) - for (MethodDeclaration srcUpdate: getUpdateMethods(srcType)) { - srcUpdate.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(" + srcResourceName + ");"); - } - MethodDeclaration srcInput = getInputMethod(srcType, src, model); - if (srcInput != null) srcInput.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(" + srcResourceName + ");"); - } else { - // for pull (or push/pull) data transfer - MethodDeclaration getter = getGetterMethod(dstType); - if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { - String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, CodeGenerator.pullAccessor).toImplementation(); - getter.addStatement("return " + curState + ";"); - } - } - } - } - } - // for source nodes - String mainTypeName = CodeGenerator.mainTypeName.substring(0,1).toLowerCase() + CodeGenerator.mainTypeName.substring(1); - TypeDeclaration mainType = typeMap.get(mainTypeName); - for (Node n: graph.getNodes()) { - ResourceNode resource = (ResourceNode) n; - String resourceName = resource.getIdentifierTemplate().getResourceName(); - TypeDeclaration type = typeMap.get(resourceName); - if (type != null) { - // getter method - MethodDeclaration getter = getGetterMethod(type); - if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { - getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); - } - // methods for input events - Map.Entry ioChannelAndMember = getIOChannelAndMember(resource, model); - if (ioChannelAndMember != null) { - ChannelMember out = ioChannelAndMember.getValue(); - Term message = (Term) out.getStateTransition().getMessageExpression(); - MethodDeclaration input = getMethod(type, message.getSymbol().getName()); - if (input != null) { - Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, CodeGenerator.pushAccessor); - String newState = updateExp.toImplementation(); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().getImplOperatorType() == Symbol.Type.METHOD_WITH_SIDE_EFFECT) { - updateStatement = newState + ";"; - } else { - updateStatement = "this." + resourceName + " = " + newState + ";"; - } - if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { - input.addFirstStatement(updateStatement); - } - if (mainType != null) { - MethodDeclaration mainInput = getMethod(mainType, input.getName()); - if (mainInput != null) { - mainInput.addStatement("this." + resourceName + "." + input.getName() + "(" + resourceName + ");"); - } - } - } - } - } - } - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e1) { - e1.printStackTrace(); - } - - if (floor != null) floor.setMemento(floorMem); - if (sum != null) sum.setMemento(sumMem); - return codes; - } - - private static MethodDeclaration getUpdateMethod(TypeDeclaration type, TypeDeclaration from) { - for (MethodDeclaration m: type.getMethods()) { - if (m.getName().equals("update" + from.getTypeName())) return m; - } - return null; - } - - private static ArrayList getUpdateMethods(TypeDeclaration type) { - ArrayList updates = new ArrayList<>(); - for (MethodDeclaration m: type.getMethods()) { - if (m.getName().startsWith("update")) { - updates.add(m); - } - } - return updates; - } - - private static MethodDeclaration getGetterMethod(TypeDeclaration type) { - for (MethodDeclaration m: type.getMethods()) { - if (m.getName().startsWith("get")) return m; - } - return null; - } - - private static Map.Entry getIOChannelAndMember(ResourceNode resource, DataFlowModel model) { - for (ChannelGenerator c: model.getIOChannelGenerators()) { - DataflowChannelGenerator channel = (DataflowChannelGenerator) c; - // I/O channel - for (ChannelMember out: channel.getOutputChannelMembers()) { - if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { - if (out.getStateTransition().getMessageExpression() instanceof Term) { - // not an identity element - return new AbstractMap.SimpleEntry<>(channel, out); - } - } - } - } - return null; - } - - private static MethodDeclaration getInputMethod(TypeDeclaration type, ResourceNode resource, DataFlowModel model) { - for (ChannelGenerator c: model.getIOChannelGenerators()) { - DataflowChannelGenerator channel = (DataflowChannelGenerator) c; - // I/O channel - for (ChannelMember out: channel.getOutputChannelMembers()) { - if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { - if (out.getStateTransition().getMessageExpression() instanceof Term) { - // not an identity element - Term message = (Term) out.getStateTransition().getMessageExpression(); - MethodDeclaration input = getMethod(type, message.getSymbol().getName()); - return input; - } - } - } - } - return null; - } - - private static MethodDeclaration getMethod(TypeDeclaration type, String methodName) { - for (MethodDeclaration m: type.getMethods()) { - if (m.getName().equals(methodName)) return m; - } - return null; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/SelectableDataTransfers.java b/AlgebraicDataflowArchitectureModel/src/algorithms/SelectableDataTransfers.java index 7975e57..5747583 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/SelectableDataTransfers.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/SelectableDataTransfers.java @@ -5,10 +5,6 @@ public class SelectableDataTransfers { static public ResourceDependencyGraph init(ResourceDependencyGraph graph) { - PushPullAttribute ppat = new PushPullAttribute(); - ppat.addOption(PushPullValue.PUSHorPULL); - ppat.addOption(PushPullValue.PUSH); - ppat.addOption(PushPullValue.PULL); for (Node n : graph.getNodes()) { if (((StoreAttribute) ((ResourceNode) n).getAttribute()).isNeeded()) { trackEdges(n); @@ -16,6 +12,10 @@ } for (Edge e : graph.getEdges()) { if (((ResourceDependency) e).getAttribute() == null) { + PushPullAttribute ppat = new PushPullAttribute(); + ppat.addOption(PushPullValue.PUSHorPULL); + ppat.addOption(PushPullValue.PUSH); + ppat.addOption(PushPullValue.PULL); ((ResourceDependency) e).setAttribute(ppat); } } @@ -23,9 +23,9 @@ } static private void trackEdges(Node n) { - PushPullAttribute ppat = new PushPullAttribute(); - ppat.addOption(PushPullValue.PUSH); for (Edge e : ((ResourceNode) n).getInEdges()) { + PushPullAttribute ppat = new PushPullAttribute(); + ppat.addOption(PushPullValue.PUSH); ((ResourceDependency) e).setAttribute(ppat); } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Annotation.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Annotation.java new file mode 100644 index 0000000..15b1e6a --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Annotation.java @@ -0,0 +1,57 @@ +package code.ast; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class Annotation extends ASTNode { + private String name = null; + private Map keyValueMap = null; + + public Annotation(String name) { + this.name = name; + keyValueMap = new HashMap<>(); + } + + public Annotation(String name, String value) { + this.name = name; + keyValueMap = new HashMap<>(); + keyValueMap.put("value", value); + } + + public String getElementName() { + return name; + } + + public Map getParams() { + return keyValueMap; + } + + public Object getValue(String key) { + return keyValueMap.get(key); + } + + public void addParam(String key, Object value) { + keyValueMap.put(key, value); + } + + public String toString() { + String code = "@" + name; + Set keySet = keyValueMap.keySet(); + if (keySet.size() == 0) { + return code; + } else if (keySet.size() == 1 && keySet.iterator().next().equals("value")) { + code += "(" + keyValueMap.get("value").toString() + ")"; + } else { + code += "("; + String delimitar = ""; + for (String key: keySet) { + Object value = keyValueMap.get(key); + code += delimitar + key + " = \"" + value.toString() + "\""; + delimitar = ", "; + } + code += ")"; + } + return code; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/CodeUtil.java b/AlgebraicDataflowArchitectureModel/src/code/ast/CodeUtil.java index 4322271..99f1561 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/CodeUtil.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/CodeUtil.java @@ -11,4 +11,33 @@ return newString; } + public static String getToStringExp(String typeName, String rawExp) { + if (typeName.equals("int")) { + return "Integer.toString(" + rawExp + ")"; + } else if (typeName.equals("float")) { + return "Float.toString(" + rawExp + ")"; + } else if (typeName.equals("double")) { + return "Double.toString(" + rawExp + ")"; + } else if (typeName.equals("boolean")) { + return "Boolean.toString(" + rawExp + ")"; + } else { + return rawExp + ".toString()"; + } + } + + public static String getToValueExp(String typeName, String strExp) { + if (typeName.equals("int")) { + return "Integer.parseInt(" + strExp + ")"; + } else if (typeName.equals("float")) { + return "Float.parseFloat(" + strExp + ")"; + } else if (typeName.equals("double")) { + return "Double.parseDouble(" + strExp + ")"; + } else if (typeName.equals("boolean")) { + return "Boolean.parseBoolean(" + strExp + ")"; + } else if (typeName.startsWith("ArrayList") || typeName.startsWith("List")) { + return "Arrays.asList(" + strExp + ".replace(\"[\",\"\").replace(\"]\",\"\").split(\",\",0))"; + } else { + return strExp; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java index 1e90895..b5e2dca 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java @@ -1,11 +1,16 @@ package code.ast; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import models.algebra.Type; -public class FieldDeclaration extends BodyDeclaration { +public class FieldDeclaration extends BodyDeclaration implements IAnnotatable { private Type type; private String fieldName; private String initializer; + private Map annotations = new HashMap<>(); public FieldDeclaration(Type type, String fieldName) { this.type = type; @@ -42,10 +47,31 @@ this.initializer = initializer; } + @Override + public Annotation getAnnotation(String name) { + return annotations.get(name); + } + + @Override + public Collection getAnnotations() { + return annotations.values(); + } + + @Override + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.getElementName(), annotation); + } + public String toString() { - if (initializer == null) { - return "private " + type.getImplementationTypeName() + " " + fieldName + ";\n"; + String code = ""; + for (Annotation annotation: getAnnotations()) { + code += annotation.toString() + "\n"; } - return "private " + type.getImplementationTypeName() + " " + fieldName + " = " + initializer + ";\n"; + if (initializer == null) { + code += "private " + type.getImplementationTypeName() + " " + fieldName + ";\n"; + } else { + code += "private " + type.getImplementationTypeName() + " " + fieldName + " = " + initializer + ";\n"; + } + return code; } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/IAnnotatable.java b/AlgebraicDataflowArchitectureModel/src/code/ast/IAnnotatable.java new file mode 100644 index 0000000..47001e5 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/IAnnotatable.java @@ -0,0 +1,9 @@ +package code.ast; + +import java.util.Collection; + +public interface IAnnotatable { + Annotation getAnnotation(String name); + Collection getAnnotations(); + void addAnnotation(Annotation annotation); +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index 6705cf6..f4d5b6a 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -1,15 +1,20 @@ package code.ast; import java.util.List; +import java.util.Map; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; + import models.algebra.Type; -public class MethodDeclaration extends BodyDeclaration { +public class MethodDeclaration extends BodyDeclaration implements IAnnotatable { private String name = null; private boolean isConstructor = false; private Type returnType = null; private List parameters = null; private Block body = null; + private Map annotations = new HashMap<>(); public MethodDeclaration(String methodName) { this(methodName, false); @@ -96,9 +101,28 @@ } body.addFirstStatement(statement); } + + @Override + public Annotation getAnnotation(String name) { + return annotations.get(name); + } + + @Override + public Collection getAnnotations() { + return annotations.values(); + } + + @Override + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.getElementName(), annotation); + } public String toString() { - String code = "public "; + String code = ""; + for (Annotation annotation: getAnnotations()) { + code += annotation.toString() + "\n"; + } + code += "public "; if (returnType == null) { if(!isConstructor) code += "void "; }else { diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java index 153a47a..0d97782 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java @@ -1,12 +1,16 @@ package code.ast; import java.util.List; +import java.util.Map; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; -public class TypeDeclaration extends AbstractTypeDeclaration { +public class TypeDeclaration extends AbstractTypeDeclaration implements IAnnotatable { private List fields = new ArrayList<>(); private List methods = new ArrayList<>(); private List constructors = new ArrayList<>(); + private Map annotations = new HashMap<>(); public TypeDeclaration(String typeName) { this.typeName = typeName; @@ -53,9 +57,28 @@ public List getConstructors() { return constructors; } + + @Override + public Annotation getAnnotation(String name) { + return annotations.get(name); + } + + @Override + public Collection getAnnotations() { + return annotations.values(); + } + + @Override + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.getElementName(), annotation); + } public String toString() { - String code = "public class " + typeName + " {\n"; + String code = ""; + for (Annotation annotation: getAnnotations()) { + code += annotation.toString() + "\n"; + } + code += "public class " + typeName + " {\n"; for (FieldDeclaration f: fields) { code += "\t" + f.toString(); } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java index 1e21603..7e30d18 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java @@ -1,10 +1,15 @@ package code.ast; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import models.algebra.Type; -public class VariableDeclaration extends ASTNode { +public class VariableDeclaration extends ASTNode implements IAnnotatable { private Type type; private String variableName; + private Map annotations = new HashMap<>(); public VariableDeclaration(Type type, String variableName) { this.type = type; @@ -26,8 +31,28 @@ public void setName(String variableName) { this.variableName = variableName; } + + @Override + public Annotation getAnnotation(String name) { + return annotations.get(name); + } + + @Override + public Collection getAnnotations() { + return annotations.values(); + } + + @Override + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.getElementName(), annotation); + } public String toString() { - return type.getImplementationTypeName() + " " + variableName; + String code = ""; + for (Annotation annotation: getAnnotations()) { + code += annotation.toString() + " "; + } + code += type.getImplementationTypeName() + " " + variableName; + return code; } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java new file mode 100644 index 0000000..7205732 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java @@ -0,0 +1,81 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JFileChooser; + +import algorithms.*; +import code.ast.*; +import graphicalrefactor.editor.Editor; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.ResourceDependencyGraph; + +public class JavaPrototypeGenerateAction extends AbstractEditorAction { + /** + * + */ + private static final long serialVersionUID = -3694103632055735068L; + + private String lastDir = null; + + public JavaPrototypeGenerateAction(Editor editor) { + super("Generate Plain Java Prototype", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + ResourceDependencyGraph graph = editor.getResourceDependencyGraph(); + if (graph != null) { + DataFlowModel model = editor.getModel(); + FinalDecisionOfStoringResourceStates.doDecide(graph); + String fileName = editor.getCurFileName(); + String mainTypeName = fileName.split("\\.")[0]; + boolean exist = false; + for (IdentifierTemplate id: model.getIdentifierTemplates()) { + String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); + if (mainTypeName.equals(resourceName)) { + exist = true; + } + } + if (!exist) { + JavaCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + } else { + JavaCodeGenerator.resetMainTypeName(); // use the default main type's name. + } + editor.setCodes(JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model))); + for (CompilationUnit file : editor.getCodes()) { + System.out.println(file); + } + + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + JFileChooser fc = new JFileChooser(wd); + fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + int rc = fc.showSaveDialog(null); + if (rc == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getPath(); + for (CompilationUnit cu : editor.getCodes()) { + save(fc.getSelectedFile(), cu); + } + } + } + } + + private void save(File dir, CompilationUnit cu) { + File javaFile = new File(dir.getPath(), cu.getFileName()); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); + writer.write(cu.toString()); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java new file mode 100644 index 0000000..204f061 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java @@ -0,0 +1,81 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JFileChooser; + +import algorithms.*; +import code.ast.*; +import graphicalrefactor.editor.Editor; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.ResourceDependencyGraph; + +public class JerseyPrototypeGenerateAction extends AbstractEditorAction { + /** + * + */ + private static final long serialVersionUID = 1117065654665887436L; + + private String lastDir = null; + + public JerseyPrototypeGenerateAction(Editor editor) { + super("Generate Jersey Prototype", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + ResourceDependencyGraph graph = editor.getResourceDependencyGraph(); + if (graph != null) { + DataFlowModel model = editor.getModel(); + FinalDecisionOfStoringResourceStates.doDecide(graph); + String fileName = editor.getCurFileName(); + String mainTypeName = fileName.split("\\.")[0]; + boolean exist = false; + for (IdentifierTemplate id: model.getIdentifierTemplates()) { + String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); + if (mainTypeName.equals(resourceName)) { + exist = true; + } + } + if (!exist) { + JerseyCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + } else { + JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. + } + editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); + for (CompilationUnit file : editor.getCodes()) { + System.out.println(file); + } + + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + JFileChooser fc = new JFileChooser(wd); + fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + int rc = fc.showSaveDialog(null); + if (rc == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getPath(); + for (CompilationUnit cu : editor.getCodes()) { + save(fc.getSelectedFile(), cu); + } + } + } + } + + private void save(File dir, CompilationUnit cu) { + File javaFile = new File(dir.getPath(), cu.getFileName()); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); + writer.write(cu.toString()); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java deleted file mode 100644 index 747fdb5..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java +++ /dev/null @@ -1,81 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -import javax.swing.JFileChooser; - -import algorithms.*; -import code.ast.*; -import graphicalrefactor.editor.Editor; -import models.dataConstraintModel.IdentifierTemplate; -import models.dataFlowModel.DataFlowModel; -import models.dataFlowModel.ResourceDependencyGraph; - -public class PrototypeGenerateAction extends AbstractEditorAction { - /** - * - */ - private static final long serialVersionUID = -3694103632055735068L; - - private String lastDir = null; - - public PrototypeGenerateAction(Editor editor) { - super("Generate Prototype", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - ResourceDependencyGraph graph = editor.getResourceDependencyGraph(); - if (graph != null) { - DataFlowModel model = editor.getModel(); - FinalDecisionOfStoringResourceStates.doDecide(graph); - String fileName = editor.getCurFileName(); - String mainTypeName = fileName.split("\\.")[0]; - boolean exist = false; - for (IdentifierTemplate id: model.getIdentifierTemplates()) { - String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); - if (mainTypeName.equals(resourceName)) { - exist = true; - } - } - if (!exist) { - CodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. - } else { - CodeGenerator.resetMainTypeName(); // use the default main type's name. - } - editor.setCodes(MethodBodyGenerator.doGenerate(graph, model, CodeGenerator.doGenerate(graph, model))); - for (CompilationUnit file : editor.getCodes()) { - System.out.println(file); - } - - String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); - JFileChooser fc = new JFileChooser(wd); - fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - int rc = fc.showSaveDialog(null); - if (rc == JFileChooser.APPROVE_OPTION) { - lastDir = fc.getSelectedFile().getPath(); - for (CompilationUnit cu : editor.getCodes()) { - save(fc.getSelectedFile(), cu); - } - } - } - } - - private void save(File dir, CompilationUnit cu) { - File javaFile = new File(dir.getPath(), cu.getFileName()); - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); - writer.write(cu.toString()); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java index 568a13a..16a15a6 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java @@ -94,7 +94,7 @@ try { model = parser.doParse(); curFileName = file.getName(); - if(!UpdateConflictCheck.run(model)) return null; + if (!UpdateConflictCheck.run(model)) return null; ResourceDependencyGraph resourceGraph = NecessityOfStoringResourceStates.doDecide(model); resourceDependencyGraph = SelectableDataTransfers.init(resourceGraph); graph = constructGraph(model, resourceDependencyGraph); diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java index bf80b1b..1584119 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java @@ -9,7 +9,8 @@ import graphicalrefactor.actions.CircleLayoutAction; import graphicalrefactor.actions.ExitAction; import graphicalrefactor.actions.OpenAction; -import graphicalrefactor.actions.PrototypeGenerateAction; +import graphicalrefactor.actions.JavaPrototypeGenerateAction; +import graphicalrefactor.actions.JerseyPrototypeGenerateAction; import graphicalrefactor.actions.SaveAction; import graphicalrefactor.actions.TreeLayoutAction; import graphicalrefactor.actions.ZoomInAction; @@ -21,7 +22,8 @@ private GraphicalRefactor graphicalModelRefactor = null; private OpenAction openAction = null; - private PrototypeGenerateAction prototypeGenerateAction = null; + private JavaPrototypeGenerateAction javaPrototypeGenerateAction = null; + private JerseyPrototypeGenerateAction jerseyPrototypeGenerateAction = null; private TreeLayoutAction treeLayoutAction = null; private CircleLayoutAction circleLayoutAction = null; @@ -44,7 +46,8 @@ menu.add(new ZoomOutAction(graphicalModelRefactor.getGraphComponent())); menu = add(new JMenu("Generate")); - menu.add(prototypeGenerateAction = new PrototypeGenerateAction(graphicalModelRefactor.getEditor())); + menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(graphicalModelRefactor.getEditor())); + menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(graphicalModelRefactor.getEditor())); } public Editor getEditor() { @@ -53,7 +56,7 @@ public void setEditor(Editor editor) { openAction.setEditor(editor); - prototypeGenerateAction.setEditor(editor); + javaPrototypeGenerateAction.setEditor(editor); treeLayoutAction.setEditor(editor); circleLayoutAction.setEditor(editor); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index e5bf77d..7011bcd 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -192,6 +192,9 @@ public String toImplementation() { + if (symbol.getName().equals("if") && symbol.getArity() == 3) { + return children.get(0).toImplementation() + "?" + children.get(1).toImplementation() + ":" + children.get(2).toImplementation(); + } int[] implParamOrder = symbol.getImplParamOrder(); if (getArity() == 2 && symbol.isImplInfix()) { if (implParamOrder == null) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index c718d72..1200710 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -30,7 +30,9 @@ public static final Symbol body = new Symbol("tail", 1, Symbol.Type.PREFIX, "tail", Symbol.Type.METHOD); public static final Symbol cond = new Symbol("if", 3); public static final Symbol eq = new Symbol("eq", 2, Symbol.Type.PREFIX, "==", Symbol.Type.INFIX); - + public static final Symbol gt = new Symbol("gt", 2, Symbol.Type.PREFIX, ">", Symbol.Type.INFIX); + public static final Symbol lt = new Symbol("lt", 2, Symbol.Type.PREFIX, "<", Symbol.Type.INFIX); + static { add.setInverses(new Symbol[] {sub, sub}); mul.setInverses(new Symbol[] {div, div}); @@ -62,6 +64,8 @@ addSymbol(body); addSymbol(cond); addSymbol(eq); + addSymbol(gt); + addSymbol(lt); } public Collection getIdentifierTemplates() { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java index 9e10576..ffba2e3 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java @@ -23,7 +23,7 @@ ResourceDependencyGraph graph = NecessityOfStoringResourceStates.doDecide(model); SelectableDataTransfers.init(graph); FinalDecisionOfStoringResourceStates.doDecide(graph); - ArrayList codetree = MethodBodyGenerator.doGenerate(graph, model, CodeGenerator.doGenerate(graph, model)); + ArrayList codetree = JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model)); System.out.println(codetree); } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression