diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index eb84521..13c6394 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -392,12 +392,12 @@ protected void declareAccessorInMainComponent(TypeDeclaration mainComponent, ResourceNode accessRes, MethodDeclaration stateGetter, ILanguageSpecific langSpec) { List mainGetterParams = new ArrayList<>(); int v = 1; - for (Selector selector: accessRes.getAllSelectors()) { - if (selector.getExpression() instanceof Variable) { - Variable var = (Variable) selector.getExpression(); + for (Expression param: accessRes.getOutSideResource().getPathParams()) { + if (param instanceof Variable) { + Variable var = (Variable) param; mainGetterParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - } else if (selector.getExpression() instanceof Term) { - Term var = (Term) selector.getExpression(); + } else if (param instanceof Term) { + Term var = (Term) param; mainGetterParams.add(new VariableDeclaration(var.getType(), "v" + v)); } v++; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 91c8bd0..6644f1b 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -76,8 +76,8 @@ CompilationUnit cu = langSpec.newCompilationUnit(component); codes.add(cu); - // Declare the constructor and the fields to refer to other resources. - MethodDeclaration constructor = declareConstructorAndFieldsToReferToResources(resourceNode, component, dependedRootComponentGraph, depends, langSpec); + // Declare the constructor. + MethodDeclaration constructor = declareConstructor(resourceNode, component, dependedRootComponentGraph, depends, langSpec); if (resourceNode.getResourceHierarchy().getParent() == null) { // For each root resource @@ -88,7 +88,7 @@ // Declare the fields to refer to reference resources. declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); - if (constructor.getParameters() == null) { + if (constructor.getParameters() == null || constructor.getParameters().size() == 0) { component.removeMethod(constructor); } else { resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); @@ -137,10 +137,8 @@ updateStatements.put(entry.getKey(), entry.getValue()); } - // Declare the state field and reference fields in the parent component. - if (component == null) { - declareFieldsInParentComponent(resourceNode, parentComponent, constructorParams, langSpec); - } + // Declare the fields to refer to other resources in the parent/this component, and the state field in the parent component. + declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(resourceNode, component, parentComponent, constructorParams, langSpec); // Declare the getter method in this resource to obtain the state. if (component == null) { @@ -200,7 +198,7 @@ if (constructor == null) { if (resourceComponents.get(resource) != null) { String resourceName = getComponentName(resource, langSpec); - constructor = new MethodDeclaration(resourceName, true); + constructor = langSpec.newMethodDeclaration(resourceName, true, null, null); Block body = new Block(); constructor.setBody(body); resourceComponents.get(resource).addMethod(constructor); @@ -267,14 +265,15 @@ method.addFirstStatement(updateStatement); } - private MethodDeclaration declareConstructorAndFieldsToReferToResources(ResourceNode resourceNode, TypeDeclaration component, Map> dependedRootComponentGraph, + private MethodDeclaration declareConstructor(ResourceNode resourceNode, TypeDeclaration component, Map> dependedRootComponentGraph, List depends, ILanguageSpecific langSpec) { // Declare a constructor in each component. - MethodDeclaration constructor = component.createConstructor(); + String resourceName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); + MethodDeclaration constructor = langSpec.newMethodDeclaration(resourceName, true, null, null); Block block = new Block(); constructor.setBody(block); + component.addMethod(constructor); - // Declare fields in each component. (for data-flow graph) for (Edge resToCh: resourceNode.getOutEdges()) { DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // Check if the input resource is outside of the channel scope. @@ -285,24 +284,28 @@ break; } } - // Check if the output resource is outside of the channel scope. - boolean outsideOutputResource = false; - for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. - break; - } - } - if (((PushPullAttribute) ((DataFlowEdge) resToCh).getAttribute()).getOptions().get(0) == PushPullValue.PUSH && !outsideInputResource) { - for (Edge chToRes: resToCh.getDestination().getOutEdges()) { - // for PUSH transfer - if (chToRes.getDestination() instanceof ResourceNode) { - ResourceHierarchy dstRes = addReference(component, constructor, ((ResourceNode) chToRes.getDestination()).getOutSideResource().getResourceHierarchy(), langSpec); - if (outsideOutputResource) { - if (dstRes != null && dstRes.getParent() != null) { - // Reference to root resource. - addReference(component, constructor, dstRes.getRoot(), langSpec); - } + for (Edge chToRes: resToCh.getDestination().getOutEdges()) { + if (chToRes.getDestination() instanceof ResourceNode) { + ResourceHierarchy dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource().getResourceHierarchy(); + // Check if the output resource is outside of the channel scope. + boolean outsideOutputResource = false; + for (ChannelMember cm: ch.getOutputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(dstRes) && cm.isOutside()) { + outsideOutputResource = true; // Regarded as push transfer. + break; + } + } + if ((((PushPullAttribute) ((DataFlowEdge) resToCh).getAttribute()).getOptions().get(0) == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { + // for PUSH transfer +// ResourceHierarchy dstRes = addReference(component, constructor, ((ResourceNode) chToRes.getDestination()).getOutSideResource().getResourceHierarchy(), langSpec); +// if (outsideOutputResource) { +// if (dstRes != null && dstRes.getParent() != null) { +// // Reference to root resource. +// addReference(component, constructor, dstRes.getRoot(), langSpec); +// } +// } + if (!generatesComponent(dstRes)) { + dstRes = dstRes.getParent(); } if (!depends.contains(dstRes)) depends.add(dstRes); } @@ -331,12 +334,15 @@ } if ((((PushPullAttribute) ((DataFlowEdge) resToCh).getAttribute()).getOptions().get(0) != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { // for PULL transfer - srcRes = addReference(component, constructor, ((ResourceNode) resToCh.getSource()).getOutSideResource().getResourceHierarchy(), langSpec); - if (outsideInputResource) { - if (srcRes != null & srcRes.getParent() != null) { - // Reference to root resource. - addReference(component, constructor, srcRes.getRoot(), langSpec); - } +// srcRes = addReference(component, constructor, ((ResourceNode) resToCh.getSource()).getOutSideResource().getResourceHierarchy(), langSpec); +// if (outsideInputResource) { +// if (srcRes != null & srcRes.getParent() != null) { +// // Reference to root resource. +// addReference(component, constructor, srcRes.getRoot(), langSpec); +// } +// } + if (!generatesComponent(srcRes)) { + srcRes = srcRes.getParent(); } if (!depends.contains(srcRes)) depends.add(srcRes); } @@ -387,52 +393,99 @@ } } - private void declareFieldsInParentComponent(ResourceNode resourceNode, TypeDeclaration parentComponent, List> constructorParams, ILanguageSpecific langSpec) { - // Declare reference fields for push/pull data transfer. + private void declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, List> constructorParams, ILanguageSpecific langSpec) { + // Declare reference fields for push data transfer. boolean noPullTransfer = true; for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); - for (Edge chToRes: re.getDestination().getOutEdges()) { - ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); - // Check if the destination resource is outside of the channel scope. - boolean outsideOutputResource = false; - for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(dstRes.getResourceHierarchy()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. - break; - } + // Check if the source resource is outside of the channel scope. + boolean outsideInputResource = false; + for (ChannelMember cm: ch.getInputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getResourceHierarchy()) && cm.isOutside()) { + outsideInputResource = true; // Regarded as pull transfer. + break; } - if (outsideOutputResource) { - // Declare a field in the parent component to refer to the destination resource of push transfer. - String dstResName = null; - if (!generatesComponent(dstRes.getResourceHierarchy())) { - dstRes = dstRes.getParent(); + } + for (Edge chToRes: re.getDestination().getOutEdges()) { + if (chToRes.getDestination() instanceof ResourceNode) { + ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); + // Check if the destination resource is outside of the channel scope. + boolean outsideOutputResource = false; + for (ChannelMember cm: ch.getOutputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(dstRes.getResourceHierarchy()) && cm.isOutside()) { + outsideOutputResource = true; // Regarded as push transfer. + break; + } } - dstResName = getComponentName(dstRes.getResourceHierarchy(), langSpec); - FieldDeclaration refFieldForPush = langSpec.newFieldDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); - parentComponent.addField(refFieldForPush); - if (dstRes.getParent() != null) { - // Reference to root resource. - String dstRootResName = getComponentName(dstRes.getRoot().getResourceHierarchy(), langSpec); - Type dstRootResType = new Type(dstRootResName, dstRootResName); - dstRootResName = langSpec.toVariableName(dstRootResName); - FieldDeclaration refRootFieldForPush = langSpec.newFieldDeclaration(dstRootResType, dstRootResName); - boolean existsField = false; - for (FieldDeclaration field: parentComponent.getFields()) { - if (dstRootResName.equals(field.getName())) { - existsField = true; - break; + if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { + // Declare a field in the parent component to refer to the destination resource of push transfer. + if (!generatesComponent(dstRes.getResourceHierarchy())) { + dstRes = dstRes.getParent(); + } + String dstResName = getComponentName(dstRes.getResourceHierarchy(), langSpec); + FieldDeclaration refFieldForPush = langSpec.newFieldDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); + VariableDeclaration refVarForPush = langSpec.newVariableDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); + if (component != null) { + // A component is created for this resource. + if (resourceNode.getResourceHierarchy() != dstRes.getResourceHierarchy()) { + component.addField(refFieldForPush); + if (!outsideOutputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), refVarForPush)); + } + } + } else { + // No component is created for this resource. + if (resourceNode.getParent().getResourceHierarchy() != dstRes.getResourceHierarchy()) { + parentComponent.addField(refFieldForPush); + if (!outsideOutputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refVarForPush)); + } } } - if (!existsField) { - parentComponent.addField(refRootFieldForPush); + if (outsideOutputResource) { + // When the reference to the destination resource can vary. + if (dstRes.getParent() != null) { + // Reference to its root resource. + String dstRootResName = getComponentName(dstRes.getRoot().getResourceHierarchy(), langSpec); + Type dstRootResType = new Type(dstRootResName, dstRootResName); + dstRootResName = langSpec.toVariableName(dstRootResName); + FieldDeclaration refRootFieldForPush = langSpec.newFieldDeclaration(dstRootResType, dstRootResName); + VariableDeclaration refRootVarForPush = langSpec.newVariableDeclaration(dstRootResType, dstRootResName); + if (component != null) { + // A component is created for this resource. + boolean existsField = false; + for (FieldDeclaration field: component.getFields()) { + if (dstRootResName.equals(field.getName())) { + existsField = true; + break; + } + } + if (!existsField) { + component.addField(refRootFieldForPush); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), refRootVarForPush)); + } + } else { + // No component is created for this resource. + boolean existsField = false; + for (FieldDeclaration field: parentComponent.getFields()) { + if (dstRootResName.equals(field.getName())) { + existsField = true; + break; + } + } + if (!existsField) { + parentComponent.addField(refRootFieldForPush); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootVarForPush)); + } + } + } } - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), langSpec.newVariableDeclaration(dstRootResType, dstRootResName))); } } } } + // Declare reference fields for pull data transfer. for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; @@ -446,52 +499,98 @@ break; } } - if (outsideInputResource) { - // Declare a field in the parent component to refer to the source resource of pull transfer. - String srcResName = null; + // Check if the output resource is outside of the channel scope. + boolean outsideOutputResource = false; + for (ChannelMember cm: ch.getOutputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { + outsideOutputResource = true; // Regarded as push transfer. + break; + } + } + if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { + noPullTransfer = false; + // Declare a field in the parent/this component to refer to the source resource of pull transfer. if (!generatesComponent(srcRes.getResourceHierarchy())) { srcRes = srcRes.getParent(); } - srcResName = getComponentName(srcRes.getResourceHierarchy(), langSpec); + String srcResName = getComponentName(srcRes.getResourceHierarchy(), langSpec); FieldDeclaration refFieldForPull = langSpec.newFieldDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); - parentComponent.addField(refFieldForPull); - if (srcRes.getParent() != null) { - // Reference to root resource. - String srcRootResName = getComponentName(srcRes.getRoot().getResourceHierarchy(), langSpec); - Type srcRootResType = new Type(srcRootResName, srcRootResName); - srcRootResName = langSpec.toVariableName(srcRootResName); - FieldDeclaration refRootFieldForPull = langSpec.newFieldDeclaration(srcRootResType, srcRootResName); - boolean existsField = false; - for (FieldDeclaration field: parentComponent.getFields()) { - if (srcRootResName.equals(field.getName())) { - existsField = true; - break; + VariableDeclaration refVarForPull = langSpec.newVariableDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); + if (component != null) { + // A component is created for this resource. + if (resourceNode.getResourceHierarchy() != srcRes.getResourceHierarchy()) { + component.addField(refFieldForPull); + if (!outsideInputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), refVarForPull)); } } - if (!existsField) { - parentComponent.addField(refRootFieldForPull); + } else { + // No component is created for this resource. + if (resourceNode.getParent().getResourceHierarchy() != srcRes.getResourceHierarchy()) { + parentComponent.addField(refFieldForPull); + if (!outsideInputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refVarForPull)); + } } - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), langSpec.newVariableDeclaration(srcRootResType, srcRootResName))); } - noPullTransfer = false; + if (outsideInputResource) { + // When the reference to the source resource can vary. + if (srcRes.getParent() != null) { + // Reference to its root resource. + String srcRootResName = getComponentName(srcRes.getRoot().getResourceHierarchy(), langSpec); + Type srcRootResType = new Type(srcRootResName, srcRootResName); + srcRootResName = langSpec.toVariableName(srcRootResName); + FieldDeclaration refRootFieldForPull = langSpec.newFieldDeclaration(srcRootResType, srcRootResName); + VariableDeclaration refRootVarForPull = langSpec.newVariableDeclaration(srcRootResType, srcRootResName); + if (component != null) { + // A component is created for this resource. + boolean existsField = false; + for (FieldDeclaration field: component.getFields()) { + if (srcRootResName.equals(field.getName())) { + existsField = true; + break; + } + } + if (!existsField) { + component.addField(refRootFieldForPull); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), refRootVarForPull)); + } + } else { + // No component is created for this resource. + boolean existsField = false; + for (FieldDeclaration field: parentComponent.getFields()) { + if (srcRootResName.equals(field.getName())) { + existsField = true; + break; + } + } + if (!existsField) { + parentComponent.addField(refRootFieldForPull); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootVarForPull)); + } + } + } + } } } } // Declare the state field in the parent component. - ResourceHierarchy res = resourceNode.getOutSideResource().getResourceHierarchy(); - if (((StoreAttribute) resourceNode.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { - String resName = langSpec.toVariableName(getComponentName(res, langSpec)); - boolean existsField = false; - for (FieldDeclaration field: parentComponent.getFields()) { - if (resName.equals(field.getName())) { - existsField = true; - break; + if (component == null) { + ResourceHierarchy res = resourceNode.getOutSideResource().getResourceHierarchy(); + if (((StoreAttribute) resourceNode.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { + String resName = langSpec.toVariableName(getComponentName(res, langSpec)); + boolean existsField = false; + for (FieldDeclaration field: parentComponent.getFields()) { + if (resName.equals(field.getName())) { + existsField = true; + break; + } } - } - if (!existsField) { - FieldDeclaration stateField = langSpec.newFieldDeclaration(res.getResourceStateType(), resName); - parentComponent.addField(stateField); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), langSpec.newVariableDeclaration(res.getResourceStateType(), resName))); + if (!existsField) { + FieldDeclaration stateField = langSpec.newFieldDeclaration(res.getResourceStateType(), resName); + parentComponent.addField(stateField); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), langSpec.newVariableDeclaration(res.getResourceStateType(), resName))); + } } } } @@ -676,11 +775,27 @@ } MethodDeclaration update = null; if (component != null) { - update = langSpec.newMethodDeclaration(updateMethodPrefix + from + srcResComponentName, false, null, vars); - component.addMethod(update); + for (MethodDeclaration method: component.getMethods()) { + if (method.getName().equals(updateMethodPrefix + from + srcResComponentName)) { + update = method; + break; + } + } + if (update == null) { + update = langSpec.newMethodDeclaration(updateMethodPrefix + from + srcResComponentName, false, null, vars); + component.addMethod(update); + } } else if (parentComponent != null) { - update = langSpec.newMethodDeclaration(updateMethodPrefix + resComponentName + from + srcResComponentName, false, null, vars); - parentComponent.addMethod(update); + for (MethodDeclaration method: parentComponent.getMethods()) { + if (method.getName().equals(updateMethodPrefix + resComponentName + from + srcResComponentName)) { + update = method; + break; + } + } + if (update == null) { + update = langSpec.newMethodDeclaration(updateMethodPrefix + resComponentName + from + srcResComponentName, false, null, vars); + parentComponent.addMethod(update); + } } // Add a statement to update the state field @@ -1057,13 +1172,30 @@ if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { inputMethodName += _for + getComponentName(out.getResource().getResourceHierarchy(), langSpec); } - input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); if (component != null) { // A component is created for this resource. - component.addMethod(input); + for (MethodDeclaration method: component.getMethods()) { + if (method.getName().equals(inputMethodName)) { + input = method; + break; + } + } + if (input == null) { + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + component.addMethod(input); + } } else if (parentComponent != null) { // No component is created for this resource. - parentComponent.addMethod(input); + for (MethodDeclaration method: parentComponent.getMethods()) { + if (method.getName().equals(inputMethodName)) { + input = method; + break; + } + } + if (input == null) { + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + parentComponent.addMethod(input); + } } // Declare the accessor in the main component to call the input method. @@ -1120,17 +1252,38 @@ if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { inputMethodName += _for + getComponentName(out.getResource().getResourceHierarchy(), langSpec); } - if (resInputParams.size() == 0) { - input = langSpec.newMethodDeclaration(inputMethodName, null); - } else { - input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); - } if (component != null) { // A component is created for this resource. - component.addMethod(input); + for (MethodDeclaration method: component.getMethods()) { + if (method.getName().equals(inputMethodName)) { + input = method; + break; + } + } + if (input == null) { + if (resInputParams.size() == 0) { + input = langSpec.newMethodDeclaration(inputMethodName, null); + } else { + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + } + component.addMethod(input); + } } else if (parentComponent != null) { // No component is created for this resource. - parentComponent.addMethod(input); + for (MethodDeclaration method: parentComponent.getMethods()) { + if (method.getName().equals(inputMethodName)) { + input = method; + break; + } + } + if (input == null) { + if (resInputParams.size() == 0) { + input = langSpec.newMethodDeclaration(inputMethodName, null); + } else { + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + } + parentComponent.addMethod(input); + } } // Declare the accessor in the main component to call the input method. diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index 871630a..7204b95 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -307,47 +307,49 @@ } } - // Declare the state field and reference fields in the parent component. + // Declare the state field in the parent component. if (component == null) { // Declare reference fields for push/pull data transfer. boolean noPullTransfer = true; - for (Edge resToCh : resourceNode.getOutEdges()) { - DataFlowEdge re = (DataFlowEdge) resToCh; - DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); - for (Edge chToRes: re.getDestination().getOutEdges()) { - ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); - boolean outsideOutputResource = false; - for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(dstRes.getResourceHierarchy()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. - break; - } - } - if (outsideOutputResource) { // This logic may be incorrect. (ToDo) - // Declare a field in the parent component to refer to the destination resource of push transfer. - if (!generatesComponent(dstRes.getResourceHierarchy())) { - dstRes = dstRes.getParent(); - } - String dstResName = getComponentName(dstRes.getResourceHierarchy()); - FieldDeclaration refFieldForPush = new FieldDeclaration(new Type(dstResName, dstResName), toVariableName(dstResName)); - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPush)); - if (dstRes.getParent() != null) { - // Reference to root resource. - ResourcePath dstRootRes = dstRes.getRoot(); - String dstRootResName = getComponentName(dstRootRes.getResourceHierarchy()); - Type dstRootResType = new Type(dstRootResName, dstRootResName); - FieldDeclaration refRootFieldForPush = new FieldDeclaration(dstRootResType, toVariableName(dstRootResName)); - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPush)); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(dstRootResType, toVariableName(dstRootResName)))); - } - } - } - } +// for (Edge resToCh : resourceNode.getOutEdges()) { +// DataFlowEdge re = (DataFlowEdge) resToCh; +// DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); +// for (Edge chToRes: re.getDestination().getOutEdges()) { +// ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); +// // Check if the output resource is outside of the channel scope. +// boolean outsideOutputResource = false; +// for (ChannelMember cm: ch.getOutputChannelMembers()) { +// if (cm.getResource().getResourceHierarchy().equals(dstRes.getResourceHierarchy()) && cm.isOutside()) { +// outsideOutputResource = true; // Regarded as push transfer. +// break; +// } +// } +// if (outsideOutputResource) { // This logic may be incorrect. (ToDo) +// // Declare a field in the parent component to refer to the destination resource of push transfer. +// if (!generatesComponent(dstRes.getResourceHierarchy())) { +// dstRes = dstRes.getParent(); +// } +// String dstResName = getComponentName(dstRes.getResourceHierarchy()); +// FieldDeclaration refFieldForPush = new FieldDeclaration(new Type(dstResName, dstResName), toVariableName(dstResName)); +// fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPush)); +// if (dstRes.getParent() != null) { +// // Reference to root resource. +// ResourcePath dstRootRes = dstRes.getRoot(); +// String dstRootResName = getComponentName(dstRootRes.getResourceHierarchy()); +// Type dstRootResType = new Type(dstRootResName, dstRootResName); +// FieldDeclaration refRootFieldForPush = new FieldDeclaration(dstRootResType, toVariableName(dstRootResName)); +// fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPush)); +// constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(dstRootResType, toVariableName(dstRootResName)))); +// } +// } +// } +// } for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); + // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; for (ChannelMember cm: ch.getInputChannelMembers()) { if (cm.getResource().getResourceHierarchy().equals(srcRes.getResourceHierarchy()) && cm.isOutside()) { @@ -355,24 +357,32 @@ break; } } - if (outsideInputResource) { // This logic may be incorrect. (ToDo) - // Declare a field in the parent component to refer to the source resource of pull transfer. - if (!generatesComponent(srcRes.getResourceHierarchy())) { - srcRes = srcRes.getParent(); + // Check if the output resource is outside of the channel scope. + boolean outsideOutputResource = false; + for (ChannelMember cm: ch.getOutputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getResourceHierarchy()) && cm.isOutside()) { + outsideOutputResource = true; // Regarded as push transfer. + break; } - String srcResName = getComponentName(srcRes.getResourceHierarchy()); - FieldDeclaration refFieldForPull = new FieldDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPull)); - if (srcRes.getParent() != null) { - // Reference to root resource. - ResourcePath srcRootRes = srcRes.getRoot(); - String srcRootResName = getComponentName(srcRootRes.getResourceHierarchy()); - Type srcRootResType = new Type(srcRootResName, srcRootResName); - FieldDeclaration refRootFieldForPull = new FieldDeclaration(srcRootResType, toVariableName(srcRootResName)); - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPull)); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(srcRootResType, toVariableName(srcRootResName)))); - } + } + if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { noPullTransfer = false; +// // Declare a field in the parent component to refer to the source resource of pull transfer. +// if (!generatesComponent(srcRes.getResourceHierarchy())) { +// srcRes = srcRes.getParent(); +// } +// String srcResName = getComponentName(srcRes.getResourceHierarchy()); +// FieldDeclaration refFieldForPull = new FieldDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); +// fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPull)); +// if (srcRes.getParent() != null) { +// // Reference to root resource. +// ResourcePath srcRootRes = srcRes.getRoot(); +// String srcRootResName = getComponentName(srcRootRes.getResourceHierarchy()); +// Type srcRootResType = new Type(srcRootResName, srcRootResName); +// FieldDeclaration refRootFieldForPull = new FieldDeclaration(srcRootResType, toVariableName(srcRootResName)); +// fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPull)); +// constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(srcRootResType, toVariableName(srcRootResName)))); +// } } } } @@ -424,7 +434,8 @@ } } - // Declare fields and update methods in the type of each resource. + // Declare reference fields and update methods in the type of each resource. + // Declare reference fields for push data transfer. for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); @@ -436,18 +447,18 @@ break; } } - // Check if the output resource is outside of the channel scope. - boolean outsideOutputResource = false; - for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. - break; + for (Edge chToRes: re.getDestination().getOutEdges()) { + ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); + // Check if the output resource is outside of the channel scope. + boolean outsideOutputResource = false; + for (ChannelMember cm: ch.getOutputChannelMembers()) { + if (cm.getResource().getResourceHierarchy().equals(dstRes.getResourceHierarchy()) && cm.isOutside()) { + outsideOutputResource = true; // Regarded as push transfer. + break; + } } - } - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH && !outsideInputResource) { - // Declare a field to refer to the destination resource of push transfer. - for (Edge chToRes: re.getDestination().getOutEdges()) { - ResourcePath dstRes = ((ResourceNode) chToRes.getDestination()).getOutSideResource(); + if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { + // Declare a field to refer to the destination resource of push transfer. if (!generatesComponent(dstRes.getResourceHierarchy())) { dstRes = dstRes.getParent(); } @@ -457,14 +468,23 @@ VariableDeclaration dstRefVar = new VariableDeclaration(new Type(dstResName, dstResName), toVariableName(dstResName)); if (component != null) { // A component is created for this resource. - component.addField(dstRefField); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), dstRefVar)); + if (resourceNode.getResourceHierarchy() != dstRes.getResourceHierarchy()) { + component.addField(dstRefField); + if (!outsideOutputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), dstRefVar)); + } + } } else { // No component is created for this resource. - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), dstRefField)); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), dstRefVar)); + if (resourceNode.getParent().getResourceHierarchy() != dstRes.getResourceHierarchy()) { + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), dstRefField)); + if (!outsideOutputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), dstRefVar)); + } + } } if (outsideOutputResource) { + // When the reference to the destination resource can vary. if (dstRes.getParent() != null) { // Reference to root resource. ResourcePath dstRootRes = dstRes.getRoot(); @@ -485,6 +505,7 @@ } } } + // Declare reference fields for pull data transfer. for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; @@ -508,26 +529,37 @@ } String srcResName = getComponentName(srcRes.getResourceHierarchy()); ResourcePath srcRes2 = srcRes; + String srcResName2 = srcResName; if (!generatesComponent(srcRes.getResourceHierarchy())) { srcRes2 = srcRes.getParent(); + srcResName2 = getComponentName(srcRes2.getResourceHierarchy()); } if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { // Declare a field to refer to the source resource of pull transfer. depends.add(srcRes2.getResourceHierarchy()); - FieldDeclaration srcRefField = new FieldDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); - VariableDeclaration srcRefVar = new VariableDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); + FieldDeclaration srcRefField = new FieldDeclaration(new Type(srcResName2, srcResName2), toVariableName(srcResName2)); + VariableDeclaration srcRefVar = new VariableDeclaration(new Type(srcResName2, srcResName2), toVariableName(srcResName2)); if (component != null) { // A component is created for this resource. - component.addField(srcRefField); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), srcRefVar)); + if (resourceNode.getResourceHierarchy() != srcRes2.getResourceHierarchy()) { + component.addField(srcRefField); + if (!outsideInputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), srcRefVar)); + } + } } else { // No component is created for this resource. - fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), srcRefField)); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), srcRefVar)); + if (resourceNode.getParent().getResourceHierarchy() != srcRes2.getResourceHierarchy()) { + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), srcRefField)); + if (!outsideInputResource) { + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), srcRefVar)); + } + } } if (outsideInputResource) { + // When the reference to the source resource can vary. if (srcRes2.getParent() != null) { - // Reference to root resource. + // Reference to its root resource. ResourcePath srcRootRes = srcRes2.getRoot(); String srcRootResName = getComponentName(srcRootRes.getResourceHierarchy()); FieldDeclaration srcRootRefField = new FieldDeclaration(new Type(srcRootResName, srcRootResName), toVariableName(srcRootResName)); @@ -976,12 +1008,12 @@ MethodDeclaration getterAccessor = null; List mainGetterParams = new ArrayList<>(); int v = 1; - for (Selector param: resourceNode.getAllSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); + for (Expression param: resourceNode.getOutSideResource().getPathParams()) { + if (param instanceof Variable) { + Variable var = (Variable) param; mainGetterParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); + } else if (param instanceof Term) { + Term var = (Term) param; mainGetterParams.add(new VariableDeclaration(var.getType(), "v" + v)); } v++; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index 26cb8c8..dd01240 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -228,12 +228,12 @@ children.add(child.getResourceHierarchy()); List pathParams = new ArrayList<>(); int v = 1; - for (Selector pathParam: child.getSelectors()) { - if (pathParam.getExpression() instanceof Variable) { - Variable var = (Variable) pathParam.getExpression(); + for (Expression pathParam: child.getOutSideResource().getPathParams()) { + if (pathParam instanceof Variable) { + Variable var = (Variable) pathParam; pathParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (pathParam.getExpression() instanceof Term) { - Term var = (Term) pathParam.getExpression(); + } else if (pathParam instanceof Term) { + Term var = (Term) pathParam; pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); } v++; diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java index 7f418be..f27e54c 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java @@ -103,7 +103,11 @@ channelMember.setOutside(true); } } else { - channelMember.setOutside(true); + if (channelMember.getResource().getPathParams().size() == 0) { + channelMember.setOutside(false); + } else { + channelMember.setOutside(true); + } } }