diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index df21c03..df7c5d4 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -180,7 +180,7 @@ } // Declare the fields to refer to other resources for push/pull transfer in the parent/this component, and the state field in the parent component. - boolean bDeclareClientField = declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(resourceNode, component, parentComponent, constructorParams, platformSpec, langSpec); + declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(resourceNode, component, parentComponent, constructorParams, platformSpec, langSpec); // (#2) Declare the getter method to obtain the resource state in an ancestor resource. (complementary to #1) if (component == null) { @@ -494,11 +494,10 @@ } } - private boolean declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, + private void declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, Map> constructorParams, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Declare reference fields for push data transfer. boolean noPullTransfer = true; - boolean bDeclareClientField = false; for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ChannelNode directDstChNode = (ChannelNode) re.getDestination(); @@ -548,7 +547,7 @@ outsideInputResource = true; // Regarded as (collecting) pull transfer. } if ((((PushPullAttribute) re.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { - // Declare a field in the parent component to refer to the destination resource of push transfer. + // Declare a field in the parent or this component to refer to the destination resource of push transfer. if (!generatesComponent(dstRes)) { dstRes = dstRes.getParent(); } @@ -558,10 +557,10 @@ if (!platformSpec.isMonolithic() && (outsideOutputResource || (resourceNode.getOutSideResource(ch).getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) - if (!bDeclareClientField && parentComponent != null) { + if (parentComponent != null && + !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(parentComponent)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(parentComponent); - bDeclareClientField = true; + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); } } else { // Monolithic or Inner-service @@ -596,54 +595,54 @@ } } } - } - 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(), 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 (outsideOutputResource) { + // When the reference to the destination resource can vary. + if (dstRes.getParent() != null) { + // Reference to its root resource. + String dstRootResName = getComponentName(dstRes.getRoot(), 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); - Map nameToParam = constructorParams.get(resourceNode.getResourceHierarchy()); - if (nameToParam == null) { - nameToParam = new HashMap<>(); - constructorParams.put(resourceNode.getResourceHierarchy(), nameToParam); + if (!existsField) { + component.addField(refRootFieldForPush); + Map nameToParam = constructorParams.get(resourceNode.getResourceHierarchy()); + if (nameToParam == null) { + nameToParam = new HashMap<>(); + constructorParams.put(resourceNode.getResourceHierarchy(), nameToParam); + } + if (nameToParam.get(dstRootResName) == null) { + nameToParam.put(dstRootResName, refRootVarForPush); + } } - if (nameToParam.get(dstRootResName) == null) { - nameToParam.put(dstRootResName, 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; + } } - } - } 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); - Map nameToParam = constructorParams.get(resourceNode.getParent().getResourceHierarchy()); - if (nameToParam == null) { - nameToParam = new HashMap<>(); - constructorParams.put(resourceNode.getParent().getResourceHierarchy(), nameToParam); - } - if (nameToParam.get(dstRootResName) == null) { - nameToParam.put(dstRootResName, refRootVarForPush); + if (!existsField) { + parentComponent.addField(refRootFieldForPush); + Map nameToParam = constructorParams.get(resourceNode.getParent().getResourceHierarchy()); + if (nameToParam == null) { + nameToParam = new HashMap<>(); + constructorParams.put(resourceNode.getParent().getResourceHierarchy(), nameToParam); + } + if (nameToParam.get(dstRootResName) == null) { + nameToParam.put(dstRootResName, refRootVarForPush); + } } } } @@ -708,10 +707,10 @@ if (!platformSpec.isMonolithic() && (outsideInputResource || (resourceNode.getInSideResource(ch).getCommonPrefix(srcRes) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) - if (!bDeclareClientField && parentComponent != null) { + if (parentComponent != null + && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(parentComponent)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(parentComponent); - bDeclareClientField = true; + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); } } else { // Monolithic or Inner-service (for REST API) @@ -747,54 +746,54 @@ } } } - } - 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 (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); - Map nameToParam = constructorParams.get(resourceNode.getResourceHierarchy()); - if (nameToParam == null) { - nameToParam = new HashMap<>(); - constructorParams.put(resourceNode.getResourceHierarchy(), nameToParam); + if (!existsField) { + component.addField(refRootFieldForPull); + Map nameToParam = constructorParams.get(resourceNode.getResourceHierarchy()); + if (nameToParam == null) { + nameToParam = new HashMap<>(); + constructorParams.put(resourceNode.getResourceHierarchy(), nameToParam); + } + if (nameToParam.get(srcRootResName) == null) { + nameToParam.put(srcRootResName, refRootVarForPull); + } } - if (nameToParam.get(srcRootResName) == null) { - nameToParam.put(srcRootResName, 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; + } } - } - } 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); - Map nameToParam = constructorParams.get(resourceNode.getParent().getResourceHierarchy()); - if (nameToParam == null) { - nameToParam = new HashMap<>(); - constructorParams.put(resourceNode.getParent().getResourceHierarchy(), nameToParam); - } - if (nameToParam.get(srcRootResName) == null) { - nameToParam.put(srcRootResName, refRootVarForPull); + if (!existsField) { + parentComponent.addField(refRootFieldForPull); + Map nameToParam = constructorParams.get(resourceNode.getParent().getResourceHierarchy()); + if (nameToParam == null) { + nameToParam = new HashMap<>(); + constructorParams.put(resourceNode.getParent().getResourceHierarchy(), nameToParam); + } + if (nameToParam.get(srcRootResName) == null) { + nameToParam.put(srcRootResName, refRootVarForPull); + } } } } @@ -829,7 +828,6 @@ } } } - return bDeclareClientField; } @@ -850,7 +848,9 @@ // invocations to other getter methods when at least one incoming data-flow edges is PULL-style. if (addOtherGetterInvocationsToStateGatter(stateGetter, resourceNode, platformSpec, langSpec)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(component); + if (!((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); + } } } @@ -907,7 +907,9 @@ } else { if (addOtherGetterInvocationsToStateGatter(stateGetter, resourceNode, platformSpec, langSpec)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(ancestorComponent); + if (ancestorComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(ancestorComponent)) { + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(ancestorComponent); + } } } @@ -1280,7 +1282,6 @@ String resComponentName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); List constructorStatements = new ArrayList<>(); Map>> updateStatements = new HashMap<>(); - boolean bDeclareClientField = false; for (Edge chToRes: resourceNode.getInEdges()) { ChannelNode directSrcChannel = (ChannelNode) chToRes.getSource(); DataTransferChannel ch = directSrcChannel.getChannel(); @@ -1341,10 +1342,9 @@ && (outsideOutputResource || (resourceNode.getInSideResource(ch).getCommonPrefix(srcResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service hasRestAPI = true; - if (!bDeclareClientField && component != null) { + if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(component); - bDeclareClientField = true; + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); } if (resourceNode.getParent() == null) { // A root resource @@ -1672,54 +1672,58 @@ } } - Set outsideInputMembers = new HashSet<>(); - for (ChannelMember cm: ch.getInputChannelMembers()) { - if (cm.isOutside()) { - outsideInputMembers.add(cm); - } - } - if (outsideInputMembers.size() > 0) { - Map>> resourcePaths = null; - for (ChannelMember out1: ch.getOutputChannelMembers()) { - if (resourceNode.getInSideResources().contains(out1.getResource())) { - try { - resourcePaths = ch.fillOutsideResourcePaths(out1, getPullAccessor(platformSpec)); - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { - e.printStackTrace(); - } - break; + // Update and initialize a field to refer to an outside input resource for PULL transfer. + if (platformSpec.isMonolithic()) { + // For a monolithic application. + Set outsideInputMembers = new HashSet<>(); + for (ChannelMember cm: ch.getInputChannelMembers()) { + if (cm.isOutside()) { + outsideInputMembers.add(cm); } } - if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember: outsideInputMembers) { - for (ChannelMember dependingMember: resourcePaths.get(outsideMember).getValue()) { - if (dependingMember.getResource().equals(srcResPath)) { - // An outside input resource path depends on srcRes. - ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); - String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); - if (generatesComponent(outsidePath.getResourceHierarchy())) { - outsideExp = ((Term) outsideExp).getChild(0); - } - Expression nextExp = dependingMember.getStateTransition().getNextStateExpression(); - if (nextExp != null && outsideExp instanceof Term) { - if (nextExp instanceof Variable) { - outsideExp = ((Term) outsideExp).substitute((Variable) nextExp, new Field(langSpec.toVariableName(getComponentName(dependingMember.getResource().getResourceHierarchy(), langSpec)))); - } else { - // ToDo. + if (outsideInputMembers.size() > 0) { + Map>> resourcePaths = null; + for (ChannelMember out1: ch.getOutputChannelMembers()) { + if (resourceNode.getInSideResources().contains(out1.getResource())) { + try { + resourcePaths = ch.fillOutsideResourcePaths(out1, getPullAccessor(platformSpec)); + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { + e.printStackTrace(); + } + break; + } + } + if (resourcePaths != null && resourcePaths.size() > 0) { + for (ChannelMember outsideMember: outsideInputMembers) { + for (ChannelMember dependingMember: resourcePaths.get(outsideMember).getValue()) { + if (dependingMember.getResource().equals(srcResPath)) { + // An outside input resource path depends on srcRes. + ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); + String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); + Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + if (generatesComponent(outsidePath.getResourceHierarchy())) { + outsideExp = ((Term) outsideExp).getChild(0); } - } - String[] sideEffects = new String[] {""}; - String outsideAccessor = outsideExp.toImplementation(sideEffects); - String updateReference = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); - update.addStatement(updateReference); // Update the reference field. - // Update constructor. - if (component != null) { - MethodDeclaration constructor = getConstructor(component); - constructor.addStatement(updateReference); // Initialize the reference field. - } else if (parentComponent != null){ - constructorStatements.add(updateReference); + Expression nextExp = dependingMember.getStateTransition().getNextStateExpression(); + if (nextExp != null && outsideExp instanceof Term) { + if (nextExp instanceof Variable) { + outsideExp = ((Term) outsideExp).substitute((Variable) nextExp, new Field(langSpec.toVariableName(getComponentName(dependingMember.getResource().getResourceHierarchy(), langSpec)))); + } else { + // ToDo. + } + } + String[] sideEffects = new String[] {""}; + String outsideAccessor = outsideExp.toImplementation(sideEffects); + String updateReference = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); + update.addStatement(updateReference); // Update the reference field. + // Update constructor. + if (component != null) { + MethodDeclaration constructor = getConstructor(component); + constructor.addStatement(updateReference); // Initialize the reference field. + } else if (parentComponent != null){ + constructorStatements.add(updateReference); + } } } } @@ -2132,7 +2136,6 @@ String resComponentName = langSpec.toComponentName(resName); List constructorStatements = new ArrayList<>(); Map>> inputStatements = new HashMap<>(); - boolean bDeclareClientField = false; for (Channel ch: model.getInputChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { if (!cm.isOutside()) { @@ -2909,10 +2912,9 @@ input.addStatement(langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, resName2, httpMethod)); hasUpdateMethodinvoked = true; - if (!bDeclareClientField && component != null) { + if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. - ((RestApiSpecific) platformSpec).addClientFieldDeclaration(component); - bDeclareClientField = true; + ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); } } else { // After the second time of call to update methods in this method @@ -2955,48 +2957,53 @@ } } } - if (outsideInputMembers2.size() > 0) { - if (!generatesComponent(resourceNode.getResourceHierarchy())) { - ResourcePath srcRes2 = resourceNode.getOutSideResource(directDstCh); - for (ChannelMember out2: directDstCh.getOutputChannelMembers()) { - if (!generatesComponent(out2.getResource().getResourceHierarchy())) { - ResourcePath dstRes2 = out2.getResource(); - if (srcRes2.getParent().equals(dstRes2.getParent())) { - Map>> resourcePaths = null; - try { - resourcePaths = directDstCh.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); - if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember: outsideInputMembers2) { - for (ChannelMember dependedMember: resourcePaths.get(outsideMember).getValue()) { - if (dependedMember.getResource().equals(srcRes2)) { - // An outside input resource path depends on srcRes. - ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); - if (!generatesComponent(outsidePath.getResourceHierarchy())) { - outsidePath = outsidePath.getParent(); - } - String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); - if (generatesComponent(outsidePath.getResourceHierarchy())) { - outsideExp = ((Term) outsideExp).getChild(0); - } - String[] sideEffects = new String[] {""}; - String outsideAccessor = outsideExp.toImplementation(sideEffects); - input.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. - // Update constructor. - String initializingStatement = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); - if (component != null) { - MethodDeclaration constructor = getConstructor(component); - constructor.addStatement(initializingStatement); // initialize the reference field. - } else { - constructorStatements.add(initializingStatement); // initialize the reference field. + + // Update and initialize a field to refer to an outside input resource for PULL transfer. + if (platformSpec.isMonolithic()) { + // For a monolithic application. + if (outsideInputMembers2.size() > 0) { + if (!generatesComponent(resourceNode.getResourceHierarchy())) { + ResourcePath srcRes2 = resourceNode.getOutSideResource(directDstCh); + for (ChannelMember out2: directDstCh.getOutputChannelMembers()) { + if (!generatesComponent(out2.getResource().getResourceHierarchy())) { + ResourcePath dstRes2 = out2.getResource(); + if (srcRes2.getParent().equals(dstRes2.getParent())) { + Map>> resourcePaths = null; + try { + resourcePaths = directDstCh.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); + if (resourcePaths != null && resourcePaths.size() > 0) { + for (ChannelMember outsideMember: outsideInputMembers2) { + for (ChannelMember dependedMember: resourcePaths.get(outsideMember).getValue()) { + if (dependedMember.getResource().equals(srcRes2)) { + // An outside input resource path depends on srcRes. + ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); + if (!generatesComponent(outsidePath.getResourceHierarchy())) { + outsidePath = outsidePath.getParent(); + } + String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); + Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + if (generatesComponent(outsidePath.getResourceHierarchy())) { + outsideExp = ((Term) outsideExp).getChild(0); + } + String[] sideEffects = new String[] {""}; + String outsideAccessor = outsideExp.toImplementation(sideEffects); + input.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + // Update constructor. + String initializingStatement = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); + if (component != null) { + MethodDeclaration constructor = getConstructor(component); + constructor.addStatement(initializingStatement); // initialize the reference field. + } else { + constructorStatements.add(initializingStatement); // initialize the reference field. + } } } } } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { + e.printStackTrace(); } - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { - e.printStackTrace(); } } }