Skip to content

Commit

Permalink
Merge pull request #309 from sachiniSam/sequence-model-generator
Browse files Browse the repository at this point in the history
Add Sequence diagram model generator LS extension
  • Loading branch information
sachiniSam committed Dec 4, 2023
2 parents 05c0953 + 80bf631 commit d3f3484
Show file tree
Hide file tree
Showing 65 changed files with 6,283 additions and 0 deletions.
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,14 @@ if (moduleVersion.indexOf('-') != -1) {
}
def artifactLibParent = file("$project.rootDir/build/architecture-model-generator/")
def artifactGraphqlLibParent = file("$project.rootDir/build/graphql-model-generator/")
def artifactSequenceLibParent = file("$project.rootDir/build/sequence-diagram-model-generator/")
def targetArchModelGeneratorCore = file("$project.rootDir/architecture-model-generator/modules/architecture-model-generator-core/build/libs/architecture-model-generator-core-${project.version}.jar")
def targetArchModelGeneratorPlugin = file("$project.rootDir/architecture-model-generator/modules/architecture-model-generator-plugin/build/libs/architecture-model-generator-plugin-${project.version}.jar")
def targetArchModelGeneratorLSExt = file("$project.rootDir/architecture-model-generator/modules/architecture-model-generator-ls-extension/build/libs/architecture-model-generator-ls-extension-${project.version}.jar")
def targetGraphqlModelGeneratorCore = file("$project.rootDir/graphql-model-generator/modules/graphql-model-generator-core/build/libs/graphql-model-generator-core-${project.version}.jar")
def targetGraphqlModelGeneratorLSExt = file("$project.rootDir/graphql-model-generator/modules/graphql-model-generator-ls-extension/build/libs/graphql-model-generator-ls-extension-${project.version}.jar")
def targetSequenceDiagramGeneratorCore = file("$project.rootDir/sequence-diagram-generator/modules/sequence-diagram-model-generator-core/build/libs/sequence-diagram-generator-core-${project.version}.jar")
def targetSequenceDiagramGeneratorLSExt = file("$project.rootDir/sequence-diagram-generator/modules/sequence-diagram-model-generator-ls-extension/build/libs/sequence-diagram-generator-ls-extension-${project.version}.jar")

task copyArtifactZip {
dependsOn(":architecture-model-generator:architecture-model-generator-core:build")
Expand All @@ -109,6 +112,8 @@ task copyArtifactZip {
dependsOn(":graphql-model-generator:graphql-model-generator-core:build")
dependsOn(":graphql-model-generator:graphql-model-generator-ls-extension:build")
dependsOn(":generatePomFileForMavenJavaPublication")
dependsOn(":sequence-diagram-model-generator:sequence-diagram-model-generator-core:build")
dependsOn(":sequence-diagram-model-generator:sequence-diagram-model-generator-ls-extension:build")
inputs.dir file(project.rootDir)
doLast {
copy {
Expand All @@ -131,6 +136,14 @@ task copyArtifactZip {
from targetGraphqlModelGeneratorLSExt
into file("$artifactGraphqlLibParent/ls-libs")
}
copy {
from targetSequenceDiagramGeneratorCore
into file("$artifactSequenceLibParent/libs")
}
copy {
from targetSequenceDiagramGeneratorLSExt
into file("$artifactSequenceLibParent/ls-libs")
}
}
outputs.dir artifactLibParent
doNotTrackState("build needs to run every time")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

apply from: "$rootDir/gradle/javaProject.gradle"

description = 'Model generator core for sequence diagram generation'

configurations.all {
resolutionStrategy.preferProjectModules()
}

configurations {
balTools
}

dependencies {
implementation "org.ballerinalang:ballerina-lang:${ballerinaLangVersion}"
implementation "org.ballerinalang:ballerina-parser:${ballerinaLangVersion}"
implementation "org.ballerinalang:ballerina-tools-api:${ballerinaLangVersion}"

balTools ("org.ballerinalang:jballerina-tools:${ballerinaLangVersion}") {
transitive = false
}
}

def balDistribution = file("$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}")
task jBallerinaPack() {
doLast {
configurations.balTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->
copy {
from project.zipTree(artifact.getFile())
into new File(project.buildDir, "extracted-distribution/")
}
}
}
outputs.dir balDistribution
}

task unpackStdLibs() {
dependsOn(jBallerinaPack)
doLast {
configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->
copy {
from project.zipTree(artifact.getFile())
into new File("${project.buildDir}/extracted-stdlibs/" + artifact.name + "-zip")
}
}
}
}

task copyStdlibs() {
dependsOn(unpackStdLibs)
doLast {
/* Standard Libraries */
configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->
def artifactExtractedPath = "${project.buildDir}/extracted-stdlibs/" + artifact.name + '-zip'
project.copy {
def ballerinaDist = "build/extracted-distribution/jballerina-tools-${project.ballerinaLangVersion}"
into ballerinaDist
into('repo/bala') {
from "${artifactExtractedPath}/bala"
}
into('repo/cache') {
from "${artifactExtractedPath}/cache"
}
}
}
}
}

ext.moduleName = 'io.ballerina.sequencemodelgenerator.core'

compileJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
]
classpath = files()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.sequencemodelgenerator.core;

/**
* Constants used for Sequence Diagram model generation errors.
*
* @since 2201.8.5
*/
public class Constants {
public static final String EMPTY_SEMANTIC_MODEL_MSG =
"Provided Ballerina file path doesn't contain a valid semantic model";
public static final String INVALID_NODE_MSG = "Couldn't find a valid node at the given position";
public static final String ISSUE_IN_VISITING_ROOT_NODE = "Error occurred while visiting root node : %s";
public static final String UNABLE_TO_FIND_SYMBOL = "Unable to find symbol for the given node";
public static final String ISSUE_IN_MODEL_GENERATION =
"Error occurred while visiting nodes to generate the model : %s";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.sequencemodelgenerator.core;

import io.ballerina.compiler.api.SemanticModel;
import io.ballerina.compiler.syntax.tree.NonTerminalNode;
import io.ballerina.compiler.syntax.tree.SyntaxTree;
import io.ballerina.projects.Document;
import io.ballerina.projects.DocumentId;
import io.ballerina.projects.Module;
import io.ballerina.projects.ModuleId;
import io.ballerina.projects.Package;
import io.ballerina.projects.Project;
import io.ballerina.projects.ProjectKind;
import io.ballerina.sequencemodelgenerator.core.exception.SequenceModelGenerationException;
import io.ballerina.sequencemodelgenerator.core.model.SequenceModel;
import io.ballerina.sequencemodelgenerator.core.visitors.ModuleLevelConnectorVisitor;
import io.ballerina.sequencemodelgenerator.core.visitors.RootNodeVisitor;
import io.ballerina.sequencemodelgenerator.core.visitors.VisitorContext;
import io.ballerina.tools.text.LineRange;

import java.nio.file.Path;

import static io.ballerina.sequencemodelgenerator.core.Constants.INVALID_NODE_MSG;
import static io.ballerina.sequencemodelgenerator.core.utils.CommonUtils.findNode;

/**
* Represents the root model generator for sequence diagram.
*
* @since 2201.8.5
*/
public class ModelGenerator {
public SequenceModel getSequenceDiagramModel(Project project, LineRange position, SemanticModel semanticModel)
throws SequenceModelGenerationException {
Package packageName = project.currentPackage();
DocumentId docId;
Document doc;
if (project.kind().equals(ProjectKind.BUILD_PROJECT)) {
Path filePath = Path.of(position.fileName());
docId = project.documentId(filePath);
ModuleId moduleId = docId.moduleId();
doc = project.currentPackage().module(moduleId).document(docId);
} else {
Module currentModule = packageName.getDefaultModule();
docId = currentModule.documentIds().iterator().next();
doc = currentModule.document(docId);
}

SyntaxTree syntaxTree = doc.syntaxTree();
NonTerminalNode node = findNode(syntaxTree, position);
if (node.isMissing()) {
throw new SequenceModelGenerationException(INVALID_NODE_MSG);
}

VisitorContext visitorContext = new VisitorContext();
RootNodeVisitor workerNodeVisitor = new RootNodeVisitor(semanticModel, packageName, visitorContext);
node.accept(workerNodeVisitor);
if (workerNodeVisitor.getModelGenerationException() != null) {
throw workerNodeVisitor.getModelGenerationException();
}
// get the module level connectors without interactions and update the participant list
ModuleLevelConnectorVisitor moduleLevelConnectorVisitor = new ModuleLevelConnectorVisitor(semanticModel,
workerNodeVisitor.getVisitorContext().getParticipants());
syntaxTree.rootNode().accept(moduleLevelConnectorVisitor);
return new SequenceModel(moduleLevelConnectorVisitor.getParticipants(), position);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.sequencemodelgenerator.core.exception;

/**
* Represents the exception class for Sequence diagram model generator.
*
* @since 2201.8.5
*/
public class SequenceModelGenerationException extends Exception {
public SequenceModelGenerationException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.sequencemodelgenerator.core.model;

/**
* Constants used in the sequence diagram model.
*
* @since 2201.8.5
*/
public class Constants {
public static final String PARTICIPANT = "Participant";
public static final String INTERACTION = "Interaction";
public static final String SQ_COMMENT = "@sq-comment:";
public static final String SQ_IGNORE = "@sq-ignore";


/**
* Enum for participant kind.
*/
public enum ParticipantKind {
WORKER,
ENDPOINT,
}

/**
* Enum for endpoint action types.
*/
public enum ActionType {
RESOURCE_ACTION,
REMOTE_ACTION,
}

/**
* Enum for interaction types.
*/
public enum InteractionType {
ENDPOINT_INTERACTION,
FUNCTION_INTERACTION,
METHOD_INTERACTION,
RETURN_ACTION,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.ballerina.sequencemodelgenerator.core.model;

import io.ballerina.tools.text.LineRange;
/**
* Represent an element in the sequence diagram model.
*
* @since 2201.8.5
*/
public class DElement extends DNode {
private DElementBody elementBody;

public DElement(String kind, boolean isHidden, LineRange location) {
super(kind, isHidden, location);
}

public DElementBody getElementBody() {
return elementBody;
}

public void addChildDiagramElements(DNode dNode) {
if (this.elementBody == null) {
this.elementBody = new DElementBody(this.getKind() + "Body", this.isHidden(), this.getLocation());
this.elementBody.addChildDiagramElement(dNode);
} else {
this.elementBody.addChildDiagramElement(dNode);
}
}
}
Loading

0 comments on commit d3f3484

Please sign in to comment.