package generators; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; 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.algebra.Variable; import models.dataConstraintModel.Channel; import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; import models.dataFlowModel.DataTransferModel; import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; import models.dataFlowModel.PushPullAttribute; import models.dataFlowModel.PushPullValue; import models.dataFlowModel.DataFlowEdge; import models.dataFlowModel.DataFlowGraph; import models.dataFlowModel.ResourceNode; import models.dataFlowModel.ChannelNode; 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; } public static String getComponentName(ResourceHierarchy res) { String name = res.getResourceName(); if (res.getNumParameters() > 0) { if (name.length() > 3 && name.endsWith("ies")) { name = name.substring(0, name.length() - 3) + "y"; } else if (name.length() > 1 && name.endsWith("s")) { name = name.substring(0, name.length() - 1); } else { name += "Element"; } } return name.substring(0, 1).toUpperCase() + name.substring(1); } public static Type getImplStateType(ResourceHierarchy res) { Set<ResourceHierarchy> children = res.getChildren(); if (children == null || children.size() == 0) { // leaf resource. return res.getResourceStateType(); } else { ResourceHierarchy child = children.iterator().next(); if (children.size() == 1 && child.getNumParameters() > 0) { // map or list. if (DataConstraintModel.typeList.isAncestorOf(res.getResourceStateType())) { // list. return new Type("List", "ArrayList<>", "List<" + getComponentName(child) + ">", DataConstraintModel.typeList); } else if (DataConstraintModel.typeMap.isAncestorOf(res.getResourceStateType())) { // map. return new Type("Map", "HashMap<>", "Map<String, " + getComponentName(child) + ">", DataConstraintModel.typeMap); } return null; } else { // class return res.getResourceStateType(); } } } static public ArrayList<CompilationUnit> doGenerate(DataFlowGraph graph, DataTransferModel model) { ArrayList<CompilationUnit> codes = new ArrayList<>(); // ArrayList<ResourceNode> resources = StoreResourceCheck(graph); Collection<ResourceNode> resources = graph.getResourceNodes(); Map<ResourceHierarchy, TypeDeclaration> resourceTypes = new HashMap<>(); Map<ResourceHierarchy, MethodDeclaration> getterAccessors = new HashMap<>(); Map<ResourceHierarchy, MethodDeclaration> inputAccessors = new HashMap<>(); // For each resource node. for (Node n : resources) { ResourceNode rn = (ResourceNode) n; if (rn.getResourceHierarchy().getChildren().size() == 0 && rn.getResourceHierarchy().getNumParameters() == 0) { // Don't create new component for a simple leaf resource. continue; } String resourceName = getComponentName(rn.getResourceHierarchy()); TypeDeclaration type = resourceTypes.get(rn.getResourceHierarchy()); if (type == null) { // Add compilation unit for each resource. type = new TypeDeclaration(resourceName); if (rn.getResourceHierarchy().getParent() == null) { // For a root node. type.addAnnotation(new Annotation("Component")); type.addAnnotation(new Annotation("Path", "\"/" + rn.getResourceName() + "\"")); } resourceTypes.put(rn.getResourceHierarchy(), type); CompilationUnit cu = new CompilationUnit(type); cu.addImport(new ImportDeclaration("java.util.*")); if (rn.getResourceHierarchy().getParent() == null) { // For a root node. cu.addImport(new ImportDeclaration("javax.ws.rs.*")); cu.addImport(new ImportDeclaration("javax.ws.rs.client.*")); cu.addImport(new ImportDeclaration("javax.ws.rs.core.*")); cu.addImport(new ImportDeclaration("org.springframework.stereotype.Component")); cu.addImport(new ImportDeclaration("com.fasterxml.jackson.databind.ObjectMapper")); cu.addImport(new ImportDeclaration("com.fasterxml.jackson.core.JsonProcessingException")); } codes.add(cu); } // Declare a client field and update methods from other resources. if (rn.getResourceHierarchy().getParent() == null) { // For a root resource boolean bDeclareClientField = false; for (Edge resToCh: rn.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; 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 chToRes : rn.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); String srcResName = getComponentName(srcRes.getResourceHierarchy()); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { if (!bDeclareClientField) { // 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 the destination resource. ArrayList<VariableDeclaration> vars = new ArrayList<>(); String srcName = srcRes.getResourceName(); Type srcType = srcRes.getResourceStateType(); VariableDeclaration param = new VariableDeclaration(srcType, srcName); param.addAnnotation(new Annotation("FormParam", "\"" + srcName + "\"")); vars.add(param); for (ResourcePath refRes: ((ChannelNode) re.getDestination()).getChannel().getReferenceResources()) { if (!refRes.equals(rn.getOutSideResource())) { param = new VariableDeclaration(refRes.getResourceStateType(), refRes.getResourceName()); param.addAnnotation(new Annotation("FormParam", "\"" + refRes.getResourceName() + "\"")); vars.add(param); } } MethodDeclaration update = new MethodDeclaration("update" + srcResName, false, typeVoid, vars); for (ChannelMember cm: ((ChannelNode) re.getDestination()).getChannel().getOutputChannelMembers()) { if (rn.getInSideResources().contains(cm.getResource())) { if (cm.getStateTransition().isRightUnary()) { update.addAnnotation(new Annotation("PUT")); } else { update.addAnnotation(new Annotation("POST")); } } } if (re.getDestination().getIndegree() > 1) { // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. update.addAnnotation(new Annotation("Path", "\"/" + srcName + "\"")); // Declare a field to cash the state of the source resource in the type of the destination resource. ResourcePath cashRes = ((ResourceNode) re.getSource()).getOutSideResource(); type.addField(new FieldDeclaration(cashRes.getResourceStateType(), srcName, getInitializer(cashRes))); } type.addMethod(update); } } } } // // Declare a client field to connect to the source resource of reference transfer. // if (!bDeclareClientField) { // for (ChannelGenerator cg : model.getChannelGenerators()) { // DataflowChannelGenerator dcg = ((DataflowChannelGenerator) cg); // for (ChannelMember cm : dcg.getOutputChannelMembers()) { // if (cm.getIdentifierTemplate().getResourceName().equals(type.getTypeName().toLowerCase())) { // if (dcg.getReferenceChannelMembers().size() > 0) { // // If there exists one or more reference channel member. // type.addField(new FieldDeclaration(typeClient, "client", "ClientBuilder.newClient()")); // bDeclareClientField = true; // break; // } // } // } // if (bDeclareClientField) break; // } // } // Declare input methods in resources. for (Channel ch : model.getIOChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { if (rn.getInSideResources().contains(cm.getResource())) { Expression message = cm.getStateTransition().getMessageExpression(); if (message instanceof Term) { // In each resource. ArrayList<VariableDeclaration> rootParams = new ArrayList<>(); String resourcePath = "\""; int v = 1; for (Selector selector: rn.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable var = (Variable) selector.getExpression(); String paramName = var.getName(); VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); rootParams.add(param); resourcePath += "/{" + paramName + "}"; } else if (selector.getExpression() instanceof Term) { Term var = (Term) selector.getExpression(); String paramName = "v" + v; VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); rootParams.add(param); resourcePath += "/{" + paramName + "}"; } v++; } resourcePath += "\""; ArrayList<VariableDeclaration> resParams = new ArrayList<>(); for (Variable var: message.getVariables().values()) { String paramName = var.getName(); VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); resParams.add(param); param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); rootParams.add(param); } if (rn.getResourceHierarchy().getParent() != null) { MethodDeclaration input = new MethodDeclaration(((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), false, typeVoid, resParams); type.addMethod(input); } // For the root resource. String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootParams); if (cm.getStateTransition().isRightUnary()) { inputAccessor.addAnnotation(new Annotation("PUT")); } else { inputAccessor.addAnnotation(new Annotation("POST")); } if (ch.getAllSelectors().size() > 0) { inputAccessor.addAnnotation(new Annotation("Path", resourcePath)); } inputAccessors.put(rn.getResourceHierarchy(), inputAccessor); } else if (message instanceof Variable) { // In each resource. if (rn.getResourceHierarchy().getParent() != null) { MethodDeclaration input = new MethodDeclaration(((Variable) cm.getStateTransition().getMessageExpression()).getName(), false, typeVoid, null); type.addMethod(input); } // For the root resource. ArrayList<VariableDeclaration> rootParams = new ArrayList<>(); String resourcePath = "\""; int v = 1; for (Selector selector: rn.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable var = (Variable) selector.getExpression(); String paramName = var.getName(); VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); rootParams.add(param); resourcePath += "/{" + paramName + "}"; } else if (selector.getExpression() instanceof Term) { Term var = (Term) selector.getExpression(); String paramName = "v" + v; VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); rootParams.add(param); resourcePath += "/{" + paramName + "}"; } v++; } resourcePath += "\""; String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootParams); if (cm.getStateTransition().isRightUnary()) { inputAccessor.addAnnotation(new Annotation("PUT")); } else { inputAccessor.addAnnotation(new Annotation("POST")); } if (ch.getAllSelectors().size() > 0) { inputAccessor.addAnnotation(new Annotation("Path", resourcePath)); } inputAccessors.put(rn.getResourceHierarchy(), inputAccessor); } } } } // Declare the field to store the state in the type of each resource. if (((StoreAttribute) rn.getAttribute()).isStored()) { ResourcePath res = rn.getOutSideResource(); Set<ResourceHierarchy> children = rn.getResourceHierarchy().getChildren(); if (children == null || children.size() == 0) { // leaf resource. type.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); } else { ResourceHierarchy child = children.iterator().next(); if (children.size() == 1 && child.getNumParameters() > 0) { // map or list. type.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); } else { // class for (ResourceHierarchy c: children) { String childTypeName = getComponentName(c); Type childType = null; if ((c.getChildren() == null || c.getChildren().size() == 0) && c.getNumParameters() == 0) { // The child does not have a component. childType = c.getResourceStateType(); } else { // The child has a component. childType = new Type(childTypeName, childTypeName); } String fieldName = childTypeName.substring(0, 1).toLowerCase() + childTypeName.substring(1); type.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); } } } } // Declare the getter method to obtain the state in the type of each resource. MethodDeclaration stateGetter = new MethodDeclaration("getValue", getImplStateType(rn.getResourceHierarchy())); if (rn.getResourceHierarchy().getParent() == null) { // Since this getter is also an accessor. stateGetter.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); stateGetter.addAnnotation(new Annotation("GET")); } type.addMethod(stateGetter); // Declare the getter methods to obtain a child of the resource. for (ResourceNode child: rn.getChildren()) { List<VariableDeclaration> pathParams = new ArrayList<>(); int v = 1; for (Selector pathParam: child.getSelectors()) { if (pathParam.getExpression() instanceof Variable) { Variable var = (Variable) pathParam.getExpression(); pathParams.add(new VariableDeclaration(var.getType(), var.getName())); } else if (pathParam.getExpression() instanceof Term) { Term var = (Term) pathParam.getExpression(); pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); } v++; } String childTypeName = getComponentName(child.getResourceHierarchy()); Type childType = null; if ((child.getResourceHierarchy().getChildren() == null || child.getResourceHierarchy().getChildren().size() == 0) && child.getResourceHierarchy().getNumParameters() == 0) { // The child does not have a component. childType = child.getResourceStateType(); } else { // The child has a component. childType = new Type(childTypeName, childTypeName); } MethodDeclaration childGetter = null; if (pathParams.size() == 0) { childGetter = new MethodDeclaration("get" + childTypeName, childType); } else { childGetter = new MethodDeclaration("get" + childTypeName, false, childType, pathParams); } type.addMethod(childGetter); } // Declare the getter accessor to obtain the resource state in the root resource. if (rn.getResourceHierarchy().getParent() != null) { // For a non-root resource MethodDeclaration getterAccessor = null; List<VariableDeclaration> params = new ArrayList<>(); String resourcePath = "\""; int v = 1; for (Selector pathParam: rn.getAllSelectors()) { if (pathParam.getExpression() instanceof Variable) { Variable var = (Variable) pathParam.getExpression(); String paramName = var.getName(); VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); params.add(param); resourcePath += "/{" + paramName + "}"; } else if (pathParam.getExpression() instanceof Term) { Term var = (Term) pathParam.getExpression(); String paramName = "v" + v; VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); param.addAnnotation(new Annotation("PathParam", "\"" + paramName + "\"")); params.add(param); resourcePath += "/{" + paramName + "}"; } v++; } resourcePath += "\""; if (params.size() > 0) { getterAccessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()) + "Value", false, getImplStateType(rn.getResourceHierarchy()), params); } else { getterAccessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()) + "Value", getImplStateType(rn.getResourceHierarchy())); } getterAccessor.setBody(new Block()); Expression getState = JerseyCodeGenerator.pullAccessor.getCurrentStateAccessorFor(rn.getOutSideResource(), rn.getOutSideResource().getRoot()); getterAccessor.getBody().addStatement("return " + getState.toImplementation(new String[] {null}) + ";"); getterAccessor.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); getterAccessor.addAnnotation(new Annotation("GET")); if (rn.getSelectors().size() > 0) { getterAccessor.addAnnotation(new Annotation("Path", resourcePath)); } getterAccessors.put(rn.getResourceHierarchy(), getterAccessor); } } for (ResourceHierarchy rootRes: model.getResourceHierarchies()) { if (rootRes.getParent() == null) { // root resource TypeDeclaration rootType = resourceTypes.get(rootRes); // Add getter accessors. for (ResourceHierarchy res: getterAccessors.keySet()) { if (rootRes.isAncestorOf(res)) { rootType.addMethod(getterAccessors.get(res)); } } // Add inout accessors. for (ResourceHierarchy res: inputAccessors.keySet()) { if (rootRes.isAncestorOf(res)) { rootType.addMethod(inputAccessors.get(res)); } } } } // Declare the Pair class. boolean isCreatedPair = false; for(Node n : resources) { ResourceNode rn = (ResourceNode) n; if(isCreatedPair) continue; if(model.getType("Pair").isAncestorOf(rn.getResourceStateType())) { TypeDeclaration type = new TypeDeclaration("Pair<T>"); type.addField(new FieldDeclaration(new Type("Double", "T"), "left")); type.addField(new FieldDeclaration(new Type("Double", "T"), "right")); MethodDeclaration constructor = new MethodDeclaration("Pair", true); constructor.addParameter(new VariableDeclaration(new Type("Double", "T"), "left")); constructor.addParameter(new VariableDeclaration(new Type("Double", "T"), "right")); Block block = new Block(); block.addStatement("this.left = left;"); block.addStatement("this.right = right;"); constructor.setBody(block); type.addMethod(constructor); for(FieldDeclaration field : type.getFields()) { MethodDeclaration getter = new MethodDeclaration( "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1), new Type("Double","T")); getter.setBody(new Block()); getter.getBody().addStatement("return " + field.getName() + ";"); type.addMethod(getter); } // MethodDeclaration toStr = new MethodDeclaration("toString", false, DataConstraintModel.typeString, null); // block = new Block(); // block.addStatement("return \"{\\\"\" + left + \"\\\":\\\"\" + right + \"\\\"}\";"); // toStr.setBody(block); // type.addMethod(toStr); CompilationUnit cu = new CompilationUnit(type); cu.addImport(new ImportDeclaration("java.util.*")); codes.add(cu); isCreatedPair = true; } } return codes; } private static String getInitializer(ResourcePath resId) { Type stateType = resId.getResourceStateType(); String initializer = null; if (resId.getResourceHierarchy().getInitialValue() != null) { initializer = resId.getResourceHierarchy().getInitialValue().toImplementation(new String[] {""}); } else { if (DataConstraintModel.typeList.isAncestorOf(stateType)) { initializer = "new " + resId.getResourceStateType().getImplementationTypeName() + "()"; } else if (DataConstraintModel.typeMap.isAncestorOf(stateType)) { initializer = "new " + resId.getResourceStateType().getImplementationTypeName() + "()"; } } return initializer; } static public ArrayList<String> getCodes(ArrayList<TypeDeclaration> codeTree) { ArrayList<String> 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().getInterfaceTypeName() + " " + field.getName(); if (DataConstraintModel.isListType(field.getType())) cons += " = new " + field.getType().getImplementationTypeName() + "()"; cons += ";"; codes.add(cons); } else { String cons = "\t" + "private " + field.getType().getInterfaceTypeName() + " " + field.getName() + " = new " + field.getType().getTypeName() + "("; cons += ");"; codes.add(cons); } } codes.add(""); for (MethodDeclaration method : type.getMethods()) { String varstr = "\t" + "public " + method.getReturnType().getInterfaceTypeName() + " " + method.getName() + "("; if (method.getParameters() != null) { for (VariableDeclaration var : method.getParameters()) { varstr += var.getType().getInterfaceTypeName() + " " + 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 public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ResourcePath target, ResourcePath from) { if (target.equals(from)) { return new Field("value", target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } return null; } @Override public Expression getNextStateAccessorFor(ResourcePath target, ResourcePath from) { return new Parameter(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } }; static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ResourcePath target, ResourcePath from) { if (from != null && !from.getResourceHierarchy().isAncestorOf(target.getResourceHierarchy())) { if (target.equals(from)) { return new Field("value", target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } // for reference channel member return new Parameter(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } else { // access from an ancestor or outside of the hierarchy Stack<ResourcePath> pathStack = new Stack<>(); ResourcePath curPath = target; do { if (from != null && curPath.equals(from)) break; pathStack.push(curPath); curPath = curPath.getParent(); } while (curPath != null); // iterate from the `from' resource Term getter = null; int v = 1; while (!pathStack.empty()) { curPath = pathStack.pop(); String typeName = getComponentName(curPath.getResourceHierarchy()); if (getter == null && from == null) { // root resource String fieldName = typeName.substring(0, 1).toLowerCase() + typeName.substring(1); getter = new Field(fieldName, new Type(typeName, typeName)); } else { Term newGetter = new Term(new Symbol("get" + typeName, -1, Symbol.Type.METHOD)); newGetter.addChild(getter); if (curPath.getResourceHierarchy().getNumParameters() > 0) { Variable var = null; Expression param = curPath.getLastParam(); if (param instanceof Variable) { var = (Variable) param; } else if (param instanceof Term) { var = new Variable("v" + v, ((Term) param).getType()); } if (var != null) { newGetter.addChild(var); newGetter.getSymbol().setArity(2); } v++; } getter = newGetter; } } if (target.getResourceHierarchy().getNumParameters() > 0 || (target.getResourceHierarchy().getChildren() != null && target.getResourceHierarchy().getChildren().size() > 0)) { Term newGetter = new Term(new Symbol("getValue", 1, Symbol.Type.METHOD)); newGetter.addChild(getter); getter = newGetter; } return getter; } } @Override public Expression getNextStateAccessorFor(ResourcePath target, ResourcePath from) { return new Parameter(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } }; }