diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/model/Listener.java b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/model/Listener.java index 1cd579a6a7..4a16dd3aa4 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/model/Listener.java +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/model/Listener.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Objects; +import static io.ballerina.servicemodelgenerator.extension.util.Constants.PROP_KEY_LISTENER_TYPE; import static io.ballerina.servicemodelgenerator.extension.util.Constants.PROP_KEY_VARIABLE_NAME; import static io.ballerina.servicemodelgenerator.extension.util.Utils.getValueString; @@ -101,7 +102,7 @@ public String getListenerDeclaration() { StringBuilder declaration = new StringBuilder(); declaration.append("listener ") .append(listenerProtocol) - .append(":Listener ") + .append(":").append(getListenerTypeProperty().getValue()).append(" ") .append(getValueString(getVariableNameProperty())) .append(" = new "); @@ -119,7 +120,7 @@ public String getListenerDeclaration() { */ public String getInlineListenerExpression() { StringBuilder expression = new StringBuilder("new "); - expression.append(listenerProtocol).append(":Listener "); + expression.append(listenerProtocol).append(":").append(getListenerTypeProperty().getValue()).append(" "); appendListenerConstructorCall(expression); return expression.toString(); } @@ -163,6 +164,10 @@ public Value getVariableNameProperty() { return properties.get(PROP_KEY_VARIABLE_NAME); } + public Value getListenerTypeProperty() { + return properties.get(PROP_KEY_LISTENER_TYPE); + } + public Map getProperties() { return properties; } diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/Constants.java b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/Constants.java index 42f8ee2c0b..e38a80838f 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/Constants.java +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/Constants.java @@ -126,12 +126,14 @@ public class Constants { public static final String TYPE_HTTP_SERVICE_CONFIG = "http:ServiceConfig"; public static final String PROP_KEY_VARIABLE_NAME = "variableNameKey"; + public static final String PROP_KEY_LISTENER_TYPE = "listenerType"; public static final String PROP_KEY_LISTENER = "listener"; public static final String PROP_KEY_SERVICE_TYPE = "serviceType"; public static final String PROP_KEY_BASE_PATH = "basePath"; public static final String PROP_KEY_STRING_LITERAL = "stringLiteral"; public static final String PROP_READONLY_METADATA_KEY = "readOnlyMetadata"; public static final String PROP_KEY_DEFAULT_LISTENER = "defaultListener"; + public static final String DEFAULT_LISTENER_TYPE = "Listener"; // protocol listeners public static final String HTTP_DEFAULT_LISTENER_EXPR = "http:getDefaultListener()"; diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/ListenerUtil.java b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/ListenerUtil.java index 6223273bf8..c5849d3e39 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/ListenerUtil.java +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/main/java/io/ballerina/servicemodelgenerator/extension/util/ListenerUtil.java @@ -79,6 +79,7 @@ import static io.ballerina.servicemodelgenerator.extension.util.Constants.ASB_DEFAULT_LISTENER_EXPR; import static io.ballerina.servicemodelgenerator.extension.util.Constants.DEFAULT_LISTENER_ITEM_LABEL; import static io.ballerina.servicemodelgenerator.extension.util.Constants.DEFAULT_LISTENER_VAR_NAME; +import static io.ballerina.servicemodelgenerator.extension.util.Constants.DEFAULT_LISTENER_TYPE; import static io.ballerina.servicemodelgenerator.extension.util.Constants.FILE; import static io.ballerina.servicemodelgenerator.extension.util.Constants.FILE_DEFAULT_LISTENER_EXPR; import static io.ballerina.servicemodelgenerator.extension.util.Constants.FTP; @@ -95,6 +96,7 @@ import static io.ballerina.servicemodelgenerator.extension.util.Constants.MQTT_DEFAULT_LISTENER_EXPR; import static io.ballerina.servicemodelgenerator.extension.util.Constants.NEW_LINE; import static io.ballerina.servicemodelgenerator.extension.util.Constants.PROP_KEY_DEFAULT_LISTENER; +import static io.ballerina.servicemodelgenerator.extension.util.Constants.PROP_KEY_LISTENER_TYPE; import static io.ballerina.servicemodelgenerator.extension.util.Constants.PROP_KEY_VARIABLE_NAME; import static io.ballerina.servicemodelgenerator.extension.util.Constants.RABBITMQ; import static io.ballerina.servicemodelgenerator.extension.util.Constants.RABBITMQ_DEFAULT_LISTENER_EXPR; @@ -317,6 +319,7 @@ public static Listener createBaseListenerModel(FunctionData functionData) { .setProperties(properties); properties.put(PROP_KEY_VARIABLE_NAME, nameProperty()); + properties.put(PROP_KEY_LISTENER_TYPE, listenerTypeProperty()); return listenerBuilder.build(); } @@ -328,9 +331,9 @@ private static String getListenerProtocol(String packageName) { public static Optional getListenerModelByName(Codedata codedata, SemanticModel semanticModel, ModuleInfo moduleInfo) { - + String listenerType = codedata.getType() == null ? "Listener" : codedata.getType(); FunctionDataBuilder functionDataBuilder = new FunctionDataBuilder() - .parentSymbolType("Listener") + .parentSymbolType(listenerType) .name("init") .moduleInfo(new ModuleInfo(codedata.getOrgName(), codedata.getPackageName(), codedata.getModuleName(), codedata.getVersion())) @@ -340,6 +343,7 @@ public static Optional getListenerModelByName(Codedata codedata, Seman FunctionData functionData = functionDataBuilder.build(); Listener listener = createBaseListenerModel(functionData); + listener.getListenerTypeProperty().setValue(listenerType); setParameterProperties(functionData, listener.getProperties(), semanticModel, moduleInfo); return Optional.of(listener); } @@ -430,11 +434,12 @@ private static Listener processListenerDeclaration(ListenerDeclarationNode liste return createHttpDefaultListenerModel(orgName, listenerNode).get(); } - Optional symbol = semanticModel.symbol(listenerNode.typeDescriptor().orElse(null)); - if (symbol.isEmpty() || !(symbol.get() instanceof TypeSymbol typeSymbol) - || !(CommonUtils.getRawType(typeSymbol) instanceof ClassSymbol classSymbol)) { + Optional symbol = semanticModel.symbol(listenerNode.variableName()); + if (symbol.isEmpty() || !(symbol.get() instanceof VariableSymbol variableSymbol) + || !(CommonUtils.getRawType(variableSymbol.typeDescriptor()) instanceof ClassSymbol classSymbol)) { return null; } + TypeSymbol typeSymbol = variableSymbol.typeDescriptor(); Node initializer = listenerNode.initializer(); NewExpressionNode newExpressionNode; @@ -444,8 +449,11 @@ private static Listener processListenerDeclaration(ListenerDeclarationNode liste newExpressionNode = (NewExpressionNode) initializer; } - return createListenerModelFromNewExpressionNode(listenerNode.lineRange(), newExpressionNode, semanticModel, + Listener listener = createListenerModelFromNewExpressionNode(listenerNode.lineRange(), newExpressionNode, + semanticModel, classSymbol, moduleInfo); + listener.getListenerTypeProperty().setValue(typeSymbol.getName().orElse(DEFAULT_LISTENER_TYPE)); + return listener; } private static void processListenerName(Listener listener, ListenerDeclarationNode listenerDeclarationNode) { @@ -473,6 +481,7 @@ private static Optional createHttpDefaultListenerModel(String org, Lis Listener listener = createBaseListenerModel(functionData); listener.getProperties().put(PROP_KEY_DEFAULT_LISTENER, getHttpDefaultListenerValue()); + listener.getListenerTypeProperty().setValue(DEFAULT_LISTENER_TYPE); listener.setCodedata(new Codedata(listenerNode.lineRange())); return Optional.of(listener); @@ -497,9 +506,18 @@ private static Listener processExplicitNewExpression(ExplicitNewExpressionNode n Listener listenerModel = createListenerModelFromNewExpressionNode(newExpressionNode.lineRange(), newExpressionNode, semanticModel, classSymbol, moduleInfo); listenerModel.getProperties().remove(PROP_KEY_VARIABLE_NAME); + listenerModel.getListenerTypeProperty().setValue(getListenerTypeName(newExpressionNode)); return listenerModel; } + private static String getListenerTypeName(ExplicitNewExpressionNode explicitNewExpressionNode) { + String typeName = explicitNewExpressionNode.typeDescriptor().toSourceCode().trim(); + if (typeName.contains(":")) { + return typeName.substring(typeName.lastIndexOf(":") + 1); + } + return typeName; + } + /** * Creates a listener model from a syntax tree node and class symbol with complete property analysis. This method * constructs a comprehensive listener model by analyzing the listener's initialization arguments, setting up all @@ -614,6 +632,14 @@ public static Value nameProperty() { return valueBuilder.build(); } + public static Value listenerTypeProperty() { + return new Value.ValueBuilder() + .setMetadata(new MetaData("Listener Type", "The type of the listener")) + .value("") + .types(List.of(PropertyType.types(Value.FieldType.TYPE))) + .build(); + } + /** * Builds a CHOICE property for listener configuration with options to use an existing listener or create a new * one. diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/graphql_listener_model.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/graphql_listener_model.json index adb87a06f9..61c11be411 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/graphql_listener_model.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/graphql_listener_model.json @@ -4,7 +4,8 @@ "orgName": "ballerina", "packageName": "graphql", "moduleName": "graphql", - "version": "1.17.0" + "version": "1.17.0", + "type": "Listener" }, "filePath": "sample1/main.bal", "response": { @@ -40,6 +41,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "listenTo": { "metadata": { "label": "Listen To", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/http_listener_model.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/http_listener_model.json index 37a92dfc1b..8f0b0e039e 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/http_listener_model.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/http_listener_model.json @@ -4,7 +4,8 @@ "orgName": "ballerina", "packageName": "http", "moduleName": "http", - "version": "2.15.3" + "version": "2.15.3", + "type": "Listener" }, "filePath": "sample1/main.bal", "response": { @@ -40,6 +41,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/kafka_listener_model.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/kafka_listener_model.json index aed45f2b83..0f6a9335a8 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/kafka_listener_model.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/get_listener_model/config/kafka_listener_model.json @@ -4,7 +4,8 @@ "orgName": "ballerinax", "packageName": "kafka", "moduleName": "kafka", - "version": "4.6.0" + "version": "4.6.0", + "type": "Listener" }, "filePath": "sample1/main.bal", "response": { @@ -40,6 +41,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "bootstrapServers": { "metadata": { "label": "Bootstrap Servers", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_1.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_1.json index a8a9a9af29..4f9ae74a25 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_1.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_1.json @@ -52,6 +52,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_2.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_2.json index 18e8af0131..ed4532b89a 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_2.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_2.json @@ -52,6 +52,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_3.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_3.json index 9f578d5f04..6882a5e116 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_3.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_3.json @@ -52,6 +52,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_4.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_4.json index 797d971dd8..b873bc4b04 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_4.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_4.json @@ -52,6 +52,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_5.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_5.json index e8419216f8..7b08c18e10 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_5.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/listener_from_source/config/listener_from_source_5.json @@ -22,6 +22,23 @@ "listenerProtocol": "http", "icon": "https://bcentral-packageicons.azureedge.net/images/ballerina_http_2.15.4.png", "properties": { + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port", diff --git a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/update_listener/config/update_http_listener.json b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/update_listener/config/update_http_listener.json index de0617fae8..b0a5e0128d 100644 --- a/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/update_listener/config/update_http_listener.json +++ b/service-model-generator/modules/service-model-generator-ls-extension/src/test/resources/update_listener/config/update_http_listener.json @@ -43,6 +43,23 @@ "optional": false, "advanced": false }, + "listenerType": { + "metadata": { + "label": "Listener Type", + "description": "The type of the listener" + }, + "value": "Listener", + "types": [ + { + "fieldType": "TYPE", + "selected": true + } + ], + "enabled": false, + "editable": false, + "optional": false, + "advanced": false + }, "port": { "metadata": { "label": "Port",