diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java index 83a1e19..25de41f 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -224,14 +224,14 @@ codes.add("public class " + type.getTypeName() + "{"); for (FieldDeclaration field : type.getFields()) { if (type.getTypeName() != mainTypeName) { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + String cons = "\t" + "private " + field.getType().getInterfaceTypeName() + " " + field.getName(); if (field.getType().equals(DataConstraintModel.typeList)) cons += " = new ArrayList<>()"; cons += ";"; codes.add(cons); } else { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + String cons = "\t" + "private " + field.getType().getInterfaceTypeName() + " " + field.getName() + " = new " + field.getType().getTypeName() + "("; for (TypeDeclaration tree : codeTree) { if (field.getType().getTypeName() == tree.getTypeName()) { @@ -270,11 +270,11 @@ } } for (MethodDeclaration method : type.getMethods()) { - String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + String varstr = "\t" + "public " + method.getReturnType().getInterfaceTypeName() + " " + method.getName() + "("; if (method.getParameters() != null) { for (VariableDeclaration var : method.getParameters()) { - varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; + varstr += var.getType().getInterfaceTypeName() + " " + var.getName() + ","; } if (!method.getParameters().isEmpty()) varstr = varstr.substring(0, varstr.length() - 1); diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index 1e84b8f..650fa06 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -75,7 +75,7 @@ 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) { + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { updateStatement = curState + ";"; } else { updateStatement = dstResourceName + " = " + curState + ";"; @@ -135,7 +135,7 @@ 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) { + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { updateStatement = newState + ";"; } else { updateStatement = "this." + resourceName + " = " + newState + ";"; diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java index 7df3af6..8cf0ab2 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java @@ -69,7 +69,6 @@ // 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()) { @@ -159,14 +158,14 @@ codes.add("public class " + type.getTypeName() + "{"); for (FieldDeclaration field : type.getFields()) { if (type.getTypeName() != mainTypeName) { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + String cons = "\t" + "private " + field.getType().getInterfaceTypeName() + " " + field.getName(); if (field.getType().equals(DataConstraintModel.typeList)) cons += " = new ArrayList<>()"; cons += ";"; codes.add(cons); } else { - String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + String cons = "\t" + "private " + field.getType().getInterfaceTypeName() + " " + field.getName() + " = new " + field.getType().getTypeName() + "("; for (TypeDeclaration tree : codeTree) { if (field.getType().getTypeName() == tree.getTypeName()) { @@ -205,11 +204,11 @@ } } for (MethodDeclaration method : type.getMethods()) { - String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + String varstr = "\t" + "public " + method.getReturnType().getInterfaceTypeName() + " " + method.getName() + "("; if (method.getParameters() != null) { for (VariableDeclaration var : method.getParameters()) { - varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; + varstr += var.getType().getInterfaceTypeName() + " " + var.getName() + ","; } if (!method.getParameters().isEmpty()) varstr = varstr.substring(0, varstr.length() - 1); diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java index 42c453a..9b976f4 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -45,10 +45,19 @@ Symbol sum = model.getSymbol("sum"); Symbol.Memento sumMem = null; if (sum != null) { + // for the list of strings. sumMem = sum.createMemento(); - sum.setImplName("stream().mapToInt(x->x).sum"); + sum.setImplName("stream().mapToInt(x->Integer.parseInt(x)).sum"); sum.setImplOperatorType(Symbol.Type.METHOD); } + Symbol cons = model.getSymbol("cons"); + Symbol.Memento consMem = null; + if (cons != null) { + // for the list of strings. + consMem = cons.createMemento(); + cons.setImplName("($x,$y)->$x.add(Integer.toString($y))"); + cons.setImplOperatorType(Symbol.Type.LAMBDA_WITH_SIDE_EFFECT); + } // Create a map from type names (lower case) to their types. Map typeMap = new HashMap<>(); @@ -80,7 +89,7 @@ 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) { + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { updateStatement = curState + ";"; } else { updateStatement = dstResourceName + " = " + curState + ";"; @@ -160,7 +169,7 @@ 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) { + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { updateStatement = newState + ";"; } else { updateStatement = "this." + resourceName + " = " + newState + ";"; @@ -179,10 +188,17 @@ if (floor != null) floor.setMemento(floorMem); if (sum != null) sum.setMemento(sumMem); + if (cons != null) cons.setMemento(consMem); return codes; } private static String getHttpMethodParamsStatement(String callerResourceName, Type paramType, String paramName) { + if (paramType.getTypeName().equals("List")) { + String statements = "MultivaluedHashMap list = new MultivaluedHashMap();\n"; + statements += "list.addAll(\"" + paramName + "\", "+ paramName + ");\n"; + statements += "Entity
entity = Entity.entity(new Form(list), MediaType.APPLICATION_FORM_URLENCODED);"; + return statements; + } return "Entity entity = Entity.entity(new Form().param(\"" + paramName + "\", " + CodeUtil.getToStringExp(paramType.getImplementationTypeName(), paramName) + "), MediaType.APPLICATION_FORM_URLENCODED_TYPE);"; } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java index b5e2dca..0993b92 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java @@ -68,9 +68,9 @@ code += annotation.toString() + "\n"; } if (initializer == null) { - code += "private " + type.getImplementationTypeName() + " " + fieldName + ";\n"; + code += "private " + type.getInterfaceTypeName() + " " + fieldName + ";\n"; } else { - code += "private " + type.getImplementationTypeName() + " " + fieldName + " = " + initializer + ";\n"; + code += "private " + type.getInterfaceTypeName() + " " + fieldName + " = " + initializer + ";\n"; } return code; } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index f4d5b6a..6389e16 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -126,7 +126,7 @@ if (returnType == null) { if(!isConstructor) code += "void "; }else { - code += returnType.getImplementationTypeName() + " "; + code += returnType.getInterfaceTypeName() + " "; } code += (name + "("); if (parameters != null) { diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java index 7e30d18..6a7b25b 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclaration.java @@ -52,7 +52,7 @@ for (Annotation annotation: getAnnotations()) { code += annotation.toString() + " "; } - code += type.getImplementationTypeName() + " " + variableName; + code += type.getInterfaceTypeName() + " " + variableName; return code; } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java index 204f061..2ac5444 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java @@ -13,6 +13,7 @@ import algorithms.*; import code.ast.*; import graphicalrefactor.editor.Editor; +import models.algebra.Type; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.ResourceDependencyGraph; @@ -49,6 +50,16 @@ } else { JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. } + + Type list = model.getType("List"); + Type.Memento listMem = null; + if (list != null) { + // Only a list of strings can be passed as a form parameter of PUT/POST method. + listMem = list.createMemento(); + list.setImplementationTypeName("ArrayList"); + list.setInterfaceTypeName("List"); + } + editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); for (CompilationUnit file : editor.getCodes()) { System.out.println(file); @@ -64,6 +75,8 @@ save(fc.getSelectedFile(), cu); } } + + if (list != null) list.setMemento(listMem); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java index 6e1788d..5455843 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java @@ -104,6 +104,14 @@ public boolean isImplMethod() { return (implOperatorType == Type.METHOD || implOperatorType == Type.METHOD_WITH_SIDE_EFFECT); } + + public boolean isImplLambda() { + return (implOperatorType == Type.LAMBDA || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT); + } + + public boolean isImplWithSideEffect() { + return (implOperatorType == Type.METHOD_WITH_SIDE_EFFECT || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT); + } public void setImplOperatorType(Type implOperatorType) { this.implOperatorType = implOperatorType; @@ -135,7 +143,9 @@ PREFIX, INFIX, METHOD, - METHOD_WITH_SIDE_EFFECT + METHOD_WITH_SIDE_EFFECT, + LAMBDA, + LAMBDA_WITH_SIDE_EFFECT } public Memento createMemento() { diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index 7011bcd..ecd85a4 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -192,10 +192,23 @@ 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 (symbol.isImplLambda()) { + String[] components = symbol.getImplName().split("->"); + String component0 = components[0].replace("(", "").replace(")", ""); + String[] params = component0.split(","); + String exp = components[1]; + if (implParamOrder == null) { + for (int i = 0; i < params.length; i++) { + exp = exp.replace(params[i], children.get(i).toImplementation()); + } + } else { + for (int i = 0; i < params.length; i++) { + exp = exp.replace(params[i], children.get(implParamOrder[i]).toImplementation()); + } + } + return exp; + } if (getArity() == 2 && symbol.isImplInfix()) { if (implParamOrder == null) { return "(" + children.get(0).toImplementation() + symbol.toImplementation() + children.get(1).toImplementation() + ")"; diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java index c65b07d..7241bed 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java @@ -3,10 +3,18 @@ public class Type { private String typeName; private String implementationTypeName; + private String interfaceTypeName; public Type(String typeName, String implementastionTypeName) { this.typeName = typeName; this.implementationTypeName = implementastionTypeName; + this.interfaceTypeName = implementastionTypeName; + } + + public Type(String typeName, String implementastionTypeName, String interfaceTypeName) { + this.typeName = typeName; + this.implementationTypeName = implementastionTypeName; + this.interfaceTypeName = interfaceTypeName; } public String getTypeName() { @@ -24,4 +32,31 @@ public void setImplementationTypeName(String implementastionTypeName) { this.implementationTypeName = implementastionTypeName; } + + public String getInterfaceTypeName() { + return interfaceTypeName; + } + + public void setInterfaceTypeName(String interfaceTypeName) { + this.interfaceTypeName = interfaceTypeName; + } + + public Memento createMemento() { + return new Memento(implementationTypeName, interfaceTypeName); + } + + public void setMemento(Memento memento) { + this.implementationTypeName = memento.implementationTypeName; + this.interfaceTypeName = memento.interfaceTypeName; + } + + public static class Memento { + private String implementationTypeName; + private String interfaceTypeName; + + public Memento(String implementationTypeName, String interfaceTypeName) { + this.implementationTypeName = implementationTypeName; + this.interfaceTypeName = interfaceTypeName; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 1200710..1089b4d 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -18,7 +18,7 @@ public static final Type typeInt = new Type("Int", "int"); public static final Type typeFloat = new Type("Float", "float"); public static final Type typeDouble = new Type("Double", "double"); - public static final Type typeList = new Type("List", "ArrayList"); + public static final Type typeList = new Type("List", "ArrayList", "List"); public static final Type typeBoolean = new Type("Bool", "boolean"); public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX); public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX);; @@ -26,9 +26,9 @@ public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX); public static final Symbol minus = new Symbol(Parser.MINUS, 1); public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "add", Symbol.Type.METHOD_WITH_SIDE_EFFECT, new int[] {1, 0}); - public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "head", Symbol.Type.METHOD); - 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 head = new Symbol("head", 1, Symbol.Type.PREFIX, "get(0)", Symbol.Type.METHOD); + public static final Symbol body = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subString(1, $x.size())", Symbol.Type.LAMBDA); + public static final Symbol cond = new Symbol("if", 3, Symbol.Type.PREFIX, "($x,$y,$z)->$x?$y:$z", Symbol.Type.LAMBDA); 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);