| |
---|
| | Map<ResourceHierarchy, TypeDeclaration> resourceComponents = new HashMap<>(); |
---|
| | Map<ResourceHierarchy, MethodDeclaration> resourceConstructors = new HashMap<>(); |
---|
| | List<Map.Entry<ResourceHierarchy, VariableDeclaration>> constructorParams = new ArrayList<>(); |
---|
| | List<Map.Entry<ResourceHierarchy, String>> constructorStatements = new ArrayList<>(); |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> updateStatements = new HashMap<>(); |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> updateStatements = new HashMap<>(); |
---|
| | Map<ResourceHierarchy, Set<ResourceHierarchy>> descendantGetters = new HashMap<>(); |
---|
| | |
---|
| | // For each components (1st pass). |
---|
| | for (Node componentNode: components) { |
---|
| |
---|
| | parentComponent = resourceComponents.get(resourceNode.getResourceHierarchy().getParent()); |
---|
| | } |
---|
| | |
---|
| | // Declare cache fields and update methods in this resource. |
---|
| | Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec); |
---|
| | Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec); |
---|
| | if (component == null) { |
---|
| | // Constructor statements were not added to any component because no component had been generated. |
---|
| | for (String statement: initStatementsAndUpdateUpdates.getKey()) { |
---|
| | constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); |
---|
| | } |
---|
| | } |
---|
| | for (Map.Entry<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) { |
---|
| | for (Map.Entry<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) { |
---|
| | updateStatements.put(entry.getKey(), entry.getValue()); |
---|
| | } |
---|
| | |
---|
| | // Declare the fields to refer to other resources in the parent/this component, and the state field in the parent component. |
---|
| |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | // Declare input methods in this component and the main component. |
---|
| | Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec); |
---|
| | Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec); |
---|
| | if (component == null) { |
---|
| | // Constructor statements were not added to any component because no component had been generated. |
---|
| | for (String statement: initStatementsAndInputUpdates.getKey()) { |
---|
| | constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); |
---|
| | } |
---|
| | } |
---|
| | for (Map.Entry<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> entry: initStatementsAndInputUpdates.getValue().entrySet()) { |
---|
| | for (Map.Entry<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> entry: initStatementsAndInputUpdates.getValue().entrySet()) { |
---|
| | updateStatements.put(entry.getKey(), entry.getValue()); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| |
---|
| | |
---|
| | // Add update statements. |
---|
| | for (MethodDeclaration method: updateStatements.keySet()) { |
---|
| | Expression updateExp = updateStatements.get(method).getKey(); |
---|
| | ResourceHierarchy descendantRes = updateStatements.get(method).getValue(); |
---|
| | Set<ResourceHierarchy> children; |
---|
| | do { |
---|
| | if (JavaCodeGenerator.generatesComponent(descendantRes)) break; |
---|
| | children = descendantRes.getChildren(); |
---|
| | } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); |
---|
| | TypeDeclaration descendanttComponent = resourceComponents.get(descendantRes); |
---|
| | addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, descendantRes, descendanttComponent, langSpec); |
---|
| | ResourceHierarchy resource = updateStatements.get(method).getValue().getKey(); |
---|
| | ResourceHierarchy descendantRes = updateStatements.get(method).getValue().getValue(); |
---|
| | TypeDeclaration descendantComponent = resourceComponents.get(descendantRes); |
---|
| | addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, resource, descendantRes, descendantComponent, langSpec); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static List<VariableDeclaration> addConstructorParameters(ResourceHierarchy resource, Map<ResourceHierarchy, TypeDeclaration> resourceComponents, |
---|
| |
---|
| | if (resource.getNumParameters() > 0) params.clear(); |
---|
| | return params; |
---|
| | } |
---|
| | |
---|
| | private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) { |
---|
| | private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy resource, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) { |
---|
| | Type replacedJsonType = descendantRes.getResourceStateType(); |
---|
| | String replacingClassName = getComponentName(descendantRes, langSpec); |
---|
| | Type descendantType = new Type(replacingClassName, replacingClassName); |
---|
| | Map<Position, Term> subTerms = ((Term) exp).getSubTerms(Term.class); |
---|
| |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | // Replace the type of the state field. |
---|
| | Type fieldType = getImplStateType(descendantRes.getParent(), langSpec); |
---|
| | Type fieldType = getImplStateType(resource, langSpec); |
---|
| | if (exp instanceof Term) { |
---|
| | ((Term) exp).setType(fieldType); |
---|
| | for (Map.Entry<Position, Variable> varEnt: ((Term) exp).getVariables().entrySet()) { |
---|
| | if (varEnt.getValue().getName().equals(fieldOfResourceState)) { |
---|
| |
---|
| | } while (childNodes != null && childNodes.size() == 1 && (descendant = childNodes.iterator().next()) != null); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) { |
---|
| | private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) { |
---|
| | // Declare cash fields and update methods in the component. |
---|
| | String resComponentName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); |
---|
| | List<String> constructorStatements = new ArrayList<>(); |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> updateStatements = new HashMap<>(); |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> updateStatements = new HashMap<>(); |
---|
| | for (Edge chToRes: resourceNode.getInEdges()) { |
---|
| | for (Edge resToCh: chToRes.getSource().getInEdges()) { |
---|
| | DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); |
---|
| | DataFlowEdge re = (DataFlowEdge) resToCh; |
---|
| |
---|
| | } |
---|
| | // Replace Json constructor with a constructor of the child resource. |
---|
| | ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); |
---|
| | if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { |
---|
| | ResourceHierarchy childRes = outRes.getChildren().iterator().next(); |
---|
| | Type childStateType = childRes.getResourceStateType(); |
---|
| | if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { |
---|
| | updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, childRes)); |
---|
| | break; |
---|
| | } |
---|
| | ResourceHierarchy descendantRes = outRes; |
---|
| | Set<ResourceHierarchy> children = descendantRes.getChildren(); |
---|
| | do { |
---|
| | descendantRes = children.iterator().next(); |
---|
| | if (generatesComponent(descendantRes)) { |
---|
| | updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes))); |
---|
| | updateExp = null; |
---|
| | break; |
---|
| | } |
---|
| | children = descendantRes.getChildren(); |
---|
| | } while (children != null && children.size() == 1); |
---|
| | } |
---|
| | // Add statements to the update method. |
---|
| | String[] sideEffects = new String[] {""}; |
---|
| | String newState = updateExp.toImplementation(sideEffects); |
---|
| |
---|
| | } |
---|
| | return new AbstractMap.SimpleEntry<>(constructorStatements, updateStatements); |
---|
| | } |
---|
| | |
---|
| | private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, |
---|
| | private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, |
---|
| | TypeDeclaration parentComponent, TypeDeclaration mainComponent, DataTransferModel model, ILanguageSpecific langSpec) { |
---|
| | // Declare input methods. |
---|
| | String resName = resourceNode.getResourceName(); |
---|
| | String resComponentName = langSpec.toComponentName(resName); |
---|
| | List<String> constructorStatements = new ArrayList<>(); |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> inputStatements = new HashMap<>(); |
---|
| | for (Channel ch : model.getInputChannels()) { |
---|
| | for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) { |
---|
| | Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> inputStatements = new HashMap<>(); |
---|
| | for (Channel ch: model.getInputChannels()) { |
---|
| | for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) { |
---|
| | if (resourceNode.getInSideResources().contains(out.getResource())) { |
---|
| | Expression message = out.getStateTransition().getMessageExpression(); |
---|
| | MethodDeclaration input = null; |
---|
| | MethodDeclaration inputAccessor = null; |
---|
| |
---|
| | if (input != null) { |
---|
| | // Add a statement to update the state field to the input method. |
---|
| | try { |
---|
| | Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor()).getKey(); |
---|
| | // Replace Json constructor with a constructor of the child resource. |
---|
| | // Replace Json constructor with a constructor of a descendant resource. |
---|
| | ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); |
---|
| | if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { |
---|
| | ResourceHierarchy childRes = outRes.getChildren().iterator().next(); |
---|
| | Type childStateType = childRes.getResourceStateType(); |
---|
| | if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { |
---|
| | inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, childRes)); |
---|
| | updateExp = null; |
---|
| | } |
---|
| | ResourceHierarchy descendantRes = outRes; |
---|
| | Set<ResourceHierarchy> children = descendantRes.getChildren(); |
---|
| | do { |
---|
| | descendantRes = children.iterator().next(); |
---|
| | if (generatesComponent(descendantRes)) { |
---|
| | inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes))); |
---|
| | updateExp = null; |
---|
| | break; |
---|
| | } |
---|
| | children = descendantRes.getChildren(); |
---|
| | } while (children != null && children.size() == 1); |
---|
| | } |
---|
| | // Add statements to the input method. |
---|
| | if (updateExp != null) { |
---|
| | String[] sideEffects = new String[] {""}; |
---|
| |
---|
| | |