diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java index 6374908..fb04068 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java @@ -1,49 +1,84 @@ package application.simulator; -import application.editor.Editor; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Rectangle; +import java.util.EventObject; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; + import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGraphModel; import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.view.mxICellEditor; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxUtils; import com.mxgraph.view.mxCellState; -import models.algebra.*; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import application.editor.Editor; +import application.layouts.DAGLayout; +import models.algebra.Expression; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Position; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +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.dataFlowModel.DataTransferModel; +import models.dataFlowModel.DataFlowGraph; import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.PushPullAttribute; import models.dataFlowModel.PushPullValue; import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.visualModel.FormulaChannel; import parser.Parser; import parser.Parser.TokenStream; import parser.exceptions.ExpectedColon; import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedRightBracket; import parser.exceptions.WrongJsonExpression; -import simulator.Event; +import simulator.ChannelState; import simulator.Resource; import simulator.ResourceIdentifier; import simulator.Simulator; +import simulator.Event; +import simulator.SystemState; -import javax.swing.*; -import java.awt.*; -import java.util.ArrayList; -import java.util.EventObject; -import java.util.List; - -public class InputEventCellEditor implements mxICellEditor { +public class InputEventCellEditor implements mxICellEditor { public int DEFAULT_MIN_WIDTH = 70; public int DEFAULT_MIN_HEIGHT = 30; public double DEFAULT_MINIMUM_EDITOR_SCALE = 1; private double x = 20; private double y = 20; - + protected double minimumEditorScale = DEFAULT_MINIMUM_EDITOR_SCALE; protected int minimumWidth = DEFAULT_MIN_WIDTH; protected int minimumHeight = DEFAULT_MIN_HEIGHT; - + private SimulatorWindow window; private Object editingCell; private EventObject trigger; @@ -60,73 +95,75 @@ this.simulator = simulator; this.editor = editor; } - + @Override public Object getEditingCell() { return editingCell; } - + @Override public void startEditing(Object cell, EventObject evt) { if (editingCell != null) { stopEditing(true); } if (!graphComponent.getGraph().getModel().isEdge(cell)) { - Resource res = simulator.getCurState().getResource((String) ((mxCell) cell).getValue()); - ResourceIdentifier resId = res.getResourceIdentifier(); // clicked resource - ArrayList eventChs = new ArrayList<>(); // eventchannelList - ArrayList messages = new ArrayList<>(); // ADLmessage - ArrayList eventMessages = new ArrayList<>(); // messageList + ResourceIdentifier resId = res.getResourceIdentifier(); // clicked resource + ArrayList eventChs = new ArrayList<>(); // event channel list + ArrayList messageTexts = new ArrayList<>(); // message text list + ArrayList messageExps = new ArrayList<>(); // message expression list + ArrayList> refParams = new ArrayList<>(); // message parameters for ref ports ResourcePath eventResPath = null; - - for (Channel ch : simulator.getModel().getInputChannels()) { // all channels - eventResPath = getSelectableMessages(ch, resId, eventChs, messages, eventMessages, eventResPath); + + for (Channel ch: simulator.getModel().getInputChannels()) { // all channels + eventResPath = getSelectableMessages(ch, resId, eventChs, messageTexts, messageExps, refParams, eventResPath); } - - if (messages.isEmpty()) { + if (messageTexts.isEmpty()) { return; } - String[] eventList = messages.toArray(new String[messages.size()]); - JComboBox event = new JComboBox(eventList); + String[] messageList = messageTexts.toArray(new String[messageTexts.size()]); + JComboBox messageMenu = new JComboBox(messageList); - JPanel eventChoice = new JPanel(); - eventChoice.add(event); // FirstEventChoice + JPanel eventSelectPanel = new JPanel(); + eventSelectPanel.add(messageMenu); - int ret = JOptionPane.showConfirmDialog(window, eventChoice, "Event Choice", JOptionPane.OK_CANCEL_OPTION); + int ret = JOptionPane.showConfirmDialog(window, eventSelectPanel, "Event Choice", JOptionPane.OK_CANCEL_OPTION); // Select an event. if (ret == JOptionPane.OK_OPTION) { - - JPanel inputEvent = new JPanel(); - int i, eventNum; - i = eventNum = 0; - - for (String eventString : eventList) { - if (eventString.equals(event.getSelectedItem().toString())) { - eventNum = i; + int i, messageIdx; + i = messageIdx = 0; + for (String messageText : messageList) { + if(messageText.equals(messageMenu.getSelectedItem().toString())) { + messageIdx = i; } i++; } - - JTextArea textArea = new JTextArea(eventMessages.get(eventNum).toString(), 10, 30); // EventInput - inputEvent.add(textArea); - - int approve = JOptionPane.showConfirmDialog(window, inputEvent, "Event Code", JOptionPane.OK_CANCEL_OPTION); + JPanel inputEventPanel = new JPanel(); + JTextArea textArea = new JTextArea(messageExps.get(messageIdx).toString(), 10, 30); + inputEventPanel.add(textArea); + + int approve = JOptionPane.showConfirmDialog(window, inputEventPanel, "Event Code", JOptionPane.OK_CANCEL_OPTION); // Input an message text for the event. if (approve == JOptionPane.OK_OPTION) { try { - - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - stream.addLine(textArea.getText()); - Expression eventMessage = parser.parseTerm(stream, simulator.getModel()); - - Event newEvent = new Event(eventChs.get(eventNum), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); - simulator.transition(newEvent); - - graphComponent.setCellEditor(new InputEventCellEditor(window, graphComponent, simulator, this.editor)); - + + TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + stream.addLine(textArea.getText()); + Expression eventMessage = parser.parseTerm(stream, simulator.getModel()); + if (eventMessage instanceof Term) { + TreeMap refMap = refParams.get(messageIdx); + for (Integer paramIdx: refMap.keySet()) { + ((Term) eventMessage).getSymbol().setArity(-1); + ((Term) eventMessage).addChild(paramIdx, refMap.get(paramIdx), true); + } + } + + Event newEvent = new Event(eventChs.get(messageIdx), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); + simulator.transition(newEvent); + + graphComponent.setCellEditor(new InputEventCellEditor(window, graphComponent, simulator, this.editor)); + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | - WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } @@ -134,12 +171,12 @@ // resource return; } - + mxCellState state = graphComponent.getGraph().getView().getState(cell); if (state != null && state.getLabel() != null && !state.getLabel().equals("")) { editingCell = cell; trigger = evt; - + double scale = Math.max(minimumEditorScale, graphComponent.getGraph().getView().getScale()); Object value = graphComponent.getGraph().getModel().getValue(cell); if (value != null && value instanceof PushPullAttribute) { @@ -154,45 +191,68 @@ } } } - + private ResourcePath getSelectableMessages(Channel ch, ResourceIdentifier resId, - ArrayList eventChs, ArrayList messages, ArrayList eventMessages, - ResourcePath eventResPath) { - if (((DataTransferChannel) ch).getInputResources().size() == 0) { // event ch or normal ch - for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) { + ArrayList eventChs, ArrayList messageTexts, ArrayList messageExps, ArrayList> refParams, + ResourcePath eventResPath) { + if (((DataTransferChannel) ch).getInputResources().size() == 0) { // event ch. or normal ch. + for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) { ResourcePath resPath = out.getResource(); - if (!out.isOutside() && resId.isInstanceOf(resPath)) { // account.uid == acounts.123 + if (!out.isOutside() && resId.isInstanceOf(resPath)) { eventResPath = resPath; eventChs.add(((DataTransferChannel) ch)); - String message = null; + String messageText = null; Expression mesExp = out.getStateTransition().getMessageExpression(); + TreeMap refMap = new TreeMap<>(); if (mesExp instanceof Term) { + // Reconstruct an input message template List pathParams = resPath.getPathParams(); List children = ((Term) mesExp).getChildren(); mesExp = new Term(((Term) mesExp).getSymbol()); - for (Expression child : children) { - if (!pathParams.contains(child)) { - ((Term) mesExp).addChild(child); + for (int i = 0; i < children.size(); i++) { + Expression child = children.get(i); + boolean isRefVar = false; + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + if (refCm.getStateTransition().getMessageExpression() instanceof Term) { + Expression varExp = ((Term) refCm.getStateTransition().getMessageExpression()).getChild(i); + if (varExp != null && varExp instanceof Variable) { + if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { + // child has come from a reference resource. + isRefVar = true; + break; + } + } + } + } + if (!isRefVar) { + // child has not come from a reference resource. + if (!pathParams.contains(child)) { + ((Term) mesExp).addChild(child); + } else { + int idx = pathParams.indexOf(child); + ((Term) mesExp).addChild(resId.getPathParams().get(idx)); + } } else { - int idx = pathParams.indexOf(child); - ((Term) mesExp).addChild(resId.getPathParams().get(idx)); + // child has come from a reference resource. + refMap.put(i, child); } } - message = ((Term) mesExp).getSymbol().toString(); - } else if (mesExp instanceof Variable) { - message = ((Variable) mesExp).getName(); + messageText = ((Term) mesExp).getSymbol().toString(); + } else if(mesExp instanceof Variable) { + messageText = ((Variable) mesExp).getName(); } - eventMessages.add(mesExp); - messages.add(message); // for the pull-down menu + messageExps.add(mesExp); + messageTexts.add(messageText); // for the pull-down menu + refParams.add(refMap); } } - for (Channel childCh : ch.getChildren()) { - eventResPath = getSelectableMessages(childCh, resId, eventChs, messages, eventMessages, eventResPath); + for (Channel childCh: ch.getChildren()) { + eventResPath = getSelectableMessages(childCh, resId, eventChs, messageTexts, messageExps, refParams, eventResPath); } } return eventResPath; } - + @Override public void stopEditing(boolean cancel) { if (editingCell != null) { @@ -207,14 +267,14 @@ PushPullAttribute attr = (PushPullAttribute) value; List options = attr.getOptions(); PushPullValue selected = null; - for (PushPullValue option : options) { + for (PushPullValue option: options) { if (option.toString().equals(getCurrentValue())) { selected = option; break; } } if (selected != null) { - attr.selectOption(selected); + attr.selectOption(selected); } graphComponent.labelChanged(cell, attr, trig); } @@ -222,58 +282,58 @@ mxCellState state = graphComponent.getGraph().getView().getState(cell); graphComponent.redraw(state); } - + if (comboBox.getParent() != null) { comboBox.setVisible(false); comboBox.getParent().remove(comboBox); } - + graphComponent.requestFocusInWindow(); } } - + public String getCurrentValue() { return (String) comboBox.getSelectedItem(); } - + /** * Returns the bounds to be used for the editor. */ public Rectangle getEditorBounds(mxCellState state, double scale) { mxIGraphModel model = state.getView().getGraph().getModel(); Rectangle bounds = null; - + bounds = state.getLabelBounds().getRectangle(); bounds.height += 10; - + // Applies the horizontal and vertical label positions if (model.isVertex(state.getCell())) { String horizontal = mxUtils.getString(state.getStyle(), mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER); - + if (horizontal.equals(mxConstants.ALIGN_LEFT)) { bounds.x -= state.getWidth(); } else if (horizontal.equals(mxConstants.ALIGN_RIGHT)) { bounds.x += state.getWidth(); } - + String vertical = mxUtils.getString(state.getStyle(), mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); - + if (vertical.equals(mxConstants.ALIGN_TOP)) { bounds.y -= state.getHeight(); } else if (vertical.equals(mxConstants.ALIGN_BOTTOM)) { bounds.y += state.getHeight(); } } - + bounds.setSize( (int) Math.max(bounds.getWidth(), Math.round(minimumWidth * scale)), (int) Math.max(bounds.getHeight(), Math.round(minimumHeight * scale))); - + return bounds; } - + } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 972a1cb..9808d10 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -1,21 +1,68 @@ package generators; -import algorithms.TypeInference; -import code.ast.*; -import models.Edge; -import models.Node; -import models.algebra.*; -import models.dataConstraintModel.*; -import models.dataFlowModel.*; -import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; - -import java.util.*; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import algorithms.TypeInference; + +import java.util.Set; +import java.util.Stack; + +import code.ast.Annotation; +import code.ast.Block; +import code.ast.CodeUtil; +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Constant; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.InvalidMessage; +import models.algebra.Parameter; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Position; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.algebra.Variable; +import models.dataConstraintModel.Channel; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; +import models.dataConstraintModel.ResourceHierarchy; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.Selector; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.IFlowGraph; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.ChannelNode; +import models.dataFlowModel.StoreAttribute; +import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; + public class CodeGeneratorFromDataFlowGraph extends CodeGenerator { - - public void generateCodeFromFlowGraph(DataTransferModel model, IFlowGraph flowGraph, Collection> components, ArrayList codes, - Map> dependedRootComponentGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + + public void generateCodeFromFlowGraph(DataTransferModel model, IFlowGraph flowGraph, Collection> components, ArrayList codes, + Map> dependedRootComponentGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { Map resourceComponents = new HashMap<>(); Map resourceConstructors = new HashMap<>(); Map> constructorParams = new HashMap<>(); @@ -37,7 +84,7 @@ } // For each components (1st pass). - for (Set componentNodeSet : components) { + for (Set componentNodeSet: components) { Node componentNode = componentNodeSet.iterator().next(); ResourceNode resourceNode = (ResourceNode) componentNode; TypeDeclaration component = null; @@ -56,7 +103,7 @@ } resourceComponents.put(resourceNode.getResourceHierarchy(), component); CompilationUnit cu = langSpec.newCompilationUnit(component); - if (!platformSpec.isMonolithic() && resourceNode.getResourceHierarchy().getParent() == null) { + if (!platformSpec.isMonolithic() && resourceNode.getResourceHierarchy().getParent() == null) { // For each root node, add platform specific imports. ((RestApiSpecific) platformSpec).addPlatformSpecificImports(cu); } @@ -75,12 +122,12 @@ } // Declare the fields to refer to reference resources. - declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); + declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); if (constructor.getParameters() == null || constructor.getParameters().size() == 0) { component.removeMethod(constructor); } else { - resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); + resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); } } @@ -107,7 +154,7 @@ // For each components (2nd pass). Map priorMemberForInputChannel = new HashMap<>(); Set generatedResources = new HashSet<>(); - for (Set componentNodeSet : components) { + for (Set componentNodeSet: components) { Node componentNode = componentNodeSet.iterator().next(); // Declare this resource. ResourceNode resourceNode = (ResourceNode) componentNode; @@ -116,7 +163,7 @@ TypeDeclaration parentComponent = null; TypeDeclaration rootComponent = null; if (generatesComponent(resourceNode.getResourceHierarchy())) { - component = resourceComponents.get(resourceNode.getResourceHierarchy()); + component = resourceComponents.get(resourceNode.getResourceHierarchy()); } if (resourceNode.getResourceHierarchy().getParent() != null) { parentComponent = resourceComponents.get(resourceNode.getResourceHierarchy().getParent()); @@ -125,14 +172,14 @@ // Declare cache fields and update methods in this resource, and an update accessor method in the type of root resource. Map.Entry, Map>>> initStatementsAndUpdateUpdates - = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, rootComponent, platformSpec, langSpec); + = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, rootComponent, platformSpec, langSpec); if (component == null) { // Constructor statements were not added to any component because no component had been generated. - for (String statement : initStatementsAndUpdateUpdates.getKey()) { + for (String statement: initStatementsAndUpdateUpdates.getKey()) { constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); } } - for (Map.Entry>> entry : initStatementsAndUpdateUpdates.getValue().entrySet()) { + for (Map.Entry>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) { updateStatements.put(entry.getKey(), entry.getValue()); } @@ -157,14 +204,14 @@ // Declare input methods in this component and the main component. if (!generatedResources.contains(resourceNode.getResourceHierarchy())) { Map.Entry, Map>>> initStatementsAndInputUpdates - = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, rootComponent, model, priorMemberForInputChannel, platformSpec, langSpec); + = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, rootComponent, model, priorMemberForInputChannel, platformSpec, langSpec); if (component == null) { // Constructor statements were not added to any component because no component had been generated. - for (String statement : initStatementsAndInputUpdates.getKey()) { + for (String statement: initStatementsAndInputUpdates.getKey()) { constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); } } - for (Map.Entry>> entry : initStatementsAndInputUpdates.getValue().entrySet()) { + for (Map.Entry>> entry: initStatementsAndInputUpdates.getValue().entrySet()) { updateStatements.put(entry.getKey(), entry.getValue()); } } @@ -173,17 +220,17 @@ } // Add constructor parameters to the ancestor components. - for (ResourceNode root : ((DataFlowGraph) flowGraph).getRootResourceNodes()) { + for (ResourceNode root: ((DataFlowGraph) flowGraph).getRootResourceNodes()) { addConstructorParameters(root.getResourceHierarchy(), resourceComponents, resourceConstructors, constructorParams, langSpec); } // Add constructor statements. - for (Map.Entry entry : constructorStatements) { + for (Map.Entry entry: constructorStatements) { resourceConstructors.get(entry.getKey()).addStatement(entry.getValue()); } // Add update statements. - for (MethodDeclaration method : updateStatements.keySet()) { + for (MethodDeclaration method: updateStatements.keySet()) { Expression updateExp = updateStatements.get(method).getKey(); ResourceHierarchy resource = updateStatements.get(method).getValue().getKey(); ResourceHierarchy descendantRes = updateStatements.get(method).getValue().getValue(); @@ -191,15 +238,15 @@ addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, resource, descendantRes, descendantComponent, langSpec); } } - + private static List addConstructorParameters(ResourceHierarchy resource, Map resourceComponents, - Map resourceConstructors, Map> constructorParams, ILanguageSpecific langSpec) { + Map resourceConstructors, Map> constructorParams, ILanguageSpecific langSpec) { List params = new ArrayList<>(); - for (ResourceHierarchy child : resource.getChildren()) { + for (ResourceHierarchy child: resource.getChildren()) { params.addAll(addConstructorParameters(child, resourceComponents, resourceConstructors, constructorParams, langSpec)); } if (constructorParams.get(resource) != null) { - for (VariableDeclaration param : constructorParams.get(resource).values()) { + for (VariableDeclaration param: constructorParams.get(resource).values()) { params.add(param); } } @@ -216,10 +263,10 @@ } } if (constructor != null) { - for (VariableDeclaration param : params) { + for (VariableDeclaration param: params) { boolean existsParam = false; if (constructor.getParameters() != null) { - for (VariableDeclaration constParam : constructor.getParameters()) { + for (VariableDeclaration constParam: constructor.getParameters()) { if (constParam.getName().equals(param.getName())) { existsParam = true; break; @@ -253,12 +300,12 @@ MethodDeclaration childConstructor = getConstructor(descendantComponent); List params = new ArrayList<>(); if (childConstructor != null) { - for (VariableDeclaration var : childConstructor.getParameters()) { + for (VariableDeclaration var: childConstructor.getParameters()) { // Extract the argument of each constructor parameter from jsonTerm. JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); jsonMember.addChild(jsonTerm); jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); - Expression param = jsonMember.reduce(); // Reduce {"name": "foo", age: 25}.name => "foo" + Expression param = jsonMember.reduce(); // Reduce {"name": "foo", age: 25}.name => "foo" if (param != null) { if (param instanceof Term) { if (((Term) param).getType() == null) { @@ -283,10 +330,10 @@ } } else { Type oldType = jsonTerm.getType(); - Type newType = new Type(oldType.getTypeName(), - oldType.getImplementationTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName), - oldType.getInterfaceTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName)); - for (Type parent : oldType.getParentTypes()) { + Type newType = new Type(oldType.getTypeName(), + oldType.getImplementationTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName), + oldType.getInterfaceTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName)); + for (Type parent: oldType.getParentTypes()) { newType.addParentType(parent); } jsonTerm.setType(newType); @@ -297,7 +344,7 @@ Type fieldType = getImplStateType(resource, langSpec); if (exp instanceof Term) { ((Term) exp).setType(fieldType); - for (Map.Entry varEnt : ((Term) exp).getVariables().entrySet()) { + for (Map.Entry varEnt: ((Term) exp).getVariables().entrySet()) { if (varEnt.getValue().getName().equals(fieldOfResourceState)) { varEnt.getValue().setType(fieldType); } @@ -305,11 +352,11 @@ } else if (exp instanceof Variable) { ((Variable) exp).setType(fieldType); } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String newState = exp.toImplementation(sideEffects); String updateStatement; if (exp instanceof Term && ((Term) exp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); } @@ -318,9 +365,9 @@ } method.addFirstStatement(updateStatement); } - - private MethodDeclaration declareConstructor(ResourceNode resourceNode, TypeDeclaration component, Map> dependedRootComponentGraph, - List depends, ILanguageSpecific langSpec) { + + private MethodDeclaration declareConstructor(ResourceNode resourceNode, TypeDeclaration component, Map> dependedRootComponentGraph, + List depends, ILanguageSpecific langSpec) { // Declare a constructor in each component. String resourceName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); MethodDeclaration constructor = langSpec.newMethodDeclaration(resourceName, true, null, null); @@ -328,24 +375,24 @@ constructor.setBody(block); component.addMethod(constructor); - for (Edge resToCh : resourceNode.getOutEdges()) { + for (Edge resToCh: resourceNode.getOutEdges()) { DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm: ch.getInputChannelMembers()) { if (resourceNode.getOutSideResources().contains(cm.getResource()) && cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } - for (Edge chToRes : resToCh.getDestination().getOutEdges()) { + for (Edge chToRes: resToCh.getDestination().getOutEdges()) { if (chToRes.getDestination() instanceof ResourceNode) { ResourceHierarchy dstRes = ((ResourceNode) chToRes.getDestination()).getResourceHierarchy(); // Check if the output resource is outside of the channel scope. boolean outsideOutputResource = false; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (((ResourceNode) chToRes.getDestination()).getInSideResources().contains(cm.getResource()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. + outsideOutputResource = true; // Regarded as push transfer. break; } } @@ -366,23 +413,23 @@ } } } - for (Edge chToRes : resourceNode.getInEdges()) { - for (Edge resToCh : chToRes.getSource().getInEdges()) { + for (Edge chToRes: resourceNode.getInEdges()) { + for (Edge resToCh: chToRes.getSource().getInEdges()) { ResourceHierarchy srcRes = ((ResourceNode) resToCh.getSource()).getResourceHierarchy(); DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm: ch.getInputChannelMembers()) { if (((ResourceNode) resToCh.getSource()).getOutSideResources().contains(cm.getResource()) && cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } // Check if the output resource is outside of the channel scope. boolean outsideOutputResource = false; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(cm.getResource()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. + outsideOutputResource = true; // Regarded as push transfer. break; } } @@ -404,8 +451,8 @@ } // Declare a field to refer to outside resources. if (resourceNode.getParent() == null) { - for (ResourceHierarchy dependedRes : dependedRootComponentGraph.keySet()) { - for (ResourceHierarchy dependingRes : dependedRootComponentGraph.get(dependedRes)) { + for (ResourceHierarchy dependedRes: dependedRootComponentGraph.keySet()) { + for (ResourceHierarchy dependingRes: dependedRootComponentGraph.get(dependedRes)) { if (resourceNode.getResourceHierarchy().equals(dependingRes)) { // Declare a field to refer to outside resources. depends.add(dependedRes); @@ -441,7 +488,7 @@ component.addField(stateField); } else { // class - for (ResourceHierarchy c : children) { + for (ResourceHierarchy c: children) { String childTypeName = getComponentName(c, langSpec); Type childType = null; if (generatesComponent(c)) { @@ -455,9 +502,9 @@ } } } - - private void declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, - Map> constructorParams, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + + 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; for (Edge resToCh : resourceNode.getOutEdges()) { @@ -466,9 +513,9 @@ DataTransferChannel directDstCh = directDstChNode.getChannel(); // Check if the source resource is outside of the channel scope. boolean outsideInputResource = false; - for (ChannelMember cm : directDstCh.getInputChannelMembers()) { + for (ChannelMember cm: directDstCh.getInputChannelMembers()) { if (cm.getResource().equals(resourceNode.getOutSideResource(directDstCh)) && cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } @@ -477,13 +524,13 @@ Set descendantDstChannels = directDstChNode.getDescendants(); Set outEdges = new HashSet<>(); outEdges.addAll(directDstChNode.getOutEdges()); - for (ChannelNode ancestorDst : ancestorDstChannels) { + for (ChannelNode ancestorDst: ancestorDstChannels) { outEdges.addAll(ancestorDst.getOutEdges()); } - for (ChannelNode descendantDst : descendantDstChannels) { + for (ChannelNode descendantDst: descendantDstChannels) { outEdges.addAll(descendantDst.getOutEdges()); } - for (Edge chToRes : outEdges) { + for (Edge chToRes: outEdges) { if (chToRes.getDestination() instanceof ResourceNode) { ResourceHierarchy dstRes = ((ResourceNode) chToRes.getDestination()).getResourceHierarchy(); ChannelNode chNode = (ChannelNode) chToRes.getSource(); @@ -491,11 +538,11 @@ // Check if the destination resource is outside of the channel scope. boolean outsideOutputResource = false; ChannelMember out = null; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (((ResourceNode) chToRes.getDestination()).getInSideResources().contains(cm.getResource())) { out = cm; if (cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. + outsideOutputResource = true; // Regarded as push transfer. break; } } @@ -503,10 +550,10 @@ ResourcePath dstResPath = out.getResource(); // Also take into account the channel hierarchy to determine push/pull transfer. if (descendantDstChannels.contains(chNode)) { - outsideOutputResource = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource = true; // Regarded as (broadcasting) push transfer. } if (ancestorDstChannels.contains(chNode)) { - outsideInputResource = true; // Regarded as (collecting) pull transfer. + outsideInputResource = true; // Regarded as (collecting) pull transfer. } if ((((PushPullAttribute) re.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { // Declare a field in the parent or this component to refer to the destination resource of push transfer. @@ -516,10 +563,10 @@ String dstResName = getComponentName(dstRes, langSpec); FieldDeclaration refFieldForPush = langSpec.newFieldDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); VariableDeclaration refVarForPush = langSpec.newVariableDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); - if (!platformSpec.isMonolithic() + if (!platformSpec.isMonolithic() && (outsideOutputResource || (resourceNode.getOutSideResource(ch).getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) - if (parentComponent != null && + if (parentComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(parentComponent)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); @@ -569,7 +616,7 @@ if (component != null) { // A component is created for this resource. boolean existsField = false; - for (FieldDeclaration field : component.getFields()) { + for (FieldDeclaration field: component.getFields()) { if (dstRootResName.equals(field.getName())) { existsField = true; break; @@ -589,7 +636,7 @@ } else { // No component is created for this resource. boolean existsField = false; - for (FieldDeclaration field : parentComponent.getFields()) { + for (FieldDeclaration field: parentComponent.getFields()) { if (dstRootResName.equals(field.getName())) { existsField = true; break; @@ -623,39 +670,39 @@ Set descendantSrcChannels = directSrcChNode.getDescendants(); Set inEdges = new HashSet<>(); inEdges.addAll(directSrcChNode.getInEdges()); - for (ChannelNode ancestorSrc : ancestorSrcChannels) { + for (ChannelNode ancestorSrc: ancestorSrcChannels) { inEdges.addAll(ancestorSrc.getInEdges()); } - for (ChannelNode descendantSrc : descendantSrcChannels) { + for (ChannelNode descendantSrc: descendantSrcChannels) { inEdges.addAll(descendantSrc.getInEdges()); } - for (Edge resToCh : inEdges) { + for (Edge resToCh: inEdges) { DataFlowEdge re = (DataFlowEdge) resToCh; ChannelNode chNode = (ChannelNode) re.getDestination(); DataTransferChannel ch = chNode.getChannel(); ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(ch); // Check if the source resource is outside of the channel scope. boolean outsideInputResource = false; - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm: ch.getInputChannelMembers()) { if (cm.getResource().equals(srcRes) && cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } // Check if the output resource is outside of the channel scope. boolean outsideOutputResource = false; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(cm.getResource()) && cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. + outsideOutputResource = true; // Regarded as push transfer. break; } } // Also take into account the channel hierarchy to determine push/pull transfer. if (descendantSrcChannels.contains(chNode)) { - outsideInputResource = true; // Regarded as (collecting) pull transfer. + outsideInputResource = true; // Regarded as (collecting) pull transfer. } if (ancestorSrcChannels.contains(chNode)) { - outsideOutputResource = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource = true; // Regarded as (broadcasting) push transfer. } if ((((PushPullAttribute) re.getAttribute()).getSelectedOption() != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { noPullTransfer = false; @@ -666,10 +713,10 @@ String srcResName = getComponentName(srcRes.getResourceHierarchy(), langSpec); FieldDeclaration refFieldForPull = langSpec.newFieldDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); VariableDeclaration refVarForPull = langSpec.newVariableDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); - if (!platformSpec.isMonolithic() + if (!platformSpec.isMonolithic() && (outsideInputResource || (resourceNode.getInSideResource(ch).getCommonPrefix(srcRes) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) - if (parentComponent != null + if (parentComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(parentComponent)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); @@ -720,7 +767,7 @@ if (component != null) { // A component is created for this resource. boolean existsField = false; - for (FieldDeclaration field : component.getFields()) { + for (FieldDeclaration field: component.getFields()) { if (srcRootResName.equals(field.getName())) { existsField = true; break; @@ -740,14 +787,14 @@ } else { // No component is created for this resource. boolean existsField = false; - for (FieldDeclaration field : parentComponent.getFields()) { + for (FieldDeclaration field: parentComponent.getFields()) { if (srcRootResName.equals(field.getName())) { existsField = true; break; } } if (!existsField) { - parentComponent.addField(refRootFieldForPull); + parentComponent.addField(refRootFieldForPull); Map nameToParam = constructorParams.get(resourceNode.getParent().getResourceHierarchy()); if (nameToParam == null) { nameToParam = new HashMap<>(); @@ -770,7 +817,7 @@ if (((StoreAttribute) resourceNode.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { String resName = langSpec.toVariableName(getComponentName(res, langSpec)); boolean existsField = false; - for (FieldDeclaration field : parentComponent.getFields()) { + for (FieldDeclaration field: parentComponent.getFields()) { if (resName.equals(field.getName())) { existsField = true; break; @@ -793,8 +840,8 @@ } - private MethodDeclaration declareStateGetterMethod(ResourceNode resourceNode, TypeDeclaration component, Type resStateType, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + private MethodDeclaration declareStateGetterMethod(ResourceNode resourceNode, TypeDeclaration component, Type resStateType, + IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Declare the getter method of the resource state. MethodDeclaration stateGetter = langSpec.newMethodDeclaration(getterOfResourceState, resStateType); if (!platformSpec.isMonolithic() && resourceNode.getResourceHierarchy().getParent() == null) { @@ -806,7 +853,7 @@ boolean hasDescendantIn = hasDescendantInput(resourceNode); if (((StoreAttribute) resourceNode.getAttribute()).isStored() && !hasDescendantIn) { fillStateGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), resStateType, platformSpec, langSpec); - } else { + } else { // 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. @@ -819,8 +866,8 @@ return stateGetter; } - private MethodDeclaration declareStateGetterMethodInAncestor(ResourceNode resourceNode, Map resourceComponents, Type resStateType, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + private MethodDeclaration declareStateGetterMethodInAncestor(ResourceNode resourceNode, Map resourceComponents, Type resStateType, + IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Search an ancestor in which the getter method is declared. ResourceNode ancestorNode = resourceNode; ResourceNode childNode = null; @@ -847,10 +894,9 @@ } // Check duplication. String getterName = getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec); - for (MethodDeclaration method : ancestorComponent.getMethods()) { - if (method.getName().equals(getterName) - && (method.getParameters() == null ? 0 : method.getParameters().size()) == getterParams.size()) - return null; + for (MethodDeclaration method: ancestorComponent.getMethods()) { + if (method.getName().equals(getterName) + && (method.getParameters() == null ? 0 : method.getParameters().size()) == getterParams.size()) return null; } // Declare the getter method of the resource state. @@ -867,7 +913,7 @@ boolean hasDescendantIn = hasDescendantInput(resourceNode); if (((StoreAttribute) resourceNode.getAttribute()).isStored() && !hasDescendantIn) { fillDescendantGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), childNode.getResourceHierarchy(), ancestorNode.getResourceHierarchy(), ancestorComponent, langSpec); - } else { + } else { if (addOtherGetterInvocationsToStateGatter(stateGetter, resourceNode, platformSpec, langSpec)) { // Declare a client field to connect to the destination resource of push transfer. if (ancestorComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(ancestorComponent)) { @@ -878,14 +924,13 @@ return stateGetter; } - + private boolean hasDescendantInput(ResourceNode resourceNode) { boolean hasDescendantIn = false; - outer: - for (Edge chToRes : resourceNode.getInEdges()) { + outer: for (Edge chToRes: resourceNode.getInEdges()) { ChannelNode chNode = (ChannelNode) chToRes.getSource(); Set descendantChannels = chNode.getDescendants(); - for (ChannelNode descendantCh : descendantChannels) { + for (ChannelNode descendantCh: descendantChannels) { if (descendantCh.getIndegree() > 0) { hasDescendantIn = true; break outer; @@ -894,9 +939,9 @@ } return hasDescendantIn; } - + private boolean addOtherGetterInvocationsToStateGatter(MethodDeclaration stateGetter, ResourceNode resourceNode, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { boolean bDeclareClientField = false; try { // Data transfer on the same channel hierarchy. @@ -904,12 +949,12 @@ DataTransferChannel ch = null; DataTransferChannel ch2 = null; HashMap inputResourceToStateAccessor = new HashMap<>(); - for (Edge chToRes : resourceNode.getInEdges()) { + for (Edge chToRes: resourceNode.getInEdges()) { ch2 = ((ChannelNode) chToRes.getSource()).getChannel(); - for (Edge resToCh : chToRes.getSource().getInEdges()) { + for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge dIn = (DataFlowEdge) resToCh; ChannelMember in = null; - for (ChannelMember cm : ch2.getInputChannelMembers()) { + for (ChannelMember cm: ch2.getInputChannelMembers()) { if (((ResourceNode) dIn.getSource()).getOutSideResources().contains(cm.getResource())) { in = cm; break; @@ -922,23 +967,23 @@ } else { // PULL transfer inputResourceToStateAccessor.put(in, getPullAccessor(platformSpec)); - ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // pull containing input side channel is at most one. - if (!platformSpec.isMonolithic() - && !in.isOutside() - && in.getResource().getCommonPrefix(resourceNode.getInSideResource(ch2)) == null + ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // pull containing input side channel is at most one. + if (!platformSpec.isMonolithic() + && !in.isOutside() + && in.getResource().getCommonPrefix(resourceNode.getInSideResource(ch2)) == null && platformSpec.isDifferentTreesAsDifferentServices()) { // for REST API ResourcePath srcResPath = in.getResource(); String srcResourceName = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); Type srcResourceType = srcResPath.getResourceStateType(); List pathParams = new ArrayList<>(); - for (Expression pathExp : srcResPath.getPathParams()) { - String[] sideEffects = new String[]{""}; + for (Expression pathExp: srcResPath.getPathParams()) { + String[] sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(stateGetter, srcResourceName, - srcResPath.getResourceHierarchy().toResourcePath(pathParams), srcResourceType, - true, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, srcResourceName, + srcResPath.getResourceHierarchy().toResourcePath(pathParams), srcResourceType, + true, platformSpec, langSpec); bDeclareClientField = true; } } @@ -948,7 +993,7 @@ ch = ch2; } ChannelMember out = null; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(cm.getResource())) { out = cm; break; @@ -957,23 +1002,23 @@ // for reference channel members. ResourcePath dstResPath = resourceNode.getInSideResource(ch); - for (ChannelMember rc : ch.getReferenceChannelMembers()) { - inputResourceToStateAccessor.put(rc, getPullAccessor(platformSpec)); // by pull data transfer + for (ChannelMember rc: ch.getReferenceChannelMembers()) { + inputResourceToStateAccessor.put(rc, getPullAccessor(platformSpec)); // by pull data transfer ResourcePath refResPath = rc.getResource(); - if (!platformSpec.isMonolithic() - && (rc.isOutside() - || (refResPath.getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { + if (!platformSpec.isMonolithic() + && (rc.isOutside() + || (refResPath.getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // for REST API String refResourceName = langSpec.toVariableName(getComponentName(refResPath.getResourceHierarchy(), langSpec)); Type refResourceType = refResPath.getResourceStateType(); List pathParams = new ArrayList<>(); - for (Expression pathExp : refResPath.getPathParams()) { - String[] sideEffects = new String[]{""}; + for (Expression pathExp: refResPath.getPathParams()) { + String[] sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(stateGetter, refResourceName, - refResPath.getResourceHierarchy().toResourcePath(pathParams), refResourceType, - true, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, refResourceName, + refResPath.getResourceHierarchy().toResourcePath(pathParams), refResourceType, + true, platformSpec, langSpec); bDeclareClientField = true; } } @@ -991,18 +1036,18 @@ Term messageTerm = resourcePathsAndMessage.getValue(); // Data transfer from path depending resource. - for (Entry>> pathEnt : resourcePaths.entrySet()) { + for (Entry>> pathEnt: resourcePaths.entrySet()) { ChannelMember cm = pathEnt.getKey(); ResourcePath srcResPath = pathEnt.getValue().getKey(); // get outside srcResPath resource state by pull data transfer. - if (!platformSpec.isMonolithic() - && (cm.isOutside() - || (srcResPath.getCommonPrefix(dstResPath)) == null && platformSpec.isDifferentTreesAsDifferentServices())) { + if (!platformSpec.isMonolithic() + && (cm.isOutside() + || (srcResPath.getCommonPrefix(dstResPath)) == null && platformSpec.isDifferentTreesAsDifferentServices())) { // for REST API // Data transfer from an outside input resource is regarded as PULL transfer. List pathParams = new ArrayList<>(); - for (Expression pathExp : srcResPath.getPathParams()) { - String[] sideEffects = new String[]{""}; + for (Expression pathExp: srcResPath.getPathParams()) { + String[] sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } // generate a pull data transfer from a depending in/ref resource. @@ -1024,22 +1069,22 @@ if (!chItr.hasNext()) { chItr = channelItrStack.pop(); } else { - curChannel = (DataTransferChannel) chItr.next(); + curChannel = (DataTransferChannel) chItr.next(); // generate pull data transfers. Set chMems = new HashSet<>(curChannel.getInputChannelMembers()); chMems.addAll(curChannel.getReferenceChannelMembers()); - for (ChannelMember cm2 : chMems) { + for (ChannelMember cm2: chMems) { if (resourcePaths == null || !resourcePaths.keySet().contains(cm2)) { // not a depending channel member. ResourcePath src2 = cm2.getResource(); Type srcResType2 = src2.getResourceStateType(); String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { - String srcGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[]{}); - stateGetter.addStatement(langSpec.getVariableDeclaration(srcResType2.getInterfaceTypeName(), srcResName2) + String srcGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {}); + stateGetter.addStatement(langSpec.getVariableDeclaration(srcResType2.getInterfaceTypeName(), srcResName2) + langSpec.getAssignment() + srcGetter + langSpec.getStatementDelimiter()); } else { - String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(stateGetter, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); bDeclareClientField = true; } @@ -1052,11 +1097,11 @@ Type srcResType2 = src2.getResourceStateType(); String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { - String dependingGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[]{}); + String dependingGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {}); stateGetter.addStatement(langSpec.getVariableDeclaration(srcResType2.getInterfaceTypeName(), srcResName2) + langSpec.getAssignment() + dependingGetter + langSpec.getStatementDelimiter()); } else { - String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(stateGetter, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); bDeclareClientField = true; } @@ -1070,13 +1115,13 @@ if (resourcePathsAndMessage != null) { resourcePaths = resourcePathsAndMessage.getKey(); Term messageTermSub = resourcePathsAndMessage.getValue(); - for (Entry fieldEnt : ((Term) messageTermSub).getSubTerms(Field.class).entrySet()) { + for (Entry fieldEnt: ((Term) messageTermSub).getSubTerms(Field.class).entrySet()) { Position pos = fieldEnt.getKey(); Field field = fieldEnt.getValue(); Variable var = new Variable(field.getSymbol().getName(), field.getType()); ((Term) messageTermSub).replaceSubTerm(pos, var); } - for (Map.Entry subTermEnt : messageTermSub.getSubTerms(Term.class).entrySet()) { + for (Map.Entry subTermEnt: messageTermSub.getSubTerms(Term.class).entrySet()) { Term subTerm = subTermEnt.getValue(); if (!(subTerm instanceof Constant) && subTerm.getSymbol().isImplWithSideEffect()) { Variable var = new Variable("v" + v, subTerm.getType()); @@ -1086,7 +1131,7 @@ Position pos = new Position(); pos.addHeadOrder(0); subTerm.replaceSubTerm(pos, var); - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String curState = messageTermSub.toImplementation(sideEffects); stateGetter.addStatement(sideEffects[0].replaceAll("\n", "")); // Cancel the side effects in the return value. @@ -1111,14 +1156,14 @@ selType = ((Variable) selExp).getType(); forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm2 : curChannel.getInputChannelMembers()) { + for (ChannelMember cm2 :curChannel.getInputChannelMembers()) { if (!cm2.isOutside()) { insideChMem = cm2; break; } } if (insideChMem == null) { - for (ChannelMember cm2 : curChannel.getReferenceChannelMembers()) { + for (ChannelMember cm2 :curChannel.getReferenceChannelMembers()) { if (!cm2.isOutside()) { insideChMem = cm2; break; @@ -1132,16 +1177,16 @@ insideResPath = insideResPath.getParent(); if (insideResPath != null) { String parent = null; - if (platformSpec.isMonolithic() - || insideResPath.getCommonPrefix(dstResPath) != null + if (platformSpec.isMonolithic() + || insideResPath.getCommonPrefix(dstResPath) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { Expression parentGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(parentGetter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath).toImplementation(new String[]{}); + parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath).toImplementation(new String[] {}); } } else { // for REST API @@ -1154,20 +1199,20 @@ // make a for loop (for a map) for data collecting. stateGetter.addFirstStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); } - if (!platformSpec.isMonolithic() - && insideResPath.getCommonPrefix(dstResPath) == null + if (!platformSpec.isMonolithic() + && insideResPath.getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()) { // for REST API Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); - String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(stateGetter, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); bDeclareClientField = true; } } } // initialize the variables to hold side effects within the loop - for (Variable var : varsForSideEffects) { + for (Variable var: varsForSideEffects) { stateGetter.addFirstStatement(langSpec.getVariableDeclaration(var.getType().getInterfaceTypeName(), var.getName()) + langSpec.getAssignment() + langSpec.getConstructorInvocation(var.getType().getImplementationTypeName(), null) + langSpec.getStatementDelimiter()); } @@ -1182,11 +1227,11 @@ } // generate a return statement. - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String curState = ch.deriveUpdateExpressionOf(out, messageTerm, getPullAccessor(platformSpec)).toImplementation(sideEffects); stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } return bDeclareClientField; @@ -1199,7 +1244,7 @@ descendants = new HashSet<>(); descendantGetters.put(resourceNode.getResourceHierarchy(), descendants); } - for (ResourceNode child : resourceNode.getChildren()) { + for (ResourceNode child: resourceNode.getChildren()) { // A descendant of the child may generate a component. List params = new ArrayList<>(); int v = 1; @@ -1240,13 +1285,13 @@ } } - private Map.Entry, Map>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, - TypeDeclaration component, TypeDeclaration parentComponent, TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + private Map.Entry, Map>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, + TypeDeclaration component, TypeDeclaration parentComponent, TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Declare cash fields and update methods in the component. String resComponentName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); List constructorStatements = new ArrayList<>(); Map>> updateStatements = new HashMap<>(); - for (Edge chToRes : resourceNode.getInEdges()) { + for (Edge chToRes: resourceNode.getInEdges()) { ChannelNode directSrcChannel = (ChannelNode) chToRes.getSource(); DataTransferChannel ch = directSrcChannel.getChannel(); // Should take into account the channel hierarchy. @@ -1254,13 +1299,13 @@ Set descendantSrcChannels = directSrcChannel.getDescendants(); Set inEdges = new HashSet<>(); inEdges.addAll(directSrcChannel.getInEdges()); - for (ChannelNode ancestorSrc : ancestorSrcChannels) { + for (ChannelNode ancestorSrc: ancestorSrcChannels) { inEdges.addAll(ancestorSrc.getInEdges()); } - for (ChannelNode descendantSrc : descendantSrcChannels) { + for (ChannelNode descendantSrc: descendantSrcChannels) { inEdges.addAll(descendantSrc.getInEdges()); } - for (Edge resToCh : inEdges) { + for (Edge resToCh: inEdges) { // For each data transfer from srcResPath:ResourcePath to resourceNode:ResourceNode. DataFlowEdge re = (DataFlowEdge) resToCh; ChannelNode indirectSrcChNode = (ChannelNode) re.getDestination(); @@ -1270,9 +1315,9 @@ String srcResName = langSpec.toVariableName(srcResComponentName); // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; - for (ChannelMember cm : indirectSrcCh.getInputChannelMembers()) { + for (ChannelMember cm: indirectSrcCh.getInputChannelMembers()) { if (cm.getResource().equals(srcResPath) && cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } @@ -1280,29 +1325,29 @@ boolean outsideOutputResource = false; ChannelMember out = null; ResourcePath dstResPath = null; - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(cm.getResource())) { out = cm; dstResPath = cm.getResource(); if (cm.isOutside()) { - outsideOutputResource = true; // Regarded as push transfer. + outsideOutputResource = true; // Regarded as push transfer. break; } } } // Also take into account the channel hierarchy to determine push/pull transfer. if (ancestorSrcChannels.contains(indirectSrcChNode)) { - outsideOutputResource = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource = true; // Regarded as (broadcasting) push transfer. } if (descendantSrcChannels.contains(indirectSrcChNode)) { - outsideInputResource = true; // Regarded as (collecting) pull transfer. + outsideInputResource = true; // Regarded as (collecting) pull transfer. } if ((((PushPullAttribute) re.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { // For push data transfer boolean hasRestAPI = false; boolean isRestAPI = false; - if (!platformSpec.isMonolithic() + if (!platformSpec.isMonolithic() && (outsideOutputResource || (resourceNode.getInSideResource(ch).getCommonPrefix(srcResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service hasRestAPI = true; @@ -1317,21 +1362,20 @@ } // Declare an update method in the type of the destination resource. ArrayList parameters = new ArrayList<>(); - getUpdateResourcePathAndPathParams(dstResPath, parameters, isRestAPI, platformSpec, langSpec); // Path parameters to identify the self resource. - for (Selector selector : ch.getAllSelectors()) { + getUpdateResourcePathAndPathParams(dstResPath, parameters, isRestAPI, platformSpec, langSpec); // Path parameters to identify the self resource. + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); VariableDeclaration chParam = langSpec.newVariableDeclaration(selVar.getType(), selVar.getName()); - if (isRestAPI) - ((RestApiSpecific) platformSpec).addFormParamAnnotation(chParam, selVar.getName()); - parameters.add(chParam); // A channel parameter to specify the context of the collaboration. + if (isRestAPI) ((RestApiSpecific) platformSpec).addFormParamAnnotation(chParam, selVar.getName()); + parameters.add(chParam); // A channel parameter to specify the context of the collaboration. } } VariableDeclaration param = langSpec.newVariableDeclaration(srcResPath.getResourceStateType(), srcResName); if (isRestAPI) ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, srcResName); - parameters.add(param); // The state of the source resource to carry the data-flow. + parameters.add(param); // The state of the source resource to carry the data-flow. // For the refs. - for (ResourcePath ref : ch.getReferenceResources()) { + for (ResourcePath ref: ch.getReferenceResources()) { if (!resourceNode.getInSideResources().contains(ref)) { String refName = langSpec.toVariableName(getComponentName(ref.getResourceHierarchy(), langSpec)); param = langSpec.newVariableDeclaration(ref.getResourceStateType(), refName); @@ -1341,7 +1385,7 @@ } MethodDeclaration update = null; if (component != null) { - for (MethodDeclaration method : component.getMethods()) { + for (MethodDeclaration method: component.getMethods()) { if (method.getName().equals(updateMethodPrefix + from + srcResComponentName)) { update = method; break; @@ -1351,7 +1395,7 @@ update = langSpec.newMethodDeclaration(updateMethodPrefix + from + srcResComponentName, false, null, parameters); } } else if (parentComponent != null) { - for (MethodDeclaration method : parentComponent.getMethods()) { + for (MethodDeclaration method: parentComponent.getMethods()) { if (method.getName().equals(updateMethodPrefix + resComponentName + from + srcResComponentName)) { update = method; break; @@ -1363,8 +1407,8 @@ } // Calculate in-degree (PUSH transfer) of the destination resource. int inDegree = 0; - for (Edge resToCh2 : inEdges) { - DataFlowEdge df = (DataFlowEdge) resToCh2; + for (Edge resToCh2: inEdges) { + DataFlowEdge df =(DataFlowEdge) resToCh2; if (((PushPullAttribute) df.getAttribute()).getSelectedOption() == PushPullValue.PUSH) { inDegree++; } @@ -1403,7 +1447,7 @@ rootComponent, inDegree, platformSpec, langSpec); } // to convert a json param to a tuple, pair or map object. - for (VariableDeclaration jsonParam : update.getParameters()) { + for (VariableDeclaration jsonParam: update.getParameters()) { Type paramType = jsonParam.getType(); String paramName = jsonParam.getName(); String paramTypeName = paramType.getInterfaceTypeName(); @@ -1477,7 +1521,7 @@ try { if (resourceNode.getInSideResources().contains(out.getResource())) { Term unifiedMassage = null; - for (ChannelNode srcChNode : ancestorSrcChannels) { + for (ChannelNode srcChNode: ancestorSrcChannels) { DataTransferChannel abcestorSrcCh = (DataTransferChannel) srcChNode.getChannel(); Term message = abcestorSrcCh.fillOutsideResourcePaths(out, getPushAccessor(platformSpec), null).getValue(); if (unifiedMassage == null) { @@ -1498,10 +1542,10 @@ } else { // if there exists one or more reference channel member. HashMap inputResourceToStateAccessor = new HashMap<>(); - for (ChannelMember in : ch.getInputChannelMembers()) { + for (ChannelMember in: ch.getInputChannelMembers()) { inputResourceToStateAccessor.put(in, getPushAccessor(platformSpec)); } - for (ChannelMember ref : ch.getReferenceChannelMembers()) { + for (ChannelMember ref: ch.getReferenceChannelMembers()) { inputResourceToStateAccessor.put(ref, getRefAccessor(platformSpec)); } Term message = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec), inputResourceToStateAccessor).getValue(); @@ -1531,7 +1575,7 @@ Type fieldType = getImplStateType(outRes, langSpec); if (updateExp instanceof Term) { ((Term) updateExp).setType(fieldType); - for (Map.Entry varEnt : ((Term) updateExp).getVariables().entrySet()) { + for (Map.Entry varEnt: ((Term) updateExp).getVariables().entrySet()) { if (varEnt.getValue().getName().equals(fieldOfResourceState)) { varEnt.getValue().setType(fieldType); } @@ -1540,10 +1584,10 @@ ((Variable) updateExp).setType(fieldType); } // Add statements to the update method. - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String newState = updateExp.toImplementation(sideEffects); int numOfOutResourcesWithTheSameHierarchy = 0; - for (ResourcePath outResPath : ch.getOutputResources()) { + for (ResourcePath outResPath: ch.getOutputResources()) { if (outResPath.getResourceHierarchy().equals(outRes)) { numOfOutResourcesWithTheSameHierarchy++; } @@ -1556,7 +1600,7 @@ updateStatement = updateStatement.substring(0, updateStatement.length() - 1); } } else { - updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); // this.value = ... + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); // this.value = ... } } else { if (sideEffects[0] != null) { @@ -1572,7 +1616,7 @@ selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newList = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (DataConstraintModel.typeMap.isAncestorOf(resourceNode.getParent().getResourceStateType())) { @@ -1580,7 +1624,7 @@ selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newMap = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { @@ -1595,11 +1639,11 @@ Term conditions = null; int i = 1; Map>> resourcePaths = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec)); - for (Expression pathParam : out.getResource().getPathParams()) { + for (Expression pathParam: out.getResource().getPathParams()) { if (pathParam instanceof Variable) { String selfParamName = ((Variable) pathParam).getName(); Expression arg = null; - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); if (selVar.getName().equals(selfParamName)) { @@ -1612,14 +1656,14 @@ ResourcePath filledPath = resourcePaths.get(out).getKey(); arg = filledPath.getPathParams().get(i - 1); } - Term condition = new Term(DataConstraintModel.eq, new Expression[]{ - new Parameter("self" + (i > 1 ? i : ""), DataConstraintModel.typeString), + Term condition = new Term(DataConstraintModel.eq, new Expression[] { + new Parameter("self" + (i > 1 ? i : ""), DataConstraintModel.typeString), arg}); if (conditions == null) { conditions = condition; } else { - conditions = new Term(DataConstraintModel.and, new Expression[]{ - conditions, + conditions = new Term(DataConstraintModel.and, new Expression[] { + conditions, condition}); } } @@ -1629,7 +1673,7 @@ } } } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e1) { + | InvalidMessage | UnificationFailed | ValueUndefined e1) { e1.printStackTrace(); } } @@ -1642,12 +1686,12 @@ // Declare the cache field. String cacheFieldName = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); FieldDeclaration cacheField = langSpec.newFieldDeclaration( - srcResPath.getResourceStateType(), - cacheFieldName, - langSpec.getFieldInitializer(srcResPath.getResourceStateType(), srcResPath.getResourceHierarchy().getInitialValue())); + srcResPath.getResourceStateType(), + cacheFieldName, + langSpec.getFieldInitializer(srcResPath.getResourceStateType(), srcResPath.getResourceHierarchy().getInitialValue())); if (component != null) { component.addField(cacheField); - } else if (parentComponent != null) { + } else if (parentComponent != null){ parentComponent.addField(cacheField); } @@ -1663,28 +1707,27 @@ if (platformSpec.isMonolithic()) { // For a monolithic application. Set outsideInputMembers = new HashSet<>(); - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm: ch.getInputChannelMembers()) { if (cm.isOutside()) { outsideInputMembers.add(cm); } } if (outsideInputMembers.size() > 0) { Map>> resourcePaths = null; - for (ChannelMember out1 : ch.getOutputChannelMembers()) { + 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) { + } 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()) { + 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(); @@ -1696,20 +1739,20 @@ 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)))); + outsideExp = ((Term) outsideExp).substitute((Variable) nextExp, new Field(langSpec.toVariableName(getComponentName(dependingMember.getResource().getResourceHierarchy(), langSpec)))); } else { // ToDo. } } - String[] sideEffects = new String[]{""}; + 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.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) { + constructor.addStatement(updateReference); // Initialize the reference field. + } else if (parentComponent != null){ constructorStatements.add(updateReference); } } @@ -1721,7 +1764,7 @@ // Add an invocation to another update method (for a chain of update method invocations). boolean hasUpdateMethodinvoked = false; - for (Edge resToCh2 : resourceNode.getOutEdges()) { + for (Edge resToCh2: resourceNode.getOutEdges()) { DataFlowEdge dOut = (DataFlowEdge) resToCh2; ChannelNode directDstChNode = (ChannelNode) resToCh2.getDestination(); DataTransferChannel directDstCh = directDstChNode.getChannel(); @@ -1729,10 +1772,10 @@ boolean outsideInputResource2 = false; ChannelMember in = null; Set outsideInputMembers2 = new HashSet<>(); - for (ChannelMember cm : directDstCh.getInputChannelMembers()) { + for (ChannelMember cm: directDstCh.getInputChannelMembers()) { if (cm.getResource().equals(resourceNode.getOutSideResource(directDstCh))) { if (cm.isOutside()) { - outsideInputResource2 = true; // Regarded as pull transfer. + outsideInputResource2 = true; // Regarded as pull transfer. } in = cm; } @@ -1745,13 +1788,13 @@ Set descendantDstChannels = directDstChNode.getDescendants(); Set outEdges = new HashSet<>(); outEdges.addAll(directDstChNode.getOutEdges()); - for (ChannelNode ancestorDst : ancestorDstChannels) { + for (ChannelNode ancestorDst: ancestorDstChannels) { outEdges.addAll(ancestorDst.getOutEdges()); } - for (ChannelNode descendantDst : descendantDstChannels) { + for (ChannelNode descendantDst: descendantDstChannels) { outEdges.addAll(descendantDst.getOutEdges()); } - for (Edge chToRes2 : outEdges) { + for (Edge chToRes2: outEdges) { // For each data transfer to dstNode:ResourceNode. ResourceNode dstNode = ((ResourceNode) chToRes2.getDestination()); ChannelNode chNode2 = (ChannelNode) chToRes2.getSource(); @@ -1759,7 +1802,7 @@ // Check if the output resource is outside of the channel scope. boolean outsideOutputResource2 = false; ChannelMember out1 = null; - for (ChannelMember cm : ch2.getOutputChannelMembers()) { + for (ChannelMember cm: ch2.getOutputChannelMembers()) { if (dstNode.getInSideResources().contains(cm.getResource())) { out1 = cm; if (cm.isOutside()) { @@ -1770,10 +1813,10 @@ } // Also take into account the channel hierarchy to determine push/pull transfer. if (descendantDstChannels.contains(chNode2)) { - outsideOutputResource2 = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource2 = true; // Regarded as (broadcasting) push transfer. } if (ancestorDstChannels.contains(chNode2)) { - outsideInputResource2 = true; // Regarded as (collecting) pull transfer. + outsideInputResource2 = true; // Regarded as (collecting) pull transfer. } if ((((PushPullAttribute) dOut.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource2) || outsideOutputResource2) { // PUSH transfer @@ -1788,14 +1831,14 @@ selType = ((Variable) selExp).getType(); forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm : ch2.getInputChannelMembers()) { + for (ChannelMember cm :ch2.getInputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; } } if (insideChMem == null) { - for (ChannelMember cm : ch2.getReferenceChannelMembers()) { + for (ChannelMember cm :ch2.getReferenceChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -1803,7 +1846,7 @@ } } if (insideChMem == null) { - for (ChannelMember cm : ch2.getOutputChannelMembers()) { + for (ChannelMember cm :ch2.getOutputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -1817,16 +1860,16 @@ insideResPath = insideResPath.getParent(); if (insideResPath != null) { String parent = null; - if (platformSpec.isMonolithic() - || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null + if (platformSpec.isMonolithic() + || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { Expression getter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[]{}); + parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {}); } } else { // for REST API @@ -1841,13 +1884,13 @@ update.addStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); addForStatement = true; } - if (!platformSpec.isMonolithic() - && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null + if (!platformSpec.isMonolithic() + && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null && platformSpec.isDifferentTreesAsDifferentServices()) { // for REST API Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); - String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(update, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); } } @@ -1858,9 +1901,9 @@ } // Get the value of reference member to call the update method. List>> refParams = new ArrayList<>(); - Map> referredResources = new HashMap<>(); + Map> referredResources = new HashMap<>(); Set referredSet = referredResources.get(update); - for (ChannelMember rc : ch2.getReferenceChannelMembers()) { + for (ChannelMember rc: ch2.getReferenceChannelMembers()) { ResourcePath ref = rc.getResource(); if (referredSet == null) { referredSet = new HashSet<>(); @@ -1871,37 +1914,39 @@ Type refResourceType = ref.getResourceStateType(); if (!referredSet.contains(ref)) { referredSet.add(ref); - String[] sideEffects = new String[]{""}; - if (!platformSpec.isMonolithic() && rc.isOutside()) { + String[] sideEffects = new String[] {""}; + ResourcePath srcRes = in.getResource(); + if (!generatesComponent(srcRes.getResourceHierarchy())) { + srcRes = srcRes.getParent(); + } + if (!platformSpec.isMonolithic() + && (rc.isOutside() || (ref.getCommonPrefix(srcRes) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { List pathParams = new ArrayList<>(); - for (Expression pathExp : ref.getPathParams()) { + for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } generatePullDataTransfer(update, refVarName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, false, platformSpec, langSpec); } else { - ResourcePath srcRes = in.getResource(); - if (!generatesComponent(srcRes.getResourceHierarchy())) { - srcRes = srcRes.getParent(); - } Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - update.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + update.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } } refParams.add(new AbstractMap.SimpleEntry<>(ref.getResourceStateType(), - new AbstractMap.SimpleEntry<>(refVarName, - refVarName))); + new AbstractMap.SimpleEntry<>(refVarName, + refVarName))); } } - List>> pathParams = new ArrayList<>(); + List>> pathParams = new ArrayList<>(); if (platformSpec.isMonolithic()) { // Update fields to refer to outside resources. ResourcePath filledOutsideResourcePath = null; try { Map>> resourcePaths = ch2.fillOutsideResourcePaths(out1, getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember : resourcePaths.keySet()) { + for (ChannelMember outsideMember: resourcePaths.keySet()) { ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); if (out1.equals(outsideMember)) { filledOutsideResourcePath = outsidePath; @@ -1917,72 +1962,71 @@ if (outsideExp instanceof Field) { outsideExp = new Variable(((Field) outsideExp).getSymbol().getName(), ((Field) outsideExp).getType()); } else if (outsideExp instanceof Term) { - for (Entry fieldEnt : ((Term) outsideExp).getSubTerms(Field.class).entrySet()) { + for (Entry fieldEnt: ((Term) outsideExp).getSubTerms(Field.class).entrySet()) { Position pos = fieldEnt.getKey(); Field field = fieldEnt.getValue(); Variable var = new Variable(field.getSymbol().getName(), field.getType()); ((Term) outsideExp).replaceSubTerm(pos, var); } } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - update.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + update.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. } } - } catch (ParameterizedIdentifierIsFutureWork | - ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } // Values of path parameters to call the update method. if (filledOutsideResourcePath == null) { filledOutsideResourcePath = out1.getResource(); } - for (Expression pathParam : filledOutsideResourcePath.getPathParams()) { + for (Expression pathParam: filledOutsideResourcePath.getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getName(), - pathVar.getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getName(), + pathVar.getName()))); } else if (pathParam instanceof Constant) { Constant pathVar = (Constant) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getSymbol().getName(), - pathVar.getSymbol().getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getSymbol().getName(), + pathVar.getSymbol().getName()))); } } } else { // Values of path parameters to call the update method. - for (Expression pathParam : out1.getResource().getPathParams()) { + for (Expression pathParam: out1.getResource().getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getName(), - pathVar.getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getName(), + pathVar.getName()))); } } } // Values of channel parameters to call the update method. - List>> params = new ArrayList<>(); - for (Selector selector : ch2.getAllSelectors()) { + List>> params = new ArrayList<>(); + for (Selector selector: ch2.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); - params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), - new AbstractMap.SimpleEntry<>(selVar.getName(), - selVar.getName()))); + params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), + new AbstractMap.SimpleEntry<>(selVar.getName(), + selVar.getName()))); } } // Value of the source side (input side) resource to call the update method. ResourceHierarchy srcRes2 = resourceNode.getResourceHierarchy(); if (generatesComponent(srcRes2)) { - params.add(new AbstractMap.SimpleEntry<>(srcRes2.getResourceStateType(), - new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes2.getResourceName()), - langSpec.getFieldAccessor(fieldOfResourceState)))); + params.add(new AbstractMap.SimpleEntry<>(srcRes2.getResourceStateType(), + new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes2.getResourceName()), + langSpec.getFieldAccessor(fieldOfResourceState)))); } else { params.add(new AbstractMap.SimpleEntry<>(srcRes2.getResourceStateType(), - new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes2.getResourceName()), - langSpec.getFieldAccessor(langSpec.toVariableName(srcRes2.getResourceName()))))); - srcRes2 = srcRes2.getParent(); + new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes2.getResourceName()), + langSpec.getFieldAccessor(langSpec.toVariableName(srcRes2.getResourceName()))))); + srcRes2 = srcRes2.getParent(); } params.addAll(refParams); // Call the update method. @@ -1992,10 +2036,10 @@ updateMethodName = updateMethodPrefix + getComponentName(dstRes, langSpec) + from + resComponentName; dstRes = dstRes.getParent(); } else { - updateMethodName = updateMethodPrefix + from + resComponentName; + updateMethodName = updateMethodPrefix + from + resComponentName; } String dstCompName = langSpec.toVariableName(getComponentName(dstRes, langSpec)); - if (outsideOutputResource2 + if (outsideOutputResource2 || (!platformSpec.isMonolithic() && in.getResource().getCommonPrefix(out1.getResource()) == null && platformSpec.isDifferentTreesAsDifferentServices())) { // Inter-servces if (!platformSpec.isMonolithic()) { @@ -2003,13 +2047,13 @@ RestApiSpecific restApiSpec = (RestApiSpecific) platformSpec; String httpMethod = null; if (out1.getStateTransition().isRightUnary()) { - httpMethod = "put"; + httpMethod = "put"; } else { httpMethod = "post"; } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; List pathParamsUrl = new ArrayList<>(); - for (Expression pathExp : out1.getResource().getPathParams()) { + for (Expression pathExp: out1.getResource().getPathParams()) { pathParamsUrl.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } String resName = langSpec.toVariableName(resComponentName); @@ -2020,14 +2064,14 @@ try { filledPaths = ch2.fillOutsideResourcePaths(out1, getPushAccessor(platformSpec)); } catch (ParameterizedIdentifierIsFutureWork - | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage - | UnificationFailed | ValueUndefined e) { + | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage + | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } String dstPath = null; if (filledPaths != null && filledPaths.get(out1) != null) { ResourcePath filledDstPath = filledPaths.get(out1).getKey(); - dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); } else { dstPath = dstRes.toResourcePath(pathParamsUrl); } @@ -2036,7 +2080,7 @@ // The first call to an update method in this method update.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes2.getResourceName(), params, true)); update.addStatement(langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") - + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, resName, httpMethod)); + + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, resName, httpMethod)); hasUpdateMethodinvoked = true; } else { // After the second time of call to update methods in this method @@ -2046,31 +2090,31 @@ } else { // Use the reference field to refer to outside destination resource. List args = new ArrayList<>(); - for (Map.Entry> paramEnt : pathParams) { + for (Map.Entry> paramEnt: pathParams) { args.add(paramEnt.getValue().getValue()); } - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } - update.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + update.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) + + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); } } else { // Intra-service // The destination resource is not outside. List args = new ArrayList<>(); - for (Map.Entry> paramEnt : pathParams) { + for (Map.Entry> paramEnt: pathParams) { args.add(paramEnt.getValue().getValue()); } - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } if (srcRes2 != dstRes) { - update.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + update.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) + + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); } else { update.addStatement(langSpec.getMethodInvocation(updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.updateDstFromSrc(value, refParams); + + langSpec.getStatementDelimiter()); // this.updateDstFromSrc(value, refParams); } } if (addForStatement) { @@ -2083,10 +2127,10 @@ if (!generatesComponent(resourceNode.getResourceHierarchy())) { // srcRes2 does not have a component. ResourcePath srcRes2 = resourceNode.getOutSideResource(directDstCh); - for (Edge chToRes2 : outEdges) { + for (Edge chToRes2: outEdges) { ChannelNode chNode2 = (ChannelNode) chToRes2.getSource(); DataTransferChannel ch2 = chNode2.getChannel(); - for (ChannelMember out2 : ch2.getOutputChannelMembers()) { + for (ChannelMember out2: ch2.getOutputChannelMembers()) { if (!generatesComponent(out2.getResource().getResourceHierarchy())) { // Also dstRes2 does not have a component. ResourcePath dstRes2 = out2.getResource(); @@ -2095,8 +2139,8 @@ try { resourcePaths = ch2.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember : outsideInputMembers2) { - for (ChannelMember dependedMember : resourcePaths.get(outsideMember).getValue()) { + 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(); @@ -2108,14 +2152,14 @@ if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } - String[] sideEffects = new String[]{""}; + 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.addStatement(updateReference); // Update the reference field. // Update constructor. if (component != null) { MethodDeclaration constructor = getConstructor(component); - constructor.addStatement(updateReference); // Initialize the reference field. + constructor.addStatement(updateReference); // Initialize the reference field. } else if (parentComponent != null) { constructorStatements.add(updateReference); } @@ -2123,9 +2167,8 @@ } } } - } catch (ParameterizedIdentifierIsFutureWork | - ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } } @@ -2142,21 +2185,21 @@ } private Map.Entry, Map>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, - TypeDeclaration parentComponent, TypeDeclaration mainComponent, TypeDeclaration rootComponent, DataTransferModel model, Map priorMemberForInputChannel, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + TypeDeclaration parentComponent, TypeDeclaration mainComponent, TypeDeclaration rootComponent, DataTransferModel model, Map priorMemberForInputChannel, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Declare input methods. String resName = resourceNode.getResourceName(); String resComponentName = langSpec.toComponentName(resName); List constructorStatements = new ArrayList<>(); Map>> inputStatements = new HashMap<>(); - for (Channel ch : model.getInputChannels()) { + for (Channel ch: model.getInputChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { if (!cm.isOutside()) { if (priorMemberForInputChannel.get(ch) == null) { - priorMemberForInputChannel.put(ch, cm); // The receiver of the input event when multiple output resources are defined for the channel. + priorMemberForInputChannel.put(ch, cm); // The receiver of the input event when multiple output resources are defined for the channel. } } } - for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) { + for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(out.getResource())) { Expression message = out.getStateTransition().getMessageExpression(); MethodDeclaration input = null; @@ -2169,7 +2212,7 @@ ArrayList rootInputParams = new ArrayList<>(); String resourcePath = null; if (!platformSpec.isMonolithic()) { - resourcePath = getInputMethodResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); // Path parameters for the input REST API. + resourcePath = getInputMethodResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); // Path parameters for the input REST API. if (resourcePath.indexOf('/') > 0) { resourcePath = resourcePath.substring(resourcePath.indexOf('/')); } else { @@ -2181,35 +2224,35 @@ // Channel parameters to specify the context of the collaboration. int v = 1; - for (Selector selector : ch.getSelectors()) { + for (Selector selector: ch.getSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); resInputParams.add(langSpec.newVariableDeclaration(selVar.getType(), selVar.getName())); mainInputParams.add(langSpec.newVariableDeclaration(selVar.getType(), selVar.getName())); } else if (selector.getExpression() instanceof Term) { Term var = (Term) selector.getExpression(); - resInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + resInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); } v++; } if (ch.getParent() != null) { - for (Selector selector : ch.getParent().getAllSelectors()) { + for (Selector selector: ch.getParent().getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); mainInputParams.add(langSpec.newVariableDeclaration(selVar.getType(), selVar.getName())); } else if (selector.getExpression() instanceof Term) { Term var = (Term) selector.getExpression(); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); } v++; } } // Message parameters to carry the data-flows. - for (Map.Entry varEnt : message.getVariables().entrySet()) { + for (Map.Entry varEnt: message.getVariables().entrySet()) { Variable var = varEnt.getValue(); String refVarName = null; - for (ChannelMember refCm : ((DataTransferChannel) ch).getReferenceChannelMembers()) { + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { Expression varExp = refCm.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); if (varExp != null && varExp instanceof Variable) { if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { @@ -2225,8 +2268,8 @@ // var has not come from a reference resource. resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); boolean bExists = false; - for (VariableDeclaration mainParam : mainInputParams) { - if (mainParam.getName().equals(var.getName())) { + for (VariableDeclaration mainParam: mainInputParams) { + if (mainParam.getName().equals(var.getName()) ) { bExists = true; break; } @@ -2234,7 +2277,7 @@ if (!bExists) { mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); } - if (!platformSpec.isMonolithic() && !resourcePath.contains("{" + var.getName() + "}")) { + if (!platformSpec.isMonolithic() && !resourcePath.contains("{" + var.getName()+ "}")) { VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), var.getName()); ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, var.getName()); rootInputParams.add(param); @@ -2249,7 +2292,7 @@ } if (component != null) { // A component is created for this resource. - for (MethodDeclaration method : component.getMethods()) { + for (MethodDeclaration method: component.getMethods()) { if (method.getName().equals(inputMethodName)) { input = method; break; @@ -2261,7 +2304,7 @@ } } else if (parentComponent != null) { // No component is created for this resource. - for (MethodDeclaration method : parentComponent.getMethods()) { + for (MethodDeclaration method: parentComponent.getMethods()) { if (method.getName().equals(inputMethodName)) { input = method; break; @@ -2284,9 +2327,9 @@ } else { // Add type to a parameter without type. if (mainInputAccessor.getParameters() != null) { - for (VariableDeclaration param : mainInputAccessor.getParameters()) { + for (VariableDeclaration param: mainInputAccessor.getParameters()) { if (param.getType() == null) { - for (VariableDeclaration p : mainInputParams) { + for (VariableDeclaration p: mainInputParams) { if (param.getName().equals(p.getName()) && p.getType() != null) { param.setType(p.getType()); } @@ -2304,7 +2347,7 @@ priorMemberForInputChannel.put(ch, out); String messageSymbol = ((Term) message).getSymbol().getImplName(); rootInputAccessor = declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, - rootComponent, platformSpec, langSpec); + rootComponent, platformSpec, langSpec); if (input == null) { input = rootInputAccessor; rootInputAccessor = null; @@ -2320,23 +2363,23 @@ Expression param = out.getResource().getLastParam(); if (param instanceof Variable) { Variable var = (Variable) param; - resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); } else if (param instanceof Term) { Term var = (Term) param; - resInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + resInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); } v++; } if (out.getResource().getParent() != null) { - for (Expression param : out.getResource().getParent().getPathParams()) { + for (Expression param: out.getResource().getParent().getPathParams()) { if (param instanceof Variable) { Variable var = (Variable) param; - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); } else if (param instanceof Term) { Term var = (Term) param; - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); } v++; } @@ -2349,7 +2392,7 @@ } if (component != null) { // A component is created for this resource. - for (MethodDeclaration method : component.getMethods()) { + for (MethodDeclaration method: component.getMethods()) { if (method.getName().equals(inputMethodName)) { input = method; break; @@ -2359,13 +2402,13 @@ if (resInputParams.size() == 0) { input = langSpec.newMethodDeclaration(inputMethodName, null); } else { - input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); } component.addMethod(input); } } else if (parentComponent != null) { // No component is created for this resource. - for (MethodDeclaration method : parentComponent.getMethods()) { + for (MethodDeclaration method: parentComponent.getMethods()) { if (method.getName().equals(inputMethodName)) { input = method; break; @@ -2375,13 +2418,13 @@ if (resInputParams.size() == 0) { input = langSpec.newMethodDeclaration(inputMethodName, null); } else { - input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); } parentComponent.addMethod(input); } } } - + // Declare the accessor in the main component to call the input method. (for monolithic application) if (platformSpec.hasMain()) { String messageSymbol = ((Variable) message).getName(); @@ -2410,7 +2453,7 @@ } String messageSymbol = ((Variable) message).getName(); rootInputAccessor = declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, - rootComponent, platformSpec, langSpec); + rootComponent, platformSpec, langSpec); if (input == null) { input = rootInputAccessor; rootInputAccessor = null; @@ -2423,17 +2466,17 @@ if (mainInputAccessor != null) { if (platformSpec.hasMain()) { // For an application with a main component, the reference resource is accessed from the main component. - for (ChannelMember rc : ((DataTransferChannel) ch).getReferenceChannelMembers()) { + for (ChannelMember rc: ((DataTransferChannel) ch).getReferenceChannelMembers()) { // For each reference channel member, get the current state of the reference resource by pull data transfer. ResourcePath ref = rc.getResource(); if (!out.getResource().equals(ref)) { String refVarName = ref.getLeafResourceName(); Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, null); - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); mainInputAccessor.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) - + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } } } @@ -2442,13 +2485,13 @@ if (resExp instanceof Term) { // to access the parent if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args.add(((Variable) ((Term) resExp).getChild(1)).getName()); + args.add(((Variable)((Term) resExp).getChild(1)).getName()); } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[]{""}); + String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); if (!args.contains(selVar.getName())) { @@ -2458,9 +2501,9 @@ } // Values of message parameters. if (message instanceof Term) { - for (Map.Entry varEnt : message.getVariables().entrySet()) { + for (Map.Entry varEnt: message.getVariables().entrySet()) { String refVarName = null; - for (ChannelMember rc : ((DataTransferChannel) ch).getReferenceChannelMembers()) { + for (ChannelMember rc: ((DataTransferChannel) ch).getReferenceChannelMembers()) { Expression varExp = rc.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); if (varExp != null && rc.getStateTransition().getCurStateExpression().contains(varExp)) { refVarName = rc.getResource().getLeafResourceName(); @@ -2472,8 +2515,7 @@ args.add(refVarName); } } else { - if (!args.contains(varEnt.getValue().getName())) - args.add(varEnt.getValue().getName()); + if (!args.contains(varEnt.getValue().getName())) args.add(varEnt.getValue().getName()); } } } @@ -2483,36 +2525,6 @@ if (input != null) { // Add a statement to update the state field to the input method. try { - if (!platformSpec.hasMain()) { - // For an application with no main component, the reference resource is accessed from each resource. - for (ChannelMember rc : ((DataTransferChannel) ch).getReferenceChannelMembers()) { - // For each reference channel member, get the current state of the reference side resource by pull data transfer. - ResourcePath ref = rc.getResource(); - if (!out.getResource().equals(ref)) { - String refResourceName = ref.getLeafResourceName(); - Type refResourceType = ref.getResourceStateType(); - String[] sideEffects = new String[]{""}; - if (!platformSpec.isMonolithic() && rc.isOutside()) { - List pathParams = new ArrayList<>(); - for (Expression pathExp : ref.getPathParams()) { - pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); - } - generatePullDataTransfer(input, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, true, platformSpec, langSpec); - } else { - ResourcePath dstRes = out.getResource(); - if (!generatesComponent(dstRes.getResourceHierarchy())) { - dstRes = dstRes.getParent(); - } - Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, dstRes); - String refExp = refGetter.toImplementation(sideEffects); - String refTypeName = refResourceType.getInterfaceTypeName(); - input.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refResourceName) - + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); - } - } - } - } - Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor(platformSpec)).getKey(); // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); @@ -2531,13 +2543,13 @@ } // Add statements to the input method. if (updateExp != null) { - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String newState = updateExp.toImplementation(sideEffects); ResourceHierarchy resource = resourceNode.getResourceHierarchy(); if (generatesComponent(resource)) { String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); } @@ -2548,7 +2560,7 @@ } else { String updateStatement = ""; if (sideEffects[0] != null) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; String resourceName = langSpec.toVariableName(getComponentName(resource, langSpec)); updateStatement = updateStatement.replace(langSpec.getFieldAccessor(fieldOfResourceState), langSpec.getFieldAccessor(resourceName)); if (updateStatement.endsWith("\n")) { @@ -2560,7 +2572,7 @@ selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); selector.addChild(new Variable(input.getParameters().get(input.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newList = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (DataConstraintModel.typeMap.isAncestorOf(resourceNode.getParent().getResourceStateType())) { @@ -2568,7 +2580,7 @@ selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); selector.addChild(new Variable(input.getParameters().get(input.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newMap = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { @@ -2580,6 +2592,37 @@ } } } + if (!platformSpec.hasMain()) { + // For an application with no main component, the reference resource is accessed from each resource. + for (ChannelMember rc: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + // For each reference channel member, get the current state of the reference side resource by pull data transfer. + ResourcePath ref = rc.getResource(); + if (!out.getResource().equals(ref)) { + String refResourceName = ref.getLeafResourceName(); + Type refResourceType = ref.getResourceStateType(); + String[] sideEffects = new String[] {""}; + ResourcePath dstRes = out.getResource(); + if (!generatesComponent(dstRes.getResourceHierarchy())) { + dstRes = dstRes.getParent(); + } + if (!platformSpec.isMonolithic() + && (rc.isOutside() || (ref.getCommonPrefix(dstRes) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { + List pathParams = new ArrayList<>(); + for (Expression pathExp: ref.getPathParams()) { + pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); + } + generatePullDataTransfer(input, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, true, platformSpec, langSpec); + } else { + Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, dstRes); + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = refResourceType.getInterfaceTypeName(); + input.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refResourceName) + + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + } + } + } + } + if (rootInputAccessor != null) { // In the root resource // The expression of the receiver (resource) of the input method. @@ -2593,13 +2636,13 @@ if (resExp instanceof Term) { // to access the parent if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args.add(((Variable) ((Term) resExp).getChild(1)).getName()); + args.add(((Variable)((Term) resExp).getChild(1)).getName()); } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[]{""}); + String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); args.add(selVar.getName()); @@ -2607,7 +2650,7 @@ } // Values of message parameters. if (message instanceof Term) { - for (Variable mesVar : message.getVariables().values()) { + for (Variable mesVar: message.getVariables().values()) { args.add(mesVar.getName()); } } @@ -2617,13 +2660,13 @@ } } } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } - + // Add an invocation to an update method (for a chain of update method invocations). boolean hasUpdateMethodinvoked = false; - for (Edge resToCh : resourceNode.getOutEdges()) { + for (Edge resToCh: resourceNode.getOutEdges()) { DataFlowEdge dOut = (DataFlowEdge) resToCh; ChannelNode directDstChNode = (ChannelNode) resToCh.getDestination(); DataTransferChannel directDstCh = directDstChNode.getChannel(); @@ -2631,10 +2674,10 @@ boolean outsideInputResource2 = false; ChannelMember in = null; Set outsideInputMembers2 = new HashSet<>(); - for (ChannelMember cm : directDstCh.getInputChannelMembers()) { + for (ChannelMember cm: directDstCh.getInputChannelMembers()) { if (resourceNode.getOutSideResources().contains(cm.getResource())) { if (cm.isOutside()) { - outsideInputResource2 = true; // Regarded as pull transfer. + outsideInputResource2 = true; // Regarded as pull transfer. } in = cm; } @@ -2647,13 +2690,13 @@ Set descendantDstChannels = directDstChNode.getDescendants(); Set outEdges = new HashSet<>(); outEdges.addAll(directDstChNode.getOutEdges()); - for (ChannelNode ancestorDst : ancestorDstChannels) { + for (ChannelNode ancestorDst: ancestorDstChannels) { outEdges.addAll(ancestorDst.getOutEdges()); } - for (ChannelNode descendantDst : descendantDstChannels) { + for (ChannelNode descendantDst: descendantDstChannels) { outEdges.addAll(descendantDst.getOutEdges()); } - for (Edge chToRes : outEdges) { + for (Edge chToRes: outEdges) { // For each data transfer to dstNode:ResourceNode. ResourceNode dstNode = ((ResourceNode) chToRes.getDestination()); ChannelNode chNode2 = (ChannelNode) chToRes.getSource(); @@ -2661,7 +2704,7 @@ // Check if the output resource is outside of the channel scope. boolean outsideOutputResource2 = false; ChannelMember out2 = null; - for (ChannelMember cm : ch2.getOutputChannelMembers()) { + for (ChannelMember cm: ch2.getOutputChannelMembers()) { if (dstNode.getInSideResources().contains(cm.getResource())) { out2 = cm; if (cm.isOutside()) { @@ -2672,10 +2715,10 @@ } // Also take into account the channel hierarchy to determine push/pull transfer. if (descendantDstChannels.contains(chNode2)) { - outsideOutputResource2 = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource2 = true; // Regarded as (broadcasting) push transfer. } if (ancestorDstChannels.contains(chNode2)) { - outsideInputResource2 = true; // Regarded as (collecting) pull transfer. + outsideInputResource2 = true; // Regarded as (collecting) pull transfer. } if ((((PushPullAttribute) dOut.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource2) || outsideOutputResource2) { // PUSH transfer @@ -2683,15 +2726,15 @@ // Calculate in-degree (PUSH transfer) of the destination resource. Set inEdges = new HashSet<>(); inEdges.addAll(directDstChNode.getInEdges()); - for (ChannelNode ancestorSrc : ancestorDstChannels) { + for (ChannelNode ancestorSrc: ancestorDstChannels) { inEdges.addAll(ancestorSrc.getInEdges()); } - for (ChannelNode descendantSrc : descendantDstChannels) { + for (ChannelNode descendantSrc: descendantDstChannels) { inEdges.addAll(descendantSrc.getInEdges()); } int inDegree = 0; - for (Edge resToCh2 : inEdges) { - DataFlowEdge df = (DataFlowEdge) resToCh2; + for (Edge resToCh2: inEdges) { + DataFlowEdge df =(DataFlowEdge) resToCh2; if (((PushPullAttribute) df.getAttribute()).getSelectedOption() == PushPullValue.PUSH) { inDegree++; } @@ -2707,14 +2750,14 @@ selType = ((Variable) selExp).getType(); forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm : ch2.getInputChannelMembers()) { + for (ChannelMember cm :ch2.getInputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; } } if (insideChMem == null) { - for (ChannelMember cm : ch2.getReferenceChannelMembers()) { + for (ChannelMember cm :ch2.getReferenceChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -2722,7 +2765,7 @@ } } if (insideChMem == null) { - for (ChannelMember cm : ch2.getOutputChannelMembers()) { + for (ChannelMember cm :ch2.getOutputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -2736,16 +2779,16 @@ insideResPath = insideResPath.getParent(); if (insideResPath != null) { String parent = null; - if (platformSpec.isMonolithic() - || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null + if (platformSpec.isMonolithic() + || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { Expression getter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[]{}); + parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {}); } } else { // for REST API @@ -2760,13 +2803,13 @@ input.addStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); addForStatement = true; } - if (!platformSpec.isMonolithic() - && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null + if (!platformSpec.isMonolithic() + && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null && platformSpec.isDifferentTreesAsDifferentServices()) { // for REST API Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); - String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(input, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); } } @@ -2777,9 +2820,9 @@ } // Get the value of reference member to call the update method. List>> refParams = new ArrayList<>(); - Map> referredResources = new HashMap<>(); + Map> referredResources = new HashMap<>(); Set referredSet = referredResources.get(input); - for (ChannelMember rc : ch2.getReferenceChannelMembers()) { + for (ChannelMember rc: ch2.getReferenceChannelMembers()) { ResourcePath ref = rc.getResource(); if (referredSet == null) { referredSet = new HashSet<>(); @@ -2794,24 +2837,24 @@ srcRes = srcRes.getParent(); } Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); input.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } refParams.add(new AbstractMap.SimpleEntry<>(ref.getResourceStateType(), - new AbstractMap.SimpleEntry<>(refVarName, - refVarName))); + new AbstractMap.SimpleEntry<>(refVarName, + refVarName))); } } - List>> pathParams = new ArrayList<>(); + List>> pathParams = new ArrayList<>(); if (platformSpec.isMonolithic()) { // Update fields to refer to outside resources. ResourcePath filledOutsideResourcePath = null; try { Map>> resourcePaths = ch2.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember : resourcePaths.keySet()) { + for (ChannelMember outsideMember: resourcePaths.keySet()) { ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); if (out2.equals(outsideMember)) { filledOutsideResourcePath = outsidePath; @@ -2827,71 +2870,70 @@ if (outsideExp instanceof Field) { outsideExp = new Variable(((Field) outsideExp).getSymbol().getName(), ((Field) outsideExp).getType()); } else if (outsideExp instanceof Term) { - for (Entry fieldEnt : ((Term) outsideExp).getSubTerms(Field.class).entrySet()) { + for (Entry fieldEnt: ((Term) outsideExp).getSubTerms(Field.class).entrySet()) { Position pos = fieldEnt.getKey(); Field field = fieldEnt.getValue(); Variable var = new Variable(field.getSymbol().getName(), field.getType()); ((Term) outsideExp).replaceSubTerm(pos, var); } } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - input.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + input.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. } } - } catch (ParameterizedIdentifierIsFutureWork | - ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } // Values of path parameters to call the update method. if (filledOutsideResourcePath == null) { filledOutsideResourcePath = out2.getResource(); } - for (Expression pathParam : filledOutsideResourcePath.getPathParams()) { + for (Expression pathParam: filledOutsideResourcePath.getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getName(), - pathVar.getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getName(), + pathVar.getName()))); } else if (pathParam instanceof Constant) { Constant pathVar = (Constant) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getSymbol().getName(), - pathVar.getSymbol().getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getSymbol().getName(), + pathVar.getSymbol().getName()))); } } } else { // Values of path parameters to call the update method. - for (Expression pathParam : out2.getResource().getPathParams()) { + for (Expression pathParam: out2.getResource().getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; pathParams.add(new AbstractMap.SimpleEntry<>(pathVar.getType(), - new AbstractMap.SimpleEntry<>(pathVar.getName(), - pathVar.getName()))); + new AbstractMap.SimpleEntry<>(pathVar.getName(), + pathVar.getName()))); } } } // Values of channel parameters to call the update method. List>> params = new ArrayList<>(); - for (Selector selector : ch2.getAllSelectors()) { + for (Selector selector: ch2.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); - params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), - new AbstractMap.SimpleEntry<>(selVar.getName(), - selVar.getName()))); + params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), + new AbstractMap.SimpleEntry<>(selVar.getName(), + selVar.getName()))); } } // Value of the source side (input side) resource to call the update method. ResourceHierarchy srcRes = resourceNode.getResourceHierarchy(); if (generatesComponent(srcRes)) { - params.add(new AbstractMap.SimpleEntry<>(srcRes.getResourceStateType(), - new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes.getResourceName()), - langSpec.getFieldAccessor(fieldOfResourceState)))); + params.add(new AbstractMap.SimpleEntry<>(srcRes.getResourceStateType(), + new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes.getResourceName()), + langSpec.getFieldAccessor(fieldOfResourceState)))); } else { params.add(new AbstractMap.SimpleEntry<>(srcRes.getResourceStateType(), - new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes.getResourceName()), - langSpec.getFieldAccessor(langSpec.toVariableName(srcRes.getResourceName()))))); + new AbstractMap.SimpleEntry<>(langSpec.toVariableName(srcRes.getResourceName()), + langSpec.getFieldAccessor(langSpec.toVariableName(srcRes.getResourceName()))))); srcRes = srcRes.getParent(); } params.addAll(refParams); @@ -2899,13 +2941,13 @@ String updateMethodName = null; ResourceHierarchy dstRes = dstNode.getResourceHierarchy(); if (!generatesComponent(dstRes)) { - updateMethodName = updateMethodPrefix + getComponentName(dstRes, langSpec) + from + resComponentName; + updateMethodName = updateMethodPrefix + getComponentName(dstRes, langSpec) + from + resComponentName; dstRes = dstRes.getParent(); } else { - updateMethodName = updateMethodPrefix + from + resComponentName; + updateMethodName = updateMethodPrefix + from + resComponentName; } String dstCompName = langSpec.toVariableName(getComponentName(dstRes, langSpec)); - if (outsideOutputResource2 + if (outsideOutputResource2 || (!platformSpec.isMonolithic() && in.getResource().getCommonPrefix(out2.getResource()) == null && platformSpec.isDifferentTreesAsDifferentServices())) { // Inter-servces if (!platformSpec.isMonolithic()) { @@ -2913,13 +2955,13 @@ RestApiSpecific restApiSpec = (RestApiSpecific) platformSpec; String httpMethod = null; if (out2.getStateTransition().isRightUnary()) { - httpMethod = "put"; + httpMethod = "put"; } else { httpMethod = "post"; } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; List pathParamsUrl = new ArrayList<>(); - for (Expression pathExp : out2.getResource().getPathParams()) { + for (Expression pathExp: out2.getResource().getPathParams()) { pathParamsUrl.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } String resName2 = langSpec.toVariableName(resComponentName); @@ -2930,14 +2972,14 @@ try { filledPaths = ch2.fillOutsideResourcePaths(out2, getPushAccessor(platformSpec)); } catch (ParameterizedIdentifierIsFutureWork - | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage - | UnificationFailed | ValueUndefined e) { + | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage + | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } String dstPath = null; if (filledPaths != null && filledPaths.get(out2) != null) { ResourcePath filledDstPath = filledPaths.get(out2).getKey(); - dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); } else { dstPath = dstRes.toResourcePath(pathParamsUrl); } @@ -2946,7 +2988,7 @@ // The first call to an update method in this method input.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, true)); input.addStatement(langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") - + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, resName2, httpMethod)); + + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, resName2, httpMethod)); hasUpdateMethodinvoked = true; if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. @@ -2960,31 +3002,31 @@ } else { // Use the reference field to refer to outside destination resource. List args = new ArrayList<>(); - for (Map.Entry> paramEnt : pathParams) { + for (Map.Entry> paramEnt: pathParams) { args.add(paramEnt.getValue().getValue()); } - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } input.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); } } else { // Intra-service // The destination resource is not outside. List args = new ArrayList<>(); - for (Map.Entry> paramEnt : pathParams) { + for (Map.Entry> paramEnt: pathParams) { args.add(paramEnt.getValue().getValue()); } - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } if (srcRes != dstRes) { input.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); } else { input.addStatement(langSpec.getMethodInvocation(updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.updateDstFromSrc(value, refParams); + + langSpec.getStatementDelimiter()); // this.updateDstFromSrc(value, refParams); } } if (addForStatement) { @@ -3000,7 +3042,7 @@ if (outsideInputMembers2.size() > 0) { if (!generatesComponent(resourceNode.getResourceHierarchy())) { ResourcePath srcRes2 = resourceNode.getOutSideResource(directDstCh); - for (ChannelMember out2 : directDstCh.getOutputChannelMembers()) { + for (ChannelMember out2: directDstCh.getOutputChannelMembers()) { if (!generatesComponent(out2.getResource().getResourceHierarchy())) { ResourcePath dstRes2 = out2.getResource(); if (srcRes2.getParent().equals(dstRes2.getParent())) { @@ -3008,8 +3050,8 @@ try { resourcePaths = directDstCh.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { - for (ChannelMember outsideMember : outsideInputMembers2) { - for (ChannelMember dependedMember : resourcePaths.get(outsideMember).getValue()) { + 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(); @@ -3021,24 +3063,23 @@ if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - input.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + 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. + constructor.addStatement(initializingStatement); // initialize the reference field. } else { - constructorStatements.add(initializingStatement); // initialize the reference field. + constructorStatements.add(initializingStatement); // initialize the reference field. } } } } } - } catch (ParameterizedIdentifierIsFutureWork | - ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); } } @@ -3054,9 +3095,9 @@ } return new AbstractMap.SimpleEntry<>(constructorStatements, inputStatements); } - - protected void declareGetterAccessorInTheRootResource(ResourceNode resourceNode, TypeDeclaration rootComponent, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + + protected void declareGetterAccessorInTheRootResource(ResourceNode resourceNode, TypeDeclaration rootComponent, + IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { if (resourceNode.getResourceHierarchy().getParent() != null) { // For a non-root resource MethodDeclaration getterAccessor = null; @@ -3069,12 +3110,12 @@ } if (mainGetterParams.size() > 0) { getterAccessor = langSpec.newMethodDeclaration(getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + methoNameOfResourceState, - false, - getImplStateType(resourceNode.getResourceHierarchy(), langSpec), - mainGetterParams); + false, + getImplStateType(resourceNode.getResourceHierarchy(), langSpec), + mainGetterParams); } else { getterAccessor = langSpec.newMethodDeclaration(getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + methoNameOfResourceState, - getImplStateType(resourceNode.getResourceHierarchy(), langSpec)); + getImplStateType(resourceNode.getResourceHierarchy(), langSpec)); } getterAccessor.setBody(new Block()); ResourcePath resPath = new ResourcePath(resourceNode.getPrimaryResourcePath()); @@ -3083,7 +3124,7 @@ resPath.replacePathParam(i, pathParam, null); } Expression getState = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); - getterAccessor.getBody().addStatement(langSpec.getReturnStatement(getState.toImplementation(new String[]{null})) + langSpec.getStatementDelimiter()); + getterAccessor.getBody().addStatement(langSpec.getReturnStatement(getState.toImplementation(new String[] {null})) + langSpec.getStatementDelimiter()); if (!platformSpec.isMonolithic()) { ((RestApiSpecific) platformSpec).addGetAnnotations(getterAccessor); if (resourcePath.length() > 0) { @@ -3093,35 +3134,35 @@ rootComponent.addMethod(getterAccessor); } } - + protected void declareUpdateAccessorInTheRootResource(ResourceNode resourceNode, String updateMethodName, - DataTransferChannel ch, ChannelMember cm, ResourcePath srcResPath, ResourcePath dstResPath, TypeDeclaration rootComponent, - int inDegree, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + DataTransferChannel ch, ChannelMember cm, ResourcePath srcResPath, ResourcePath dstResPath, TypeDeclaration rootComponent, + int inDegree, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { ArrayList parameters; VariableDeclaration param; parameters = new ArrayList<>(); - String resourcePath = getUpdateResourcePathAndPathParams(dstResPath, parameters, true, platformSpec, langSpec); // Path parameters to identify the self resource. + String resourcePath = getUpdateResourcePathAndPathParams(dstResPath, parameters, true, platformSpec, langSpec); // Path parameters to identify the self resource. ResourcePath resPath = new ResourcePath(dstResPath); for (int i = 0; i < parameters.size(); i++) { Parameter pathParam = new Parameter(parameters.get(i).getName()); resPath.replacePathParam(i, pathParam, null); } - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); VariableDeclaration chParam = langSpec.newVariableDeclaration(selVar.getType(), selVar.getName()); if (!platformSpec.isMonolithic()) { ((RestApiSpecific) platformSpec).addFormParamAnnotation(chParam, selVar.getName()); } - parameters.add(chParam); // A channel parameter to specify the context of the collaboration. + parameters.add(chParam); // A channel parameter to specify the context of the collaboration. } } Type srcType = srcResPath.getResourceStateType(); String srcResName = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); param = langSpec.newVariableDeclaration(srcType, srcResName); if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, srcResName); - parameters.add(param); // The state of the source resource to carry the data-flow. - for (ResourcePath refRes : ch.getReferenceResources()) { + parameters.add(param); // The state of the source resource to carry the data-flow. + for (ResourcePath refRes: ch.getReferenceResources()) { if (!refRes.equals(resourceNode.getInSideResource(ch))) { String refName = langSpec.toVariableName(getComponentName(refRes.getResourceHierarchy(), langSpec)); param = langSpec.newVariableDeclaration(refRes.getResourceStateType(), refName); @@ -3144,11 +3185,10 @@ } } if (inDegree > 1) { - // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. + // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. resourcePath += "/" + langSpec.toVariableName(srcResName); } - if (!platformSpec.isMonolithic()) - ((RestApiSpecific) platformSpec).addPathAnnotation(updateAccessor, resourcePath); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathAnnotation(updateAccessor, resourcePath); // To make the accessor call the update method. Expression resExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); @@ -3156,21 +3196,21 @@ if (resExp instanceof Term) { // to access the parent if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args.add(((Variable) ((Term) resExp).getChild(1)).getName()); + args.add(((Variable)((Term) resExp).getChild(1)).getName()); } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[]{""}); - for (VariableDeclaration var : updateAccessor.getParameters()) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + for (VariableDeclaration var: updateAccessor.getParameters()) { args.add(var.getName()); } updateAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, updateMethodName, args) + langSpec.getStatementDelimiter()); rootComponent.addMethod(updateAccessor); } - + protected MethodDeclaration declareInputAccessorInTheRootResource(String inputMethodName, - ArrayList rootInputParams, ChannelMember cm, String resourcePath, - TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + ArrayList rootInputParams, ChannelMember cm, String resourcePath, + TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { MethodDeclaration rootInputAccessor; rootInputAccessor = langSpec.newMethodDeclaration(inputMethodName, false, null, rootInputParams); if (!platformSpec.isMonolithic()) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index f2691ff..fdfd502 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -1,27 +1,65 @@ package generators; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.Stack; + import algorithms.TypeInference; +import code.ast.CodeUtil; import code.ast.CompilationUnit; import code.ast.MethodDeclaration; import code.ast.TypeDeclaration; import code.ast.VariableDeclaration; import models.Edge; -import models.algebra.*; -import models.dataConstraintModel.*; -import models.dataFlowModel.*; +import models.Node; +import models.algebra.Constant; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.InvalidMessage; +import models.algebra.Parameter; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Position; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.algebra.Variable; +import models.dataConstraintModel.Channel; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; +import models.dataConstraintModel.ResourceHierarchy; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.Selector; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ChannelNode; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; -import java.util.*; -import java.util.Map.Entry; - public class JerseyMethodBodyGenerator { private static String baseURL = "http://localhost:8080"; - + public static ArrayList doGenerate(DataFlowGraph graph, DataTransferModel model, ArrayList codes) { // Create a map from type names (lower case) to their types. Map componentMap = new HashMap<>(); - for (CompilationUnit code : codes) { - for (TypeDeclaration component : code.types()) { + for (CompilationUnit code: codes) { + for (TypeDeclaration component: code.types()) { componentMap.put(component.getTypeName(), component); } } @@ -29,8 +67,8 @@ // Generate the body of each update or getter method. try { Set chainedCalls = new HashSet<>(); - Map> referredResources = new HashMap<>(); - for (Edge e : graph.getEdges()) { + Map> referredResources = new HashMap<>(); + for (Edge e: graph.getEdges()) { DataFlowEdge resToCh = (DataFlowEdge) e; if (!resToCh.isChannelToResource()) { PushPullAttribute pushPull = (PushPullAttribute) resToCh.getAttribute(); @@ -42,13 +80,13 @@ Set descendantDstChannels = directDstChNode.getDescendants(); Set outEdges = new HashSet<>(); outEdges.addAll(directDstChNode.getOutEdges()); - for (ChannelNode ancestorDst : ancestorDstChannels) { + for (ChannelNode ancestorDst: ancestorDstChannels) { outEdges.addAll(ancestorDst.getOutEdges()); } - for (ChannelNode descendantDst : descendantDstChannels) { + for (ChannelNode descendantDst: descendantDstChannels) { outEdges.addAll(descendantDst.getOutEdges()); } - for (Edge chToRes : outEdges) { + for (Edge chToRes: outEdges) { // For each data transfer from src:ResourceNode to dst:ResourceNode. ResourceNode dst = (ResourceNode) chToRes.getDestination(); String srcResourceName = JerseyCodeGenerator.getComponentName(src.getResourceHierarchy()); @@ -58,16 +96,16 @@ // DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); ChannelNode chNode = (ChannelNode) chToRes.getSource(); DataTransferChannel ch = chNode.getChannel(); - for (ChannelMember out : ch.getOutputChannelMembers()) { + for (ChannelMember out: ch.getOutputChannelMembers()) { if (dst.getInSideResources().contains(out.getResource())) { // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; ChannelMember in = null; - for (ChannelMember cm : directDstCh.getInputChannelMembers()) { + for (ChannelMember cm: directDstCh.getInputChannelMembers()) { if (src.getOutSideResources().contains(cm.getResource())) { in = cm; if (cm.isOutside()) { - outsideInputResource = true; // Regarded as pull transfer. + outsideInputResource = true; // Regarded as pull transfer. break; } } @@ -76,10 +114,10 @@ boolean outsideOutputResource = out.isOutside(); // Also take into account the channel hierarchy to determine push/pull transfer. if (descendantDstChannels.contains(chNode)) { - outsideOutputResource = true; // Regarded as (broadcasting) push transfer. + outsideOutputResource = true; // Regarded as (broadcasting) push transfer. } if (ancestorDstChannels.contains(chNode)) { - outsideInputResource = true; // Regarded as (collecting) pull transfer. + outsideInputResource = true; // Regarded as (collecting) pull transfer. } if ((pushPull.getSelectedOption() == PushPullValue.PUSH && !outsideInputResource) || outsideOutputResource) { // for push data transfer @@ -109,10 +147,10 @@ } else { // if there exists one or more reference channel member. HashMap inputResourceToStateAccessor = new HashMap<>(); - for (ChannelMember c : ch.getInputChannelMembers()) { + for (ChannelMember c: ch.getInputChannelMembers()) { inputResourceToStateAccessor.put(c, JerseyCodeGenerator.pushAccessor); } - for (ChannelMember c : ch.getReferenceChannelMembers()) { + for (ChannelMember c: ch.getReferenceChannelMembers()) { inputResourceToStateAccessor.put(c, JerseyCodeGenerator.refAccessor); } Term message = ch.fillOutsideResourcePaths(out, JerseyCodeGenerator.pushAccessor, inputResourceToStateAccessor).getValue(); @@ -143,7 +181,7 @@ Type fieldType = JerseyCodeGenerator.getImplStateType(outRes); if (updateExp instanceof Term) { ((Term) updateExp).setType(fieldType); - for (Map.Entry varEnt : ((Term) updateExp).getVariables().entrySet()) { + for (Map.Entry varEnt: ((Term) updateExp).getVariables().entrySet()) { if (varEnt.getValue().getName().equals("value")) { varEnt.getValue().setType(fieldType); } @@ -152,10 +190,10 @@ ((Variable) updateExp).setType(fieldType); } // Add statements to the update method. - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String newState = updateExp.toImplementation(sideEffects); int numOfOutResourcesWithTheSameHierarchy = 0; - for (ResourcePath outResPath : ch.getOutputResources()) { + for (ResourcePath outResPath: ch.getOutputResources()) { if (outResPath.getResourceHierarchy().equals(outRes)) { numOfOutResourcesWithTheSameHierarchy++; } @@ -163,7 +201,7 @@ String updateStatement = ""; if (JerseyCodeGenerator.generatesComponent(outRes)) { if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); } @@ -172,7 +210,7 @@ } } else { if (sideEffects[0] != null) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(outRes))); if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); @@ -183,7 +221,7 @@ selector.addChild(new Field("value")); selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newList = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (DataConstraintModel.typeMap.isAncestorOf(outRes.getParent().getResourceStateType())) { @@ -191,7 +229,7 @@ selector.addChild(new Field("value")); selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newMap = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { @@ -205,11 +243,11 @@ Term conditions = null; int v = 1; Map>> resourcePaths = ch.fillOutsideResourcePaths(out, JerseyCodeGenerator.pushAccessor); - for (Expression pathParam : out.getResource().getPathParams()) { + for (Expression pathParam: out.getResource().getPathParams()) { if (pathParam instanceof Variable) { String selfParamName = ((Variable) pathParam).getName(); Expression arg = null; - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); if (selVar.getName().equals(selfParamName)) { @@ -222,20 +260,20 @@ ResourcePath filledPath = resourcePaths.get(out).getKey(); arg = filledPath.getPathParams().get(v - 1); } - Term condition = new Term(DataConstraintModel.eq, new Expression[]{ - new Parameter("self" + (v > 1 ? v : ""), DataConstraintModel.typeString), + Term condition = new Term(DataConstraintModel.eq, new Expression[] { + new Parameter("self" + (v > 1 ? v : ""), DataConstraintModel.typeString), arg}); if (conditions == null) { conditions = condition; } else { - conditions = new Term(DataConstraintModel.and, new Expression[]{ - conditions, + conditions = new Term(DataConstraintModel.and, new Expression[] { + conditions, condition}); } } v++; } - String ifStatement = "if (" + conditions.toImplementation(new String[]{""}) + ") {\n"; + String ifStatement = "if (" + conditions.toImplementation(new String[] {""})+ ") {\n"; update.addFirstStatement(ifStatement + "\t" + updateStatement.replace("\n", "\n\t") + "\n}"); } } @@ -243,19 +281,19 @@ int inDegree = 0; Set inEdges = new HashSet<>(); inEdges.addAll(chNode.getInEdges()); - for (ChannelNode ancestor : chNode.getAncestors()) { + for (ChannelNode ancestor: chNode.getAncestors()) { inEdges.addAll(ancestor.getInEdges()); } - for (ChannelNode descendant : chNode.getDescendants()) { + for (ChannelNode descendant: chNode.getDescendants()) { inEdges.addAll(descendant.getInEdges()); } - for (Edge resToCh2 : inEdges) { - DataFlowEdge df = (DataFlowEdge) resToCh2; + for (Edge resToCh2: inEdges) { + DataFlowEdge df =(DataFlowEdge) resToCh2; if (((PushPullAttribute) df.getAttribute()).getSelectedOption() == PushPullValue.PUSH) { inDegree++; } } - if (inDegree > 1 + if (inDegree > 1 || (inDegree == 1 && directDstCh.getInputChannelMembers().iterator().next().getStateTransition().isRightPartial())) { // update a cache of src side resource (when incoming edges are multiple) String cacheStatement = "this." + JerseyCodeGenerator.toVariableName(srcResourceName) + " = " + JerseyCodeGenerator.toVariableName(srcResourceName) + ";"; @@ -264,14 +302,14 @@ } } // For a post/put REST API. - if (outsideOutputResource + if (outsideOutputResource || (in.getResource().getCommonPrefix(out.getResource()) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { // Inter-services if (dst.getResourceHierarchy().getParent() != null) { // If not a root resource. TypeDeclaration rootComponent = componentMap.get(JerseyCodeGenerator.getComponentName(dst.getResourceHierarchy().getRoot())); MethodDeclaration update2 = update; - update = getMethod(rootComponent, update2.getName()); // get the accessor to the update method. + update = getMethod(rootComponent, update2.getName()); // get the accessor to the update method. // To make the accessor call the update method. ResourcePath outResPath = new ResourcePath(out.getResource()); for (int i = 0; i < outResPath.getPathParams().size(); i++) { @@ -284,14 +322,14 @@ if (resExp instanceof Term) { // to access the parent if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args += delimiter + ((Variable) ((Term) resExp).getChild(1)).getName(); + args += delimiter + ((Variable)((Term) resExp).getChild(1)).getName(); delimiter = ", "; } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[]{""}); + String resourceAccess = resExp.toImplementation(new String[] {""}); int v = 0; - for (VariableDeclaration var : update2.getParameters()) { + for (VariableDeclaration var: update2.getParameters()) { if (v < out.getResource().getPathParams().size()) { if (out.getResource().getPathParams().get(v) instanceof Variable) { args += delimiter + ((Variable) out.getResource().getPathParams().get(v)).getName(); @@ -307,7 +345,7 @@ update.addStatement(resourceAccess + "." + update2.getName() + "(" + args + ");"); } // to convert a json param to a tuple, pair or map object. - for (VariableDeclaration param : update.getParameters()) { + for (VariableDeclaration param: update.getParameters()) { Type paramType = param.getType(); String paramName = param.getName(); String paramConverter = ""; @@ -392,7 +430,7 @@ getter.addStatement("return " + dstResName + ";"); } } else { - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; if (DataConstraintModel.typeList.isAncestorOf(dst.getParent().getResourceStateType())) { Term selector = new Term(DataConstraintModel.get); selector.addChild(new Field("value")); @@ -412,7 +450,7 @@ // src side (for a chain of update method invocations) String httpMethod = null; if (out.getStateTransition().isRightUnary()) { - httpMethod = "put"; + httpMethod = "put"; } else { httpMethod = "post"; } @@ -423,16 +461,16 @@ srcName = srcResourceName; } // For caller update methods - for (MethodDeclaration srcUpdate : getUpdateMethods(srcComponent, srcName)) { + for (MethodDeclaration srcUpdate: getUpdateMethods(srcComponent, srcName)) { if (srcUpdate != null) { List>> params = new ArrayList<>(); ResourcePath dstRes = out.getResource(); // Values of channel parameters. - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); - params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), - new AbstractMap.SimpleEntry<>(selVar.getName(), selVar.getName()))); + params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), + new AbstractMap.SimpleEntry<>(selVar.getName(), selVar.getName()))); } } // Value of the source side (input side) resource. @@ -440,12 +478,12 @@ if (!JerseyCodeGenerator.generatesComponent(src.getResourceHierarchy())) { srcFieldName = JerseyCodeGenerator.toVariableName(srcResourceName); } - params.add(new AbstractMap.SimpleEntry<>(src.getResourceStateType(), - new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), srcFieldName))); + params.add(new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), srcFieldName))); // Get the value of reference member to call the update method. Set referredSet = referredResources.get(srcUpdate); if (ch.getReferenceChannelMembers().size() > 0) { - for (ChannelMember rc : ch.getReferenceChannelMembers()) { + for (ChannelMember rc: ch.getReferenceChannelMembers()) { // For each reference channel member, get the current state of the reference side resource by pull data transfer. ResourcePath ref = rc.getResource(); if (referredSet == null) { @@ -457,18 +495,18 @@ Type refResourceType = ref.getResourceStateType(); if (!referredSet.contains(ref)) { referredSet.add(ref); - String[] sideEffects = new String[]{""}; - if (rc.isOutside()) { + String[] sideEffects = new String[] {""}; + ResourcePath srcRes = in.getResource(); + if (!JerseyCodeGenerator.generatesComponent(srcRes.getResourceHierarchy())) { + srcRes = srcRes.getParent(); + } + if (rc.isOutside() || (ref.getCommonPrefix(srcRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { List pathParams = new ArrayList<>(); - for (Expression pathExp : ref.getPathParams()) { + for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); - } + } generatePullDataTransfer(srcUpdate, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType); } else { - ResourcePath srcRes = in.getResource(); - if (!JerseyCodeGenerator.generatesComponent(srcRes.getResourceHierarchy())) { - srcRes = srcRes.getParent(); - } Expression refGetter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(ref, srcRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); @@ -482,9 +520,9 @@ } if (outsideOutputResource || (in.getResource().getCommonPrefix(dstRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { // Inter-servces - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; List pathParams = new ArrayList<>(); - for (Expression pathExp : dstRes.getPathParams()) { + for (Expression pathExp: dstRes.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } String srcResName = JerseyCodeGenerator.toVariableName(srcResourceName); @@ -495,7 +533,7 @@ String dstPath = null; if (filledPaths != null && filledPaths.get(out) != null) { ResourcePath filledDstPath = filledPaths.get(out).getKey(); - dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); } else { dstPath = dstRes.getResourceHierarchy().toResourcePath(pathParams); } @@ -520,14 +558,14 @@ selType = ((Variable) selExp).getType(); varName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm :ch.getInputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; } } if (insideChMem == null) { - for (ChannelMember cm : ch.getReferenceChannelMembers()) { + for (ChannelMember cm :ch.getReferenceChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -535,7 +573,7 @@ } } if (insideChMem == null) { - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm :ch.getOutputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -552,14 +590,14 @@ Expression getter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()); Term valueGetter = new Term(new Symbol("getValue", 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()).toImplementation(new String[]{}); + parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()).toImplementation(new String[] {}); } if (insideResPath != null) { if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for broadcasting. - srcUpdate.addFirstStatement("for (int " + varName + " = 0; " + varName + " < " + parent + ".size(); " + varName + "++) {"); + srcUpdate.addFirstStatement("for (int " + varName + " = 0; " + varName +" < " + parent + ".size(); " + varName + "++) {"); srcUpdate.addStatement("}"); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for broadcasting. @@ -584,7 +622,7 @@ String callParams = ""; String delimiter = ""; // Values of path parameters. - for (Expression pathParam : dstRes.getPathParams()) { + for (Expression pathParam: dstRes.getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; callParams += delimiter + pathVar.getName(); @@ -592,15 +630,15 @@ } } // Values of other parameters. - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { callParams += delimiter + paramEnt.getValue().getValue(); delimiter = ", "; } // Call the update method. if (srcComponent != dstComponent) { - srcUpdate.addStatement("this." + JerseyCodeGenerator.toVariableName(dstResourceName) + "." + updateMethodName + "(" + callParams + ");"); + srcUpdate.addStatement("this." + JerseyCodeGenerator.toVariableName(dstResourceName) + "." + updateMethodName + "(" + callParams + ");"); } else { - srcUpdate.addStatement("this." + updateMethodName + "(" + callParams + ");"); + srcUpdate.addStatement("this." + updateMethodName + "(" + callParams + ");"); } if (update != null && update.getThrows() != null && update.getThrows().getExceptions().contains("JsonProcessingException")) { srcUpdate.addThrow("JsonProcessingException"); @@ -609,15 +647,15 @@ } } // For caller input methods - for (MethodDeclaration srcInput : getInputMethods(srcComponent, src, model)) { + for (MethodDeclaration srcInput: getInputMethods(srcComponent, src, model)) { List>> params = new ArrayList<>(); ResourcePath dstRes = out.getResource(); // Values of channel parameters. - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); - params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), - new AbstractMap.SimpleEntry<>(selVar.getName(), selVar.getName()))); + params.add(new AbstractMap.SimpleEntry<>(selVar.getType(), + new AbstractMap.SimpleEntry<>(selVar.getName(), selVar.getName()))); } } // Value of the source side (input side) resource. @@ -625,11 +663,11 @@ if (!JerseyCodeGenerator.generatesComponent(src.getResourceHierarchy())) { srcFieldName = JerseyCodeGenerator.toVariableName(srcResourceName); } - params.add(new AbstractMap.SimpleEntry<>(src.getResourceStateType(), - new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), srcFieldName))); + params.add(new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), srcFieldName))); // Get the value of reference member to call the update method. Set referredSet = referredResources.get(srcInput); - for (ChannelMember rc : ch.getReferenceChannelMembers()) { + for (ChannelMember rc: ch.getReferenceChannelMembers()) { // For each reference channel member, get the current state of the reference side resource by pull data transfer. ResourcePath ref = rc.getResource(); if (referredSet == null) { @@ -641,18 +679,18 @@ Type refResourceType = ref.getResourceStateType(); if (!referredSet.contains(ref)) { referredSet.add(ref); - String[] sideEffects = new String[]{""}; - if (rc.isOutside()) { + String[] sideEffects = new String[] {""}; + ResourcePath srcRes = in.getResource(); + if (!JerseyCodeGenerator.generatesComponent(srcRes.getResourceHierarchy())) { + srcRes = srcRes.getParent(); + } + if (rc.isOutside() || (ref.getCommonPrefix(srcRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { List pathParams = new ArrayList<>(); - for (Expression pathExp : ref.getPathParams()) { + for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); - } + } generatePullDataTransfer(srcInput, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType); } else { - ResourcePath srcRes = in.getResource(); - if (!JerseyCodeGenerator.generatesComponent(srcRes.getResourceHierarchy())) { - srcRes = srcRes.getParent(); - } Expression refGetter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(ref, srcRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); @@ -661,13 +699,13 @@ } // Value of a reference side resource. params.add(new AbstractMap.SimpleEntry<>(refResourceType, new AbstractMap.SimpleEntry<>(refResourceName, refResourceName))); - } + } } if (outsideOutputResource || (in.getResource().getCommonPrefix(dstRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { // Inter-services - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; List pathParams = new ArrayList<>(); - for (Expression pathExp : dstRes.getPathParams()) { + for (Expression pathExp: dstRes.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } String srcResName = JerseyCodeGenerator.toVariableName(srcResourceName); @@ -678,7 +716,7 @@ String dstPath = null; if (filledPaths != null && filledPaths.get(out) != null) { ResourcePath filledDstPath = filledPaths.get(out).getKey(); - dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + dstPath = filledDstPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); } else { dstPath = dstRes.getResourceHierarchy().toResourcePath(pathParams); } @@ -703,14 +741,14 @@ selType = ((Variable) selExp).getType(); forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm : ch.getInputChannelMembers()) { + for (ChannelMember cm :ch.getInputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; } } if (insideChMem == null) { - for (ChannelMember cm : ch.getReferenceChannelMembers()) { + for (ChannelMember cm :ch.getReferenceChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -718,7 +756,7 @@ } } if (insideChMem == null) { - for (ChannelMember cm : ch.getOutputChannelMembers()) { + for (ChannelMember cm :ch.getOutputChannelMembers()) { if (!cm.isOutside()) { insideChMem = cm; break; @@ -735,14 +773,14 @@ Expression getter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()); Term valueGetter = new Term(new Symbol("getValue", 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()).toImplementation(new String[]{}); + parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, src.getPrimaryResourcePath()).toImplementation(new String[] {}); } if (insideResPath != null) { if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for broadcasting. - srcInput.addFirstStatement("for (int " + forVarName + " = 0; " + forVarName + " < " + parent + ".size(); " + forVarName + "++) {"); + srcInput.addFirstStatement("for (int " + forVarName + " = 0; " + forVarName +" < " + parent + ".size(); " + forVarName + "++) {"); srcInput.addStatement("}"); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for broadcasting. @@ -767,7 +805,7 @@ String callParams = ""; String delimiter = ""; // Values of path parameters. - for (Expression pathParam : dstRes.getPathParams()) { + for (Expression pathParam: dstRes.getPathParams()) { if (pathParam instanceof Variable) { Variable pathVar = (Variable) pathParam; callParams += delimiter + pathVar.getName(); @@ -775,15 +813,15 @@ } } // Values of other parameters. - for (Map.Entry> paramEnt : params) { + for (Map.Entry> paramEnt: params) { callParams += delimiter + paramEnt.getValue().getValue(); delimiter = ", "; } // Call the update method. if (srcComponent != dstComponent) { - srcInput.addStatement("this." + JerseyCodeGenerator.toVariableName(dstResourceName) + "." + updateMethodName + "(" + callParams + ");"); + srcInput.addStatement("this." + JerseyCodeGenerator.toVariableName(dstResourceName) + "." + updateMethodName + "(" + callParams + ");"); } else { - srcInput.addStatement("this." + updateMethodName + "(" + callParams + ");"); + srcInput.addStatement("this." + updateMethodName + "(" + callParams + ");"); } if (update != null && update.getThrows() != null && update.getThrows().getExceptions().contains("JsonProcessingException")) { srcInput.addThrow("JsonProcessingException"); @@ -806,26 +844,26 @@ // The first time to fill the getter method's body. // Data transfer on the same channel hierarchy. - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; // For each reference channel member, get the current state of the reference side resource by pull data transfer. - for (ChannelMember rc : ch.getReferenceChannelMembers()) { + for (ChannelMember rc: ch.getReferenceChannelMembers()) { ResourcePath refRes = rc.getResource(); String refResourceName = JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(refRes.getResourceHierarchy())); Type refResourceType = refRes.getResourceStateType(); - if (rc.isOutside()) { + ResourcePath dstRes = out.getResource(); + if (!JerseyCodeGenerator.generatesComponent(dstRes.getResourceHierarchy())) { + dstRes = dstRes.getParent(); + } + if (rc.isOutside() || (refRes.getCommonPrefix(dstRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { List pathParams = new ArrayList<>(); - for (Expression pathExp : refRes.getPathParams()) { - sideEffects = new String[]{""}; + for (Expression pathExp: refRes.getPathParams()) { + sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } generatePullDataTransfer(getter, refResourceName, refRes.getResourceHierarchy().toResourcePath(pathParams), refResourceType); } else { - ResourcePath dstRes = out.getResource(); - if (!JerseyCodeGenerator.generatesComponent(dstRes.getResourceHierarchy())) { - dstRes = dstRes.getParent(); - } Expression refGetter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(refRes, dstRes); - sideEffects = new String[]{""}; + sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = refResourceType.getInterfaceTypeName(); getter.addFirstStatement(sideEffects[0] + refTypeName + " " + refResourceName + " = " + refExp + ";"); @@ -838,15 +876,15 @@ Term messageTerm = resourcePathsAndMessage.getValue(); // Data transfer from path depending resource. - for (Entry>> pathEnt : resourcePaths.entrySet()) { + for (Entry>> pathEnt: resourcePaths.entrySet()) { ChannelMember cm = pathEnt.getKey(); ResourcePath src2 = pathEnt.getValue().getKey(); // get outside src2 resource state by pull data transfer. if (cm.isOutside() || src2.getCommonPrefix(dst.getInSideResource(ch)) == null) { // Data transfer from an outside input resource is regarded as PULL transfer. List pathParams = new ArrayList<>(); - for (Expression pathExp : src2.getPathParams()) { - sideEffects = new String[]{""}; + for (Expression pathExp: src2.getPathParams()) { + sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } // generate a pull data transfer from a depending in/ref resource. @@ -872,13 +910,13 @@ // generate pull data transfers. Set chMems = new HashSet<>(curChannel.getInputChannelMembers()); chMems.addAll(curChannel.getReferenceChannelMembers()); - for (ChannelMember cm2 : chMems) { + for (ChannelMember cm2: chMems) { if (resourcePaths == null || !resourcePaths.keySet().contains(cm2)) { // not a depending channel member. ResourcePath src2 = cm2.getResource(); Type srcResType2 = src2.getResourceStateType(); String srcResName2 = JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(src2.getResourceHierarchy())); - String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(getter, srcResName2, srcPath2, srcResType2); } else { // a depending channel member. @@ -888,7 +926,7 @@ // generate a pull data transfer from a depending in/ref resource. Type srcResType2 = src2.getResourceStateType(); String srcResName2 = JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(src2.getResourceHierarchy())); - String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(getter, srcResName2, srcPath2, srcResType2); } } @@ -900,7 +938,7 @@ if (resourcePathsAndMessage != null) { resourcePaths = resourcePathsAndMessage.getKey(); Term messageTermSub = resourcePathsAndMessage.getValue(); - for (Map.Entry subTermEnt : messageTermSub.getSubTerms(Term.class).entrySet()) { + for (Map.Entry subTermEnt: messageTermSub.getSubTerms(Term.class).entrySet()) { Term subTerm = subTermEnt.getValue(); if (!(subTerm instanceof Constant) && subTerm.getSymbol().isImplWithSideEffect()) { Variable var = new Variable("v" + v, subTerm.getType()); @@ -910,7 +948,7 @@ Position pos = new Position(); pos.addHeadOrder(0); subTerm.replaceSubTerm(pos, var); - sideEffects = new String[]{""}; + sideEffects = new String[] {""}; String curState = messageTermSub.toImplementation(sideEffects); getter.addStatement(sideEffects[0].replaceAll("\n", "")); // Cancel the side effects in the return value. @@ -935,14 +973,14 @@ selType = ((Variable) selExp).getType(); varName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; - for (ChannelMember cm2 : curChannel.getInputChannelMembers()) { + for (ChannelMember cm2 :curChannel.getInputChannelMembers()) { if (!cm2.isOutside()) { insideChMem = cm2; break; } } if (insideChMem == null) { - for (ChannelMember cm2 : curChannel.getReferenceChannelMembers()) { + for (ChannelMember cm2 :curChannel.getReferenceChannelMembers()) { if (!cm2.isOutside()) { insideChMem = cm2; break; @@ -961,16 +999,16 @@ Expression parentGetter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, dst.getInSideResource(ch)); Term valueGetter = new Term(new Symbol("getValue", 1, Symbol.Type.METHOD)); valueGetter.addChild(parentGetter); - parent = valueGetter.toImplementation(new String[]{}); + parent = valueGetter.toImplementation(new String[] {}); } else { - parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, dst.getInSideResource(ch)).toImplementation(new String[]{}); + parent = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(insideResPath, dst.getInSideResource(ch)).toImplementation(new String[] {}); } } else { parent = JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(insideResPath.getResourceHierarchy())); } if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for data collecting. - getter.addFirstStatement("for (int " + varName + " = 0; " + varName + " < " + parent + ".size(); " + varName + "++) {"); + getter.addFirstStatement("for (int " + varName + " = 0; " + varName +" < " + parent + ".size(); " + varName + "++) {"); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for data collecting. getter.addFirstStatement("for (String " + varName + ": " + parent + ".keySet()) {"); @@ -978,13 +1016,13 @@ if (insideResPath.getCommonPrefix(dst.getInSideResource(ch)) == null) { Type parentResType = insideResPath.getResourceStateType(); String parentResName = JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(insideResPath.getResourceHierarchy())); - String parentResPath = insideResPath.toString().replaceAll(":.*\\}", "\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); + String parentResPath = insideResPath.toString().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); generatePullDataTransfer(getter, parentResName, parentResPath, parentResType); } } } // initialize the variables to hold side effects within the loop - for (Variable var : varsForSideEffects) { + for (Variable var: varsForSideEffects) { getter.addFirstStatement(var.getType().getInterfaceTypeName() + " " + var.getName() + " = new " + var.getType().getImplementationTypeName() + "();"); } // end of the loop @@ -998,7 +1036,7 @@ } // generate a return statement. Expression curExp = ch.deriveUpdateExpressionOf(out, messageTerm, JerseyCodeGenerator.pullAccessor); - sideEffects = new String[]{""}; + sideEffects = new String[] {""}; String curState = curExp.toImplementation(sideEffects); if (ch.getChildren() == null || ch.getChildren().size() == 0) { getter.addStatement(sideEffects[0] + "return " + curState + ";"); @@ -1012,7 +1050,7 @@ List pathParams = new ArrayList<>(); generatePullDataTransfer(getter, src.getResourceName(), src.getResourceHierarchy().toResourcePath(pathParams), srcResourceType); } - } + } } } } @@ -1020,7 +1058,7 @@ } // for source nodes - for (ResourceHierarchy resource : model.getResourceHierarchies()) { + for (ResourceHierarchy resource: model.getResourceHierarchies()) { String resourceName = JerseyCodeGenerator.getComponentName(resource); TypeDeclaration component = componentMap.get(resourceName); if (JavaCodeGenerator.generatesComponent(resource)) { @@ -1044,13 +1082,13 @@ String implTypeName = resourceType.getImplementationTypeName(); stateGetter.addStatement("return new " + implTypeName + "(value);"); } else { - Term composer = null; + Term composer = null; Term composerSub = new Constant(DataConstraintModel.nil); composerSub.setType(DataConstraintModel.typeMap); - for (ResourceHierarchy child : resource.getChildren()) { + for (ResourceHierarchy child: resource.getChildren()) { String childTypeName = JerseyCodeGenerator.getComponentName(child); String fieldName = JerseyCodeGenerator.toVariableName(childTypeName); - Term childGetter = null; + Term childGetter = null; if (!JerseyCodeGenerator.generatesComponent(child)) { // the child is not a class childGetter = new Term(new Symbol("get" + childTypeName, 1, Symbol.Type.METHOD)); @@ -1062,18 +1100,18 @@ } composer = new Term(DataConstraintModel.insert); composer.addChild(composerSub); - composer.addChild(new Constant(fieldName, DataConstraintModel.typeString)); // key - composer.addChild(childGetter); // value + composer.addChild(new Constant(fieldName, DataConstraintModel.typeString)); // key + composer.addChild(childGetter); // value composer.setType(DataConstraintModel.typeMap); composerSub = composer; } composer.setType(stateGetter.getReturnType()); - String[] sideEffects = new String[]{null}; + String[] sideEffects = new String[] {null}; String returnValue = composer.toImplementation(sideEffects); if (sideEffects[0] != null) { - stateGetter.addStatement(sideEffects[0] + "return " + returnValue + ";"); + stateGetter.addStatement(sideEffects[0] + "return " + returnValue+ ";"); } else { - stateGetter.addStatement("return " + returnValue + ";"); + stateGetter.addStatement("return " + returnValue+ ";"); } } } @@ -1082,7 +1120,7 @@ // (#4) descendant getter method (the implementation must be kept consistent with #3) if (resource.getChildren().size() > 0) { - for (ResourceHierarchy child : resource.getChildren()) { + for (ResourceHierarchy child: resource.getChildren()) { ResourceHierarchy parent = resource; ResourceHierarchy descendant = child; Set children; @@ -1101,7 +1139,7 @@ do { String methodName = JerseyCodeGenerator.getComponentName(descendant); MethodDeclaration descendantGetter = null; - for (MethodDeclaration getter : getGetterMethods(component, methodName)) { + for (MethodDeclaration getter: getGetterMethods(component, methodName)) { if ((getter.getParameters() == null && params == 0) || (getter.getParameters() != null && getter.getParameters().size() == params)) { descendantGetter = getter; break; @@ -1122,7 +1160,7 @@ selector = newSelector; } if (descendantGetter != null && (descendantGetter.getBody() == null || descendantGetter.getBody().getStatements().size() == 0)) { - String[] sideEffects = new String[]{null}; + String[] sideEffects = new String[] {null}; String returnValue = selector.toImplementation(sideEffects); if (sideEffects[0] != null) descendantGetter.addStatement(sideEffects[0]); descendantGetter.addStatement("return " + returnValue + ";"); @@ -1141,16 +1179,16 @@ children = descendant.getChildren(); } while (children != null && children.size() == 1 && (descendant = children.iterator().next()) != null); } - } + } } } // methods for input events Map> ioChannelsAndMembers = getIOChannelsAndMembers(resource, model); - for (Map.Entry> entry : ioChannelsAndMembers.entrySet()) { + for (Map.Entry> entry: ioChannelsAndMembers.entrySet()) { DataTransferChannel ch = entry.getKey(); Set outs = entry.getValue(); - for (ChannelMember out : outs) { + for (ChannelMember out: outs) { MethodDeclaration input = null; if (JerseyCodeGenerator.generatesComponent(resource)) { // A component is generated for this resource. @@ -1166,7 +1204,7 @@ if (input != null) { // In each resource Set referredSet = referredResources.get(input); - for (ChannelMember rc : ch.getReferenceChannelMembers()) { + for (ChannelMember rc: ch.getReferenceChannelMembers()) { // For each reference channel member, get the current state of the reference side resource by pull data transfer. ResourcePath ref = rc.getResource(); if (referredSet == null) { @@ -1178,18 +1216,18 @@ Type refResourceType = ref.getResourceStateType(); if (!referredSet.contains(ref)) { referredSet.add(ref); - String[] sideEffects = new String[]{""}; - if (rc.isOutside()) { + String[] sideEffects = new String[] {""}; + ResourcePath dstRes = out.getResource(); + if (!JerseyCodeGenerator.generatesComponent(dstRes.getResourceHierarchy())) { + dstRes = dstRes.getParent(); + } + if (rc.isOutside() || (ref.getCommonPrefix(dstRes) == null && JerseyCodeGenerator.differentTreesAsDifferentServices)) { List pathParams = new ArrayList<>(); - for (Expression pathExp : ref.getPathParams()) { + for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(input, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType); + generatePullDataTransfer(input, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType); } else { - ResourcePath dstRes = out.getResource(); - if (!JerseyCodeGenerator.generatesComponent(dstRes.getResourceHierarchy())) { - dstRes = dstRes.getParent(); - } Expression refGetter = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(ref, dstRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = refResourceType.getInterfaceTypeName(); @@ -1219,7 +1257,7 @@ Type fieldType = JerseyCodeGenerator.getImplStateType(outRes); if (updateExp instanceof Term) { ((Term) updateExp).setType(fieldType); - for (Map.Entry varEnt : ((Term) updateExp).getVariables().entrySet()) { + for (Map.Entry varEnt: ((Term) updateExp).getVariables().entrySet()) { if (varEnt.getValue().getName().equals("value")) { varEnt.getValue().setType(fieldType); } @@ -1228,12 +1266,12 @@ ((Variable) updateExp).setType(fieldType); } // Add statements to the input method. - String[] sideEffects = new String[]{""}; + String[] sideEffects = new String[] {""}; String newState = updateExp.toImplementation(sideEffects); if (JerseyCodeGenerator.generatesComponent(resource)) { String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); } @@ -1246,7 +1284,7 @@ } else { String updateStatement = ""; if (sideEffects[0] != null) { - updateStatement = sideEffects[0]; + updateStatement = sideEffects[0]; updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(resource))); if (updateStatement.endsWith("\n")) { updateStatement = updateStatement.substring(0, updateStatement.length() - 1); @@ -1257,7 +1295,7 @@ selector.addChild(new Field("value")); selector.addChild(new Variable(input.getParameters().get(input.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newList = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (DataConstraintModel.typeMap.isAncestorOf(resource.getParent().getResourceStateType())) { @@ -1265,7 +1303,7 @@ selector.addChild(new Field("value")); selector.addChild(new Variable(input.getParameters().get(input.getParameters().size() - 2).getName())); selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[]{""}; + String[] sideEffects2 = new String[] {""}; String newMap = selector.toImplementation(sideEffects2); updateStatement += sideEffects2[0]; } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { @@ -1299,14 +1337,14 @@ if (resExp instanceof Term) { // to access the parent if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args += delimiter + ((Variable) ((Term) resExp).getChild(1)).getName(); + args += delimiter + ((Variable)((Term) resExp).getChild(1)).getName(); delimiter = ", "; } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[]{""}); + String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. - for (Selector selector : ch.getAllSelectors()) { + for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); args += delimiter + selVar.getName(); @@ -1315,7 +1353,7 @@ } // Values of message parameters. if (message instanceof Term) { - for (Variable mesVar : message.getVariables().values()) { + for (Variable mesVar: message.getVariables().values()) { args += delimiter + mesVar.getName(); delimiter = ", "; } @@ -1331,12 +1369,12 @@ } } } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e1) { + | InvalidMessage | UnificationFailed | ValueUndefined e1) { e1.printStackTrace(); } return codes; } - + private static void replaceJsonTermWithConstructorInvocation(Expression exp, Type replacedJsonType, String replacingClassName, TypeDeclaration descendantComponent) { // Replace each json term in exp with the corresponding constructor invocation. Type descendantType = new Type(replacingClassName, replacingClassName); @@ -1352,12 +1390,12 @@ MethodDeclaration descendantConstructor = getConstructor(descendantComponent); if (descendantConstructor != null) { String delimiter = ""; - for (VariableDeclaration var : descendantConstructor.getParameters()) { + for (VariableDeclaration var: descendantConstructor.getParameters()) { // Extract the argument of each constructor parameter from jsonTerm. JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); jsonMember.addChild(jsonTerm); jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); - Expression param = jsonMember.reduce(); // Reduce {"name": "foo", age: 25}.name => "foo" + Expression param = jsonMember.reduce(); // Reduce {"name": "foo", age: 25}.name => "foo" if (param != null) { if (param instanceof Term) { if (((Term) param).getType() == null) { @@ -1384,10 +1422,10 @@ } } else { Type oldType = jsonTerm.getType(); - Type newType = new Type(oldType.getTypeName(), - oldType.getImplementationTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName), - oldType.getInterfaceTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName)); - for (Type parent : oldType.getParentTypes()) { + Type newType = new Type(oldType.getTypeName(), + oldType.getImplementationTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName), + oldType.getInterfaceTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName)); + for (Type parent: oldType.getParentTypes()) { newType.addParentType(parent); } jsonTerm.setType(newType); @@ -1395,7 +1433,7 @@ } } } - + private static void generatePullDataTransfer(MethodDeclaration methodBody, String fromResourceName, String fromResourcePath, Type fromResourceType) { String varName = new String(fromResourceName); String respTypeName = fromResourceType.getInterfaceTypeName(); @@ -1437,7 +1475,7 @@ } methodBody.addFirstStatement(respTypeName + " " + varName + " = " + getHttpMethodCallStatementWithResponse(baseURL, fromResourcePath, "get", respImplTypeName)); } - + private static String convertFromEntryToMapType(Type type) { String mapTypeName = null; if (DataConstraintModel.typePair.isAncestorOf(type)) { @@ -1462,18 +1500,18 @@ for (int idx = mapTypeName.indexOf("<", 0); idx >= 0; idx = mapTypeName.indexOf("<", idx + 1)) { int to = mapTypeName.indexOf(",", idx); if (to > idx) { - mapTypeName = mapTypeName.substring(0, idx + 1) + "String" + mapTypeName.substring(to); // All elements except for the last one have the string type. + mapTypeName = mapTypeName.substring(0, idx + 1) + "String" + mapTypeName.substring(to); // All elements except for the last one have the string type. } } } return mapTypeName; } - + private static String getCodeForConversionFromMapToTuple(Type tupleType, String mapVar) { String decoded = "$x"; List elementsTypes = TypeInference.getTupleComponentTypes(tupleType); String elementBase = mapVar; - for (Type elmType : elementsTypes.subList(0, elementsTypes.size() - 1)) { + for (Type elmType: elementsTypes.subList(0, elementsTypes.size() - 1)) { elementBase += ".entrySet().iterator().next()"; if (elmType == DataConstraintModel.typeBoolean || elmType == DataConstraintModel.typeInt @@ -1492,14 +1530,14 @@ decoded = decoded.replace("$x", elementBase); return decoded; } - + private static String getCodeForConversionFromMapToPair(Type pairType, String mapVar) { String decoded = "$x"; decoded = decoded.replace("$x", "new Pair<>(" + mapVar + ".get(\"left\"), $x)"); decoded = decoded.replace("$x", mapVar + ".get(\"right\")"); return decoded; } - + private static String getCodeForConversionFromMapToMap(Type mapType, String mapVal, String mapVar) { List elementsTypes = TypeInference.getMapComponentTypes(mapType); Type keyType = elementsTypes.get(0); @@ -1521,14 +1559,14 @@ } return decoded; } - + private static String getHttpMethodParamsStatement(String callerResourceName, List>> params, boolean isFirstCall) { String statements = ""; if (isFirstCall) { statements += "Form "; } statements += "form = new Form();\n"; - for (Map.Entry> param : params) { + for (Map.Entry> param: params) { Type paramType = param.getKey(); String paramName = param.getValue().getKey(); String value = param.getValue().getValue(); @@ -1541,7 +1579,7 @@ statements += "for (" + wrapperType + " i: " + value + ") {\n"; } if (DataConstraintModel.typeTuple.isAncestorOf(compType) || DataConstraintModel.typePair.isAncestorOf(paramType) || DataConstraintModel.typeList.isAncestorOf(compType) || DataConstraintModel.typeMap.isAncestorOf(paramType)) { - statements += "\tform.param(\"" + paramName + "\", new ObjectMapper().writeValueAsString(i));\n"; // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} + statements += "\tform.param(\"" + paramName + "\", new ObjectMapper().writeValueAsString(i));\n"; // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} } else { statements += "\tform.param(\"" + paramName + "\", i.toString());\n"; } @@ -1549,7 +1587,7 @@ // return "Entity entity = Entity.entity(" + paramName + ".toString(), MediaType.APPLICATION_JSON);"; } else if (DataConstraintModel.typeTuple.isAncestorOf(paramType) || DataConstraintModel.typePair.isAncestorOf(paramType) || DataConstraintModel.typeMap.isAncestorOf(paramType)) { // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} - statements += "form.param(\"" + paramName + "\", new ObjectMapper().writeValueAsString(" + value + "));\n"; + statements += "form.param(\"" + paramName + "\", new ObjectMapper().writeValueAsString(" + value + "));\n"; } else { statements += "form.param(\"" + paramName + "\", " + new JavaSpecific().getValueToStringExp(paramType.getImplementationTypeName(), value) + ");\n"; } @@ -1560,12 +1598,12 @@ statements += "entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED);"; return statements; } - + private static String getHttpMethodCallStatement(String baseURL, String resourceName, String srcResName, String httpMethod) { if (srcResName == null) { return "client.target(\"" + baseURL + "\").path(\"/" + resourceName + "\").request()." + httpMethod + "(entity, String.class);"; } else { - // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. + // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. return "client.target(\"" + baseURL + "\").path(\"/" + resourceName + "/" + srcResName + "\").request()." + httpMethod + "(entity, String.class);"; } } @@ -1575,18 +1613,18 @@ if (respImplName.contains("<")) { responseShortTypeName = respImplName.substring(0, respImplName.indexOf("<")); } - return "client.target(\"" + baseURL + "\").path(\"/" + resourceName + "\").request()." + httpMethod + "(" + responseShortTypeName + ".class);"; + return "client.target(\"" + baseURL + "\").path(\"/" + resourceName + "\").request()." + httpMethod + "(" + responseShortTypeName + ".class);"; } - + private static MethodDeclaration getConstructor(TypeDeclaration component) { - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (m.isConstructor()) return m; } return null; } - + private static MethodDeclaration getUpdateMethod(TypeDeclaration component, String dstResName, String srcResName) { - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (dstResName == null) { if (m.getName().equals("updateFrom" + srcResName)) return m; } else { @@ -1598,7 +1636,7 @@ private static List getUpdateMethods(TypeDeclaration component, String resName) { List updates = new ArrayList<>(); - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (resName == null) { if (m.getName().startsWith("updateFrom")) { updates.add(m); @@ -1613,7 +1651,7 @@ } private static MethodDeclaration getGetterMethod(TypeDeclaration component, String resourceName) { - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (m.getName().startsWith("get" + resourceName)) return m; } return null; @@ -1621,7 +1659,7 @@ private static List getGetterMethods(TypeDeclaration component, String resourceName) { List getters = new ArrayList<>(); - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (m.getName().equals("get" + resourceName)) { getters.add(m); } @@ -1631,10 +1669,10 @@ private static Map> getIOChannelsAndMembers(ResourceHierarchy resource, DataTransferModel model) { Map> ioChannelsAndMembers = new HashMap<>(); - for (Channel c : model.getInputChannels()) { + for (Channel c: model.getInputChannels()) { DataTransferChannel ch = (DataTransferChannel) c; // I/O channel - for (ChannelMember out : ch.getOutputChannelMembers()) { + for (ChannelMember out: ch.getOutputChannelMembers()) { if (resource.equals(out.getResource().getResourceHierarchy())) { if (out.getStateTransition().getMessageExpression() instanceof Term || out.getStateTransition().getMessageExpression() instanceof Variable) { Set channelMembers = ioChannelsAndMembers.get(ch); @@ -1649,13 +1687,13 @@ } return ioChannelsAndMembers; } - + private static List getInputMethods(TypeDeclaration component, ResourceNode resource, DataTransferModel model) { List inputs = new ArrayList<>(); - for (Channel c : model.getInputChannels()) { + for (Channel c: model.getInputChannels()) { DataTransferChannel channel = (DataTransferChannel) c; // I/O channel - for (ChannelMember out : channel.getOutputChannelMembers()) { + for (ChannelMember out: channel.getOutputChannelMembers()) { if (resource.getInSideResources().contains(out.getResource())) { MethodDeclaration input = getInputMethod(component, out, channel.getOutputChannelMembers().size()); inputs.add(input); @@ -1664,7 +1702,7 @@ } return inputs; } - + private static MethodDeclaration getInputMethod(TypeDeclaration component, ChannelMember cm, int outNumber) { String inputMethodName = null; if (cm.getStateTransition().getMessageExpression() instanceof Term) { @@ -1680,9 +1718,9 @@ MethodDeclaration input = getMethod(component, inputMethodName); return input; } - + private static MethodDeclaration getMethod(TypeDeclaration component, String methodName) { - for (MethodDeclaration m : component.getMethods()) { + for (MethodDeclaration m: component.getMethods()) { if (m.getName().equals(methodName)) return m; } return null; diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index d96bfec..6ea96b7 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -65,6 +65,11 @@ children.add(child); } + public void addChild(int n, Expression child, boolean bForced) { + if (!bForced && getArity() != -1 && children.size() >= getArity()) return; + children.add(n, child); + } + public Expression getChild(int n) { return children.get(n); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java index d0c991d..2b2cd4f 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java @@ -1,6 +1,12 @@ package models.controlFlowModel; -import models.DirectedGraph; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import generators.CodeGenerator; import models.Edge; import models.Node; import models.algebra.Expression; @@ -8,232 +14,70 @@ import models.algebra.Variable; import models.dataConstraintModel.Channel; import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.ResourcePath; +import models.DirectedGraph; import models.dataFlowModel.*; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * {@link ControlFlowGraph} is made from data-flow graph.
- * It manages two call graphs: push call graph and pull call graph. - * - * @implNote Some nodes are shared between push and pull call graphs. - */ public class ControlFlowGraph extends DirectedGraph implements IFlowGraph { - private final DataFlowGraph dataFlowGraph; - private final CallGraph pushCallGraph; - private final CallGraph pullCallGraph; + private DataFlowGraph dataFlowGraph; + private CallGraph pushCallGraph; + private CallGraph pullCallGraph; public ControlFlowGraph(DataFlowGraph dataFlowGraph, DataTransferModel model) { this.dataFlowGraph = dataFlowGraph; this.pushCallGraph = new CallGraph(); this.pullCallGraph = new CallGraph(); - for (Edge resToCh : dataFlowGraph.getEdges()) { + for (Edge resToCh: dataFlowGraph.getEdges()) { if (!((DataFlowEdge) resToCh).isChannelToResource()) { // A resource to channel edge - PushPullAttribute pushPull = ((PushPullAttribute) resToCh.getAttribute()); + PushPullAttribute pushPull = ((PushPullAttribute) ((DataFlowEdge) resToCh).getAttribute()); ResourceNode srcResNode = (ResourceNode) resToCh.getSource(); ChannelNode chNode = (ChannelNode) resToCh.getDestination(); - for (Edge chToRes : chNode.getOutEdges()) { + for (Edge chToRes: chNode.getOutEdges()) { ResourceNode dstResNode = (ResourceNode) chToRes.getDestination(); - if (pushPull.getOptions().get(0) == PushPullValue.PUSH) { - // same direction as the data flow - pushCallGraph.addEdge(srcResNode, dstResNode, PushPullValue.PUSH); - } else { - // reverse direction to the data flow - pullCallGraph.addEdge(dstResNode, srcResNode, PushPullValue.PULL); + if (!CodeGenerator.generatesComponent(srcResNode.getResourceHierarchy())) { + srcResNode = srcResNode.getParent(); } - } - } - } - for (Channel ch : model.getInputChannels()) { - DataTransferChannel evCh = (DataTransferChannel) ch; - traverseChannelHierarchy(evCh, pushCallGraph); - } - - setupReferenceEdges(dataFlowGraph, model); - } - - /** - * Establishes reference edges in the push and pull call graphs using the given data flow graph - * and data transfer model. This method processes each channel node in the data flow graph, - * determining whether it operates in a push or pull context. If applicable, it collects - * the relevant input and output resource nodes and adds edges between them in - * their respective call graphs. - * - * @param dataFlowGraph The data flow graph containing channel nodes and resource nodes. - * It represents the overall structure and relationships between - * channels and resources in the system. - * @param model The data transfer model supporting context evaluation (push or pull) - * and providing additional relevant data required for graph construction. - */ - private void setupReferenceEdges(DataFlowGraph dataFlowGraph, DataTransferModel model) { - for (ChannelNode channelNode : dataFlowGraph.getChannelNodes()) { - DataTransferChannel channel = channelNode.getChannel(); - boolean isPush = isPushContext(channelNode, model); - boolean isPull = isPullContext(channelNode, model); - - if (isPush || isPull) { - for (ResourcePath targetResourcePath : channel.getReferenceResources()) { - for (ResourceNode inputResourceNode : dataFlowGraph.getResourceNodes(targetResourcePath.getResourceHierarchy())) { - Set outputResourceNodes = new HashSet<>(); - collectOutputResources(channelNode, outputResourceNodes); - - for (ResourceNode destinationNode : outputResourceNodes) { - if (isPush) { - pushCallGraph.addEdge(inputResourceNode, destinationNode, PushPullValue.PUSH); - } - if (isPull) { - pullCallGraph.addEdge(destinationNode, inputResourceNode, PushPullValue.PULL); - } + if (!CodeGenerator.generatesComponent(dstResNode.getResourceHierarchy())) { + dstResNode = dstResNode.getParent(); + } + if (!srcResNode.getResourceHierarchy().equals(dstResNode.getResourceHierarchy())) { + if (pushPull.getOptions().get(0) == PushPullValue.PUSH) { + // same direction as the data flow + pushCallGraph.addEdge(srcResNode, dstResNode, PushPullValue.PUSH); + } else { + // reverse direction to the data flow + pullCallGraph.addEdge(dstResNode, srcResNode, PushPullValue.PULL); } } } } } - } - - /** - * Determines whether the given channel node operates in a push-based data transfer context. - * This method evaluates the channel node's input channels and incoming edges to check - * if they involve a "PUSH" operation. If no push context is identified, the method - * recursively checks the parent channel node until a push context is found or the - * hierarchy is fully traversed. - * - * @param channelNode The channel node for which the push-based data transfer context - * is being determined. This node represents the entry point - * for the evaluation. - * @param model The data transfer model containing channel and flow information - * necessary for evaluating the data transfer context. - * @return {@code true} if the channel node (or any of its parent nodes) operates - * in a push-based data transfer context; {@code false} otherwise. - */ - private boolean isPushContext(ChannelNode channelNode, DataTransferModel model) { - if (model.getInputChannels().contains(channelNode.getChannel())) { - return true; - } - for (Edge resourceToChannel : channelNode.getInEdges()) { - if (resourceToChannel instanceof DataFlowEdge) { - PushPullAttribute attribute = (PushPullAttribute) (resourceToChannel).getAttribute(); - if (attribute != null && attribute.getOptions().contains(PushPullValue.PUSH)) { - return true; + for (Channel ch: model.getInputChannels()) { + DataTransferChannel evCh = (DataTransferChannel) ch; + EventChannelObjectNode srcNode = new EventChannelObjectNode(evCh); + for (ChannelMember cm: evCh.getChannelMembers()) { + if (srcNode.getName() == null) { + Expression exp = cm.getStateTransition().getMessageExpression(); + if (exp instanceof Term) { + srcNode.setName(((Term) exp).getSymbol().getName()); + } else if (exp instanceof Variable) { + srcNode.setName(((Variable) exp).getName()); + } + } + for (ResourceNode dstResNode: dataFlowGraph.getResourceNodes(cm.getResource().getResourceHierarchy())) { + if (!CodeGenerator.generatesComponent(dstResNode.getResourceHierarchy())) { + dstResNode = dstResNode.getParent(); + } + StatefulObjectNode dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + if (dstNode == null) { + pushCallGraph.addNode(dstResNode); + dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + } + // from an input event channel to a resource + pushCallGraph.insertEdge(srcNode, dstNode, PushPullValue.PUSH, 0); } } } - if (channelNode.getParent() != null) { - return isPushContext(channelNode.getParent(), model); - } - return false; - } - - /** - * Determines whether the given channel node operates in a pull-based data transfer context. - * The method evaluates all incoming edges of the specified channel node to check if any - * data flow involves a "PULL" operation. If none is found, it recursively checks the parent - * channel node until a pull context is identified or the hierarchy is exhausted. - * - * @param channelNode The channel node whose data transfer context is being evaluated. - * This node serves as the entry point for the context determination. - * @param model The data transfer model that may provide additional contextual - * information used during the evaluation. - * @return {@code true} if the channel node (or any of its parent nodes) is in a pull-based - * data transfer context; {@code false} otherwise. - */ - private boolean isPullContext(ChannelNode channelNode, DataTransferModel model) { - for (Edge resourceToChannel : channelNode.getInEdges()) { - if (resourceToChannel instanceof DataFlowEdge) { - PushPullAttribute attribute = (PushPullAttribute) (resourceToChannel).getAttribute(); - if (attribute != null && attribute.getOptions().contains(PushPullValue.PULL)) { - return true; - } - } - } - if (channelNode.getParent() != null) { - return isPullContext(channelNode.getParent(), model); - } - return false; - } - - /** - * Collects all output resources associated with the given channel node and - * accumulates them into the provided result set. The method identifies the root - * of the channel hierarchy by traversing upwards through the parent nodes, - * then recursively processes the hierarchy starting from the root to collect - * associated resource nodes. - * - * @param channelNode The starting channel node from which the root channel node - * is determined. The resource collection begins from the - * root node of the hierarchy. - * @param results A set where the collected resource nodes are stored. - * This set is updated during the execution of the method. - */ - private void collectOutputResources(ChannelNode channelNode, Set results) { - // Find root - ChannelNode root = channelNode; - while (root.getParent() != null) { - root = root.getParent(); - } - collectOutputResourcesRecursive(root, results); - } - - /** - * Recursively collects the output resources connected to the given channel node - * and adds them to the provided result set. This method traverses the outgoing - * edges of the specified channel node to identify associated resource nodes. - * It then recursively processes all child nodes of the provided channel node. - * - * @param channelNode The root channel node whose output resources are to be collected. - * It serves as the starting point for the recursive traversal. - * @param results A set where the identified output resource nodes are accumulated. - * This set is updated during the traversal and eventually contains - * all output resources reachable from the root channel node. - */ - private void collectOutputResourcesRecursive(ChannelNode channelNode, Set results) { - for (Edge outputEdge : channelNode.getOutEdges()) { - results.add((ResourceNode) outputEdge.getDestination()); - } - for (ChannelNode child : channelNode.getChildren()) { - collectOutputResourcesRecursive(child, results); - } - } - - /** - * Traverses the hierarchy of a {@link DataTransferChannel} and constructs connections - * in the provided push call graph between the event channels and associated - * stateful objects. - * - * @param channel The root DataTransferChannel to traverse, representing - * the starting point of the channel hierarchy. - * @param pushCallGraph The CallGraph to which push connections between - * channels and resources are added as the traversal progresses. - */ - private void traverseChannelHierarchy(DataTransferChannel channel, CallGraph pushCallGraph) { - EventChannelObjectNode parentChannelNode = new EventChannelObjectNode(channel); - for (ChannelMember channelMember : channel.getChannelMembers()) { - if (parentChannelNode.getName() == null) { - Expression message = channelMember.getStateTransition().getMessageExpression(); - if (message instanceof Term) { - parentChannelNode.setName(((Term) message).getSymbol().getName()); - } else if (message instanceof Variable) { - parentChannelNode.setName(((Variable) message).getName()); - } - } - for (ResourceNode destinationResourceNode : dataFlowGraph.getResourceNodes(channelMember.getResource().getResourceHierarchy())) { - StatefulObjectNode destinationNode = pushCallGraph.getStatefulObjectNode(destinationResourceNode); - if (destinationNode == null) { - pushCallGraph.addNode(destinationResourceNode); - destinationNode = pushCallGraph.getStatefulObjectNode(destinationResourceNode); - } - // from an input event channel to a resource - pushCallGraph.insertEdge(parentChannelNode, destinationNode, PushPullValue.PUSH, 0); - } - } - for (Channel child : channel.getChildren()) { - traverseChannelHierarchy((DataTransferChannel) child, pushCallGraph); - } } public DataFlowGraph getDataFlowGraph() { @@ -247,16 +91,16 @@ public CallGraph getPullCallGraph() { return pullCallGraph; } - + @Override public Map> getAllComponentNodes() { Map> allNodeSets = new HashMap<>(); - for (Node n : pushCallGraph.getNodes()) { + for (Node n: pushCallGraph.getNodes()) { Set nodeSet = new HashSet<>(); nodeSet.add(n); allNodeSets.put(n, nodeSet); } - for (Node n : pullCallGraph.getNodes()) { + for (Node n: pullCallGraph.getNodes()) { if (n instanceof StatefulObjectNode) { ResourceNode resNode = ((StatefulObjectNode) n).getResource(); Set nodeSet = null; diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 5d8438f..e9128bf 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -83,7 +83,10 @@ public SystemState transition(Event inputEvent) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { SystemState nextSystemState = new SystemState(curState); - inputEvent.constructMessageAndDescendantEvents(new ResourceStateValueProvider(curState, nextSystemState), true); + Expression message = inputEvent.constructMessageAndDescendantEvents(new ResourceStateValueProvider(curState, nextSystemState), true); + if (message != null) { + inputEvent.setMessage(message); + } nextSystemState.addEvent(inputEvent); fireEvent(inputEvent, curState, nextSystemState);