Skip to content

Commit

Permalink
Merge pull request #1209 from lnash94/project_api
Browse files Browse the repository at this point in the history
Use Project API for Ballerina to OpenAPI code generation
  • Loading branch information
NipunaRanasinghe committed Apr 26, 2023
2 parents 8bc6242 + ff59d68 commit 1eb8448
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 100 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version=1.6.0-SNAPSHOT
ballerinaLangVersion=2201.5.0
testngVersion=7.4.0
slf4jVersion=1.7.30
org.gradle.jvmargs=-Xmx4096M
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
commonsLang3Version=3.9
commonsIoVersion=2.6
netLingalaZip4jVersion=2.8.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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.openapi.converter.model;

import io.ballerina.compiler.api.SemanticModel;
import io.ballerina.compiler.syntax.tree.ServiceDeclarationNode;
import io.ballerina.projects.Project;

import java.nio.file.Path;

/**
* This {@code OASGenerationMetaInfo} contains details related to openAPI specification.
*
* @since 1.6.0
*/
public class OASGenerationMetaInfo {

private final String openApiFileName;
private final Path ballerinaFilePath;
private final SemanticModel semanticModel;
private final ServiceDeclarationNode serviceDeclarationNode;
private final Project project;

public OASGenerationMetaInfo(OASGenerationMetaInfoBuilder builder) {
this.openApiFileName = builder.openApiFileName;
this.ballerinaFilePath = builder.ballerinaFilePath;
this.semanticModel = builder.semanticModel;
this.serviceDeclarationNode = builder.serviceDeclarationNode;
this.project = builder.project;
}

public String getOpenApiFileName() {
return openApiFileName;
}

public Path getBallerinaFilePath() {
return ballerinaFilePath;
}

public SemanticModel getSemanticModel() {
return semanticModel;
}

public ServiceDeclarationNode getServiceDeclarationNode() {
return serviceDeclarationNode;
}

public Project getProject() {
return project;
}

/**
* This method is used to create a new {@link OASGenerationMetaInfoBuilder} instance.
*/
public static class OASGenerationMetaInfoBuilder {

private String openApiFileName;
private Path ballerinaFilePath;
private SemanticModel semanticModel;
private ServiceDeclarationNode serviceDeclarationNode;
private Project project;

public OASGenerationMetaInfoBuilder setBallerinaFilePath(Path ballerinaFilePath) {
this.ballerinaFilePath = ballerinaFilePath;
return this;
}

public OASGenerationMetaInfoBuilder setSemanticModel(SemanticModel semanticModel) {
this.semanticModel = semanticModel;
return this;
}

public OASGenerationMetaInfoBuilder setServiceDeclarationNode(ServiceDeclarationNode serviceDeclarationNode) {
this.serviceDeclarationNode = serviceDeclarationNode;
return this;
}

public OASGenerationMetaInfoBuilder setOpenApiFileName(String openApiFileName) {
this.openApiFileName = openApiFileName;
return this;
}

public Project setProject(Project project) {
this.project = project;
return project;
}

public OASGenerationMetaInfo build() {
return new OASGenerationMetaInfo(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved.
*
* WSO2 Inc. 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.openapi.converter.service;

import io.ballerina.compiler.syntax.tree.ListenerDeclarationNode;
import io.ballerina.compiler.syntax.tree.NodeVisitor;
import io.ballerina.compiler.syntax.tree.TypeDefinitionNode;

import java.util.LinkedList;
import java.util.List;

/**
* Visitor to get the TypeDefinitionNode and ListenerDeclarationNodes.
*
* @since 1.6.0
*/
public class ModuleMemberVisitor extends NodeVisitor {

LinkedList<TypeDefinitionNode> typeDefinitionNodes = new LinkedList<>();
LinkedList<ListenerDeclarationNode> listenerDeclarationNodes = new LinkedList<>();

@Override
public void visit(TypeDefinitionNode typeDefinitionNode) {
typeDefinitionNodes.add(typeDefinitionNode);
}

@Override
public void visit(ListenerDeclarationNode listenerDeclarationNode) {
listenerDeclarationNodes.add(listenerDeclarationNode);
}

public List<TypeDefinitionNode> getTypeDefinitionNodes() {
return typeDefinitionNodes;
}

public List<ListenerDeclarationNode> getListenerDeclarationNodes() {
return listenerDeclarationNodes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.ballerina.compiler.syntax.tree.Node;
import io.ballerina.compiler.syntax.tree.NodeList;
import io.ballerina.compiler.syntax.tree.ParenthesizedArgList;
import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode;
import io.ballerina.compiler.syntax.tree.SeparatedNodeList;
import io.ballerina.compiler.syntax.tree.ServiceDeclarationNode;
import io.ballerina.compiler.syntax.tree.SpecificFieldNode;
Expand All @@ -44,6 +45,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;

Expand All @@ -64,22 +66,18 @@ public class OpenAPIEndpointMapper {
* @param service service node with bound endpoints
* @return openapi definition with Server information
*/
public OpenAPI getServers(OpenAPI openAPI, List<ListenerDeclarationNode> endpoints,
public OpenAPI getServers(OpenAPI openAPI, LinkedHashSet<ListenerDeclarationNode> endpoints,
ServiceDeclarationNode service) {
openAPI = extractServerForExpressionNode(openAPI, service.expressions(), service);
List<Server> servers = openAPI.getServers();
//Handle ImplicitNewExpressionNode in listener
if (!endpoints.isEmpty()) {
for (ListenerDeclarationNode ep : endpoints) {
SeparatedNodeList<ExpressionNode> exprNodes = service.expressions();
for (ExpressionNode node : exprNodes) {
if (node.toString().trim().equals(ep.variableName().text().trim())) {
String serviceBasePath = getServiceBasePath(service);
Server server = extractServer(ep, serviceBasePath);
servers.add(server);
}
updateServerDetails(service, servers, ep, node);
}
}

}
if (servers.size() > 1) {
Server mainServer = addEnumValues(servers);
Expand All @@ -88,6 +86,27 @@ public OpenAPI getServers(OpenAPI openAPI, List<ListenerDeclarationNode> endpoin
return openAPI;
}

/**
* This util is for extracting the server details from endpoints and update server list.
*/
private void updateServerDetails(ServiceDeclarationNode service, List<Server> servers,
ListenerDeclarationNode endPoint, ExpressionNode expNode) {

if (expNode instanceof QualifiedNameReferenceNode) {
//Handle QualifiedNameReferenceNode in listener
QualifiedNameReferenceNode refNode = (QualifiedNameReferenceNode) expNode;
if (refNode.identifier().text().trim().equals(endPoint.variableName().text().trim())) {
String serviceBasePath = getServiceBasePath(service);
Server server = extractServer(endPoint, serviceBasePath);
servers.add(server);
}
} else if (expNode.toString().trim().equals(endPoint.variableName().text().trim())) {
String serviceBasePath = getServiceBasePath(service);
Server server = extractServer(endPoint, serviceBasePath);
servers.add(server);
}
}

private Server addEnumValues(List<Server> servers) {

Server mainServer = servers.get(0);
Expand Down Expand Up @@ -136,7 +155,7 @@ private Optional<ParenthesizedArgList> extractListenerNodeType(Node expression2)
return list;
}

// Function for handle both ExplicitNewExpressionNode and ImplicitNewExpressionNode in listener.
// Function to handle ExplicitNewExpressionNode in listener.
private OpenAPI extractServerForExpressionNode(OpenAPI openAPI, SeparatedNodeList<ExpressionNode> bTypeExplicit,
ServiceDeclarationNode service) {
String serviceBasePath = getServiceBasePath(service);
Expand All @@ -148,11 +167,6 @@ private OpenAPI extractServerForExpressionNode(OpenAPI openAPI, SeparatedNodeLis
list = Optional.ofNullable(explicit.parenthesizedArgList());
Server server = generateServer(serviceBasePath, list);
servers.add(server);
} else if (expressionNode.kind().equals(SyntaxKind.IMPLICIT_NEW_EXPRESSION)) {
ImplicitNewExpressionNode implicit = (ImplicitNewExpressionNode) expressionNode;
list = implicit.parenthesizedArgList();
Server server = generateServer(serviceBasePath, list);
servers.add(server);
}
}
openAPI.setServers(servers);
Expand Down
Loading

0 comments on commit 1eb8448

Please sign in to comment.