Skip to content

Commit

Permalink
Merge pull request #283 from madushajg/tooling-backend-model-revamp
Browse files Browse the repository at this point in the history
[Architecture Model Gen] Revamp the architecture model
  • Loading branch information
madushajg authored Oct 11, 2023
2 parents cb11ed2 + 6917baa commit da37161
Show file tree
Hide file tree
Showing 37 changed files with 3,086 additions and 3,191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import io.ballerina.architecturemodelgenerator.core.diagnostics.ArchitectureModelDiagnostic;
import io.ballerina.architecturemodelgenerator.core.model.entity.Entity;
import io.ballerina.architecturemodelgenerator.core.model.functionentrypoint.FunctionEntryPoint;
import io.ballerina.architecturemodelgenerator.core.model.service.Connection;
import io.ballerina.architecturemodelgenerator.core.model.service.Service;
import io.ballerina.projects.Package;

import java.util.List;
import java.util.Map;
Expand All @@ -34,32 +34,47 @@
*/
public class ArchitectureModel {

private final String modelVersion;
private final String id;
private final String orgName;
private final String version;
private final PackageId packageId;
private final boolean hasCompilationErrors;
private final List<ArchitectureModelDiagnostic> diagnostics;
private final Map<String, Service> services;
private final Map<String, Entity> entities;
private final FunctionEntryPoint functionEntryPoint;

public ArchitectureModel(String version, PackageId packageId, List<ArchitectureModelDiagnostic> diagnostics,
Map<String, Service> services, Map<String, Entity> entities,
FunctionEntryPoint functionEntryPoint, boolean hasCompilationErrors) {
private final List<Connection> connections;

public ArchitectureModel(String modelVersion, String id, String orgName, String version,
List<ArchitectureModelDiagnostic> diagnostics, Map<String, Service> services,
Map<String, Entity> entities, FunctionEntryPoint functionEntryPoint,
boolean hasCompilationErrors, List<Connection> connections) {
this.modelVersion = modelVersion;
this.id = id;
this.orgName = orgName;
this.version = version;
this.packageId = packageId;
this.diagnostics = diagnostics;
this.services = services;
this.entities = entities;
this.functionEntryPoint = functionEntryPoint;
this.hasCompilationErrors = hasCompilationErrors;
this.connections = connections;
}

public String getVersion() {
return version;
public String getModelVersion() {
return modelVersion;
}

public String getId() {
return String.format("%s/%s:%s", orgName, id, version);
}

public String getOrgName() {
return orgName;
}

public PackageId getPackageId() {
return packageId;
public String getVersion() {
return version;
}

public List<ArchitectureModelDiagnostic> getDiagnostics() {
Expand All @@ -82,31 +97,7 @@ public boolean hasCompilationErrors() {
return hasCompilationErrors;
}

/**
* Represent current package information.
*/
public static class PackageId {

private final String name;
private final String org;
private final String version;

public PackageId(Package currentPackage) {
this.name = currentPackage.packageName().value();
this.org = currentPackage.packageOrg().value();
this.version = currentPackage.packageVersion().value().toString();
}

public String getName() {
return name;
}

public String getOrg() {
return org;
}

public String getVersion() {
return version;
}
public List<Connection> getConnections() {
return connections;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package io.ballerina.architecturemodelgenerator.core;

import io.ballerina.architecturemodelgenerator.core.ArchitectureModel.PackageId;
import io.ballerina.architecturemodelgenerator.core.diagnostics.ArchitectureModelDiagnostic;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticMessage;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticNode;
Expand All @@ -27,6 +26,7 @@
import io.ballerina.architecturemodelgenerator.core.generators.service.ServiceModelGenerator;
import io.ballerina.architecturemodelgenerator.core.model.entity.Entity;
import io.ballerina.architecturemodelgenerator.core.model.functionentrypoint.FunctionEntryPoint;
import io.ballerina.architecturemodelgenerator.core.model.service.Connection;
import io.ballerina.architecturemodelgenerator.core.model.service.Service;
import io.ballerina.projects.Package;
import io.ballerina.projects.PackageCompilation;
Expand Down Expand Up @@ -54,9 +54,12 @@ public ArchitectureModel constructComponentModel(Package currentPackage, Package
// todo: Change to TypeDefinition
Map<String, Entity> entities = new HashMap<>();
List<ArchitectureModelDiagnostic> diagnostics = new ArrayList<>();
List<Connection> allDependencies = new ArrayList<>();
AtomicReference<FunctionEntryPoint> functionEntryPoint = new AtomicReference<>();
PackageId packageId = new PackageId(currentPackage);
AtomicBoolean hasDiagnosticErrors = new AtomicBoolean(false);
String packageOrg = currentPackage.packageOrg().value();
String packageName = currentPackage.packageName().value();
String packageVersion = currentPackage.packageVersion().value().toString();

currentPackage.modules().forEach(module -> {
PackageCompilation currentPackageCompilation = packageCompilation == null ?
Expand All @@ -67,7 +70,9 @@ public ArchitectureModel constructComponentModel(Package currentPackage, Package

ServiceModelGenerator serviceModelGenerator = new ServiceModelGenerator(currentPackageCompilation, module);
try {
services.putAll(serviceModelGenerator.generate());
serviceModelGenerator.generate();
services.putAll(serviceModelGenerator.getServices());
allDependencies.addAll(serviceModelGenerator.getDependencies());
} catch (Exception e) {
DiagnosticMessage message = DiagnosticMessage.failedToGenerate(DiagnosticNode.SERVICES,
e.getMessage());
Expand All @@ -91,13 +96,15 @@ public ArchitectureModel constructComponentModel(Package currentPackage, Package

FunctionEntryPointModelGenerator functionEntryPointModelGenerator =
new FunctionEntryPointModelGenerator(currentPackageCompilation, module);
FunctionEntryPoint generatedFunctionEntryPoint = functionEntryPointModelGenerator.generate();
functionEntryPointModelGenerator.generate();
FunctionEntryPoint generatedFunctionEntryPoint = functionEntryPointModelGenerator.getFunctionEntryPoint();
if (generatedFunctionEntryPoint != null) {
functionEntryPoint.set(functionEntryPointModelGenerator.generate());
functionEntryPoint.set(generatedFunctionEntryPoint);
allDependencies.addAll(functionEntryPointModelGenerator.getDependencies());
}
});

return new ArchitectureModel(Constants.MODEL_VERSION, packageId, diagnostics, services, entities,
functionEntryPoint.get(), hasDiagnosticErrors.get());
return new ArchitectureModel(Constants.MODEL_VERSION, packageName, packageOrg, packageVersion, diagnostics,
services, entities, functionEntryPoint.get(), hasDiagnosticErrors.get(), allDependencies);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getValue() {
}
}

public static final String MODEL_VERSION = "0.3.1";
public static final String MODEL_VERSION = "0.4.0";
public static final String COLON = ":";
public static final String FORWARD_SLASH = "/";
public static final String SERVICE_ANNOTATION = "choreo:Service";
Expand All @@ -71,6 +71,7 @@ public String getValue() {
public static final String CONSTRAINT_ARRAY = "Array";
public static final String MIN_LENGTH_FIELD = "minLength";
public static final String MAX_LENGTH_FIELD = "maxLength";
public static final String DEFAULT_SERVICE_BASE_PATH = "_defaultBasePath";

// REST Methods
public static final String GET_KEYWORD = "get";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

package io.ballerina.architecturemodelgenerator.core.generators;

import io.ballerina.architecturemodelgenerator.core.ArchitectureModel;
import io.ballerina.architecturemodelgenerator.core.model.ElementLocation;
import io.ballerina.architecturemodelgenerator.core.model.SourceLocation;
import io.ballerina.architecturemodelgenerator.core.model.common.DisplayAnnotation;
import io.ballerina.compiler.api.SemanticModel;
import io.ballerina.compiler.api.symbols.Annotatable;
Expand Down Expand Up @@ -56,7 +55,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static io.ballerina.architecturemodelgenerator.core.Constants.CLIENT;
import static io.ballerina.architecturemodelgenerator.core.Constants.DISPLAY_ANNOTATION;
Expand All @@ -70,29 +68,29 @@
*/
public class GeneratorUtils {

public static ElementLocation getElementLocation(String filePath, LineRange lineRange) {
public static SourceLocation getSourceLocation(String filePath, LineRange lineRange) {

ElementLocation.LinePosition startPosition = ElementLocation.LinePosition.from(
SourceLocation.LinePosition startPosition = SourceLocation.LinePosition.from(
lineRange.startLine().line(), lineRange.startLine().offset());
ElementLocation.LinePosition endLinePosition = ElementLocation.LinePosition.from(
SourceLocation.LinePosition endLinePosition = SourceLocation.LinePosition.from(
lineRange.endLine().line(), lineRange.endLine().offset()
);
return ElementLocation.from(filePath, startPosition, endLinePosition);
return SourceLocation.from(filePath, startPosition, endLinePosition);

}

public static DisplayAnnotation getServiceAnnotation(NodeList<AnnotationNode> annotationNodes, String filePath) {

String id = UUID.randomUUID().toString();
String id = "";
String label = "";
ElementLocation elementLocation = null;
SourceLocation elementLocation = null;
for (AnnotationNode annotationNode : annotationNodes) {
String annotationName = annotationNode.annotReference().toString().trim();
if (!(annotationName.equals(DISPLAY_ANNOTATION) && annotationNode.annotValue().isPresent())) {
continue;
}
SeparatedNodeList<MappingFieldNode> fields = annotationNode.annotValue().get().fields();
elementLocation = getElementLocation(filePath, annotationNode.lineRange());
elementLocation = getSourceLocation(filePath, annotationNode.lineRange());
for (MappingFieldNode mappingFieldNode : fields) {
if (mappingFieldNode.kind() != SyntaxKind.SPECIFIC_FIELD) {
continue;
Expand Down Expand Up @@ -121,7 +119,7 @@ public static DisplayAnnotation getServiceAnnotation(Annotatable annotableSymbol

String id = null;
String label = "";
ElementLocation elementLocation = null;
SourceLocation elementLocation = null;

List<AnnotationSymbol> annotSymbols = annotableSymbol.annotations();
List<AnnotationAttachmentSymbol> annotAttachmentSymbols = annotableSymbol.annotAttachments();
Expand All @@ -131,7 +129,7 @@ public static DisplayAnnotation getServiceAnnotation(Annotatable annotableSymbol
AnnotationAttachmentSymbol annotAttachmentSymbol = annotAttachmentSymbols.get(i);
String annotName = annotSymbol.getName().orElse("");
elementLocation = annotAttachmentSymbol.getLocation().isPresent() ?
getElementLocation(filePath, annotAttachmentSymbol.getLocation().get().lineRange()) : null;
getSourceLocation(filePath, annotAttachmentSymbol.getLocation().get().lineRange()) : null;
if (!annotName.equals(DISPLAY_ANNOTATION) || annotAttachmentSymbol.attachmentValue().isEmpty() ||
!(annotAttachmentSymbol.attachmentValue().get().value() instanceof LinkedHashMap) ||
!annotAttachmentSymbol.isConstAnnotation()) {
Expand Down Expand Up @@ -220,9 +218,8 @@ public static List<String> getReferencedType(TypeSymbol typeSymbol, Package curr

private static String getReferenceEntityName(TypeReferenceTypeSymbol typeReferenceTypeSymbol,
Package currentPackage) {
ArchitectureModel.PackageId packageId = new ArchitectureModel.PackageId(currentPackage);
String currentPackageName = String.format
("%s/%s:%s", packageId.getOrg(), packageId.getName(), packageId.getVersion());
String currentPackageName = String.format("%s/%s:%s", currentPackage.packageOrg().value(),
currentPackage.packageName().value(), currentPackage.packageVersion().value());
String referenceType = typeReferenceTypeSymbol.signature();
if (typeReferenceTypeSymbol.getModule().isPresent() &&
!referenceType.split(":")[0].equals(currentPackageName.split(":")[0])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@

package io.ballerina.architecturemodelgenerator.core.generators.entity;

import io.ballerina.architecturemodelgenerator.core.ArchitectureModel.PackageId;
import io.ballerina.architecturemodelgenerator.core.Constants.CardinalityValue;
import io.ballerina.architecturemodelgenerator.core.diagnostics.ArchitectureModelDiagnostic;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticMessage;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticNode;
import io.ballerina.architecturemodelgenerator.core.generators.GeneratorUtils;
import io.ballerina.architecturemodelgenerator.core.generators.ModelGenerator;
import io.ballerina.architecturemodelgenerator.core.generators.entity.nodevisitors.TypeDefinitionNodeVisitor;
import io.ballerina.architecturemodelgenerator.core.model.ElementLocation;
import io.ballerina.architecturemodelgenerator.core.model.SourceLocation;
import io.ballerina.architecturemodelgenerator.core.model.entity.Association;
import io.ballerina.architecturemodelgenerator.core.model.entity.Attribute;
import io.ballerina.architecturemodelgenerator.core.model.entity.Entity;
Expand Down Expand Up @@ -57,6 +56,7 @@
import io.ballerina.compiler.syntax.tree.SyntaxTree;
import io.ballerina.projects.DocumentId;
import io.ballerina.projects.Module;
import io.ballerina.projects.Package;
import io.ballerina.projects.PackageCompilation;
import io.ballerina.tools.text.LineRange;

Expand Down Expand Up @@ -119,7 +119,7 @@ public Map<String, Entity> generate() {
}

private Entity getType(RecordTypeSymbol recordTypeSymbol, RecordTypeDescriptorNode recordNode,
String entityName, ElementLocation elementLocation, boolean isAnonymous) {
String entityName, SourceLocation elementLocation, boolean isAnonymous) {
List<Attribute> attributeList = new ArrayList<>();
List<String> inclusionList = new ArrayList<>();
Map<String, RecordFieldSymbol> recordFieldSymbolMap =
Expand Down Expand Up @@ -366,15 +366,16 @@ private List<String> getArrayAssociateCardinalities(Node recordFieldNode) {
*/
private String getEntityName(String moduleQualifiedName) {
// moduleQualifiedName is not correct when there is a dot in package name
PackageId packageId = new PackageId(getModule().packageInstance());
Package pkg = getModule().packageInstance();
String entityName;
String[] nameSpits = moduleQualifiedName.split(COLON);
if (packageId.getName().equals(nameSpits[0])) { // check whether the referenced type is from the same module
entityName = packageId.getOrg() + FORWARD_SLASH + packageId.getName() + COLON + packageId.getVersion() +
COLON + nameSpits[1];
if (pkg.packageName().value().equals(nameSpits[0])) {
// The referenced type is from the same module
entityName = pkg.packageOrg().value() + FORWARD_SLASH + pkg.packageName().value() + COLON +
pkg.packageVersion().value() + COLON + nameSpits[1];
} else {
entityName = packageId.getOrg() + FORWARD_SLASH + packageId.getName() + COLON + nameSpits[0] + COLON +
packageId.getVersion() + COLON + nameSpits[1];
entityName = pkg.packageOrg().value() + FORWARD_SLASH + pkg.packageName().value() + COLON + nameSpits[0] +
COLON + pkg.packageVersion().value() + COLON + nameSpits[1];
}
return entityName;
}
Expand Down Expand Up @@ -451,8 +452,8 @@ private List<Association> getAssociations(TypeSymbol fieldTypeDescriptor, Node r
return associations;
}

private ElementLocation getElementLocation(Symbol symbol) {
ElementLocation elementLocation = null;
private SourceLocation getElementLocation(Symbol symbol) {
SourceLocation elementLocation = null;
if (symbol.getLocation().isPresent()) {
LineRange typeLineRange = symbol.getLocation().get().lineRange();
String filePath;
Expand All @@ -461,7 +462,7 @@ private ElementLocation getElementLocation(Symbol symbol) {
} else {
filePath = getModuleRootPath().toString();
}
elementLocation = GeneratorUtils.getElementLocation(filePath, typeLineRange);
elementLocation = GeneratorUtils.getSourceLocation(filePath, typeLineRange);
}
return elementLocation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@
import io.ballerina.architecturemodelgenerator.core.generators.ModelGenerator;
import io.ballerina.architecturemodelgenerator.core.generators.entrypoint.nodevisitors.FunctionEntryPointVisitor;
import io.ballerina.architecturemodelgenerator.core.model.functionentrypoint.FunctionEntryPoint;
import io.ballerina.architecturemodelgenerator.core.model.service.Connection;
import io.ballerina.compiler.syntax.tree.SyntaxTree;
import io.ballerina.projects.DocumentId;
import io.ballerina.projects.Module;
import io.ballerina.projects.PackageCompilation;

import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;

/**
* Build entry point model based on a given Ballerina package.
Expand All @@ -35,12 +38,23 @@
*/
public class FunctionEntryPointModelGenerator extends ModelGenerator {

public FunctionEntryPoint functionEntryPoint = null;

private final List<Connection> dependencies = new LinkedList<>();

public FunctionEntryPoint getFunctionEntryPoint() {
return functionEntryPoint;
}

public List<Connection> getDependencies() {
return dependencies;
}

public FunctionEntryPointModelGenerator(PackageCompilation packageCompilation, Module module) {
super(packageCompilation, module);
}

public FunctionEntryPoint generate() {
FunctionEntryPoint entryPoint = null;
public void generate() {
for (DocumentId documentId :getModule().documentIds()) {
SyntaxTree syntaxTree = getModule().document(documentId).syntaxTree();
Path filePath = getModuleRootPath().resolve(syntaxTree.filePath());
Expand All @@ -49,9 +63,9 @@ public FunctionEntryPoint generate() {
syntaxTree.rootNode().accept(functionEntryPointVisitor);
FunctionEntryPoint entryPointVisited = functionEntryPointVisitor.getFunctionEntryPoint();
if (entryPointVisited != null) {
entryPoint = entryPointVisited;
functionEntryPoint = entryPointVisited;
dependencies.addAll(functionEntryPointVisitor.getDependencies());
}
}
return entryPoint;
}
}
Loading

0 comments on commit da37161

Please sign in to comment.