diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index d3257f0..015baa7 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -57,6 +57,7 @@ public static final String _for = "For"; private static String mainTypeName = null; private static ILanguageSpecific langSpec = null; + private static IPlatformSpecific platformSpec = null; public static String getMainTypeName() { return mainTypeName; @@ -134,33 +135,34 @@ * @param langSpec specified language * @return source codes */ - public ArrayList generateCode(DataTransferModel model, DataFlowGraph flowGraph, ILanguageSpecific langSpec) { + public ArrayList generateCode(DataTransferModel model, DataFlowGraph flowGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { CodeGenerator.langSpec = langSpec; + CodeGenerator.platformSpec = platformSpec; ArrayList codes = new ArrayList<>(); - // Get the dependency among root nodes. - Map> dependedRootComponentGraph = getDependedRootComponentGraph(model); - - // Sort the all components. - ArrayList components = determineComponentOrder(flowGraph, dependedRootComponentGraph); - - // Add the main component. - if (mainTypeName == null) { - mainTypeName = langSpec.getMainComponentName(); + Map> dependedRootComponentGraph = null; + Collection components = null; + if (platformSpec.isMonolithic()) { + // To build monolithic application, the dependency of the components should be resolved in advance. + + // Get the dependency among root nodes. + dependedRootComponentGraph = getDependedRootComponentGraph(model); + + // Sort the all components. + components = determineComponentOrder(flowGraph, dependedRootComponentGraph); + } else { + // Get the all components. + components = flowGraph.getResourceNodes(); } - TypeDeclaration mainComponent = langSpec.newTypeDeclaration(mainTypeName); - MethodDeclaration mainConstructor = mainComponent.createConstructor(); - CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent); - codes.add(mainCU); // Generate the other components. - generateCodeFromFlowGraph(model, flowGraph, components, dependedRootComponentGraph, mainComponent, mainConstructor, codes, langSpec); + generateCodeFromFlowGraph(model, flowGraph, components, codes, dependedRootComponentGraph, platformSpec, langSpec); return codes; } - public abstract void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, ArrayList components, Map> dependedRootComponentGraph, - TypeDeclaration mainComponent, MethodDeclaration mainConstructor, ArrayList codes, ILanguageSpecific langSpec); + public abstract void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, Collection components, ArrayList codes, + Map> dependedRootComponentGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec); private static Map> getDependedRootComponentGraph(DataTransferModel model) { Map> dependedComponentGraph = new HashMap<>(); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 31fbea9..2e7a2fc 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -2,6 +2,7 @@ import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -12,9 +13,11 @@ import java.util.Stack; import java.util.AbstractMap.SimpleEntry; +import code.ast.Annotation; import code.ast.Block; import code.ast.CompilationUnit; import code.ast.FieldDeclaration; +import code.ast.ImportDeclaration; import code.ast.MethodDeclaration; import code.ast.TypeDeclaration; import code.ast.VariableDeclaration; @@ -54,8 +57,8 @@ public class CodeGeneratorFromDataFlowGraph extends CodeGenerator { - public void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, ArrayList components, Map> dependedRootComponentGraph, - TypeDeclaration mainComponent, MethodDeclaration mainConstructor, ArrayList codes, ILanguageSpecific langSpec) { + public void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, Collection components, ArrayList codes, + Map> dependedRootComponentGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { Map resourceComponents = new HashMap<>(); Map resourceConstructors = new HashMap<>(); List> constructorParams = new ArrayList<>(); @@ -63,6 +66,19 @@ Map>> updateStatements = new HashMap<>(); Map> descendantGetters = new HashMap<>(); + TypeDeclaration mainComponent = null; + MethodDeclaration mainConstructor = null; + if (platformSpec.hasMain()) { + // Add the main component. + if (getMainTypeName() == null) { + setMainTypeName(langSpec.getMainComponentName()); + } + mainComponent = langSpec.newTypeDeclaration(getMainTypeName()); + mainConstructor = mainComponent.createConstructor(); + CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent); + codes.add(mainCU); + } + // For each components (1st pass). for (Node componentNode: components) { ResourceNode resourceNode = (ResourceNode) componentNode; @@ -76,26 +92,38 @@ if (component == null) { // Add compilation unit for this component. component = langSpec.newTypeDeclaration(resourceName); + if (platformSpec.hasComponentAnnotation() && resourceNode.getResourceHierarchy().getParent() == null) { + // For each root node, add component annotations. + platformSpec.addComponentAnnotations(component, resourceNode.getResourceName()); + } resourceComponents.put(resourceNode.getResourceHierarchy(), component); CompilationUnit cu = langSpec.newCompilationUnit(component); + if (platformSpec.hasPlatformSpecificImports() && resourceNode.getResourceHierarchy().getParent() == null) { + // For each root node, add platform specific imports. + platformSpec.addPlatformSpecificImports(cu); + } codes.add(cu); - // Declare the constructor. - MethodDeclaration constructor = declareConstructor(resourceNode, component, dependedRootComponentGraph, depends, langSpec); - - if (resourceNode.getResourceHierarchy().getParent() == null) { - // For each root resource - // Update the main component for this component. - updateMainComponent(mainComponent, mainConstructor, componentNode, constructor, depends, langSpec); - } - - // Declare the fields to refer to reference resources. - declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); - - if (constructor.getParameters() == null || constructor.getParameters().size() == 0) { - component.removeMethod(constructor); - } else { - resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); + if (platformSpec.isMonolithic()) { + // For monolithic applications (components are tightly coupled and must be built together). + + // Declare the constructor. + MethodDeclaration constructor = declareConstructor(resourceNode, component, dependedRootComponentGraph, depends, langSpec); + + if (platformSpec.hasMain() && resourceNode.getResourceHierarchy().getParent() == null) { + // For each root resource + // Update the main component for this component. + updateMainComponent(mainComponent, mainConstructor, componentNode, constructor, depends, langSpec); + } + + // Declare the fields to refer to reference resources. + declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); + + if (constructor.getParameters() == null || constructor.getParameters().size() == 0) { + component.removeMethod(constructor); + } else { + resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); + } } // Declare the field to store the state in this resource.