Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ public class HttpResponse {
private boolean editable = false;
private boolean advanced = false;

public HttpResponse(Value statusCode, Value body, Value mediaType, Value name, Value type, Value headers) {
public HttpResponse(Value statusCode, Value body, Value mediaType, Value name, Value type, Value headers,
boolean editable, boolean enabled) {
this.statusCode = statusCode;
this.body = body;
this.mediaType = mediaType;
this.name = name;
this.type = type;
this.headers = headers;
this.editable = editable;
this.enabled = enabled;
}

public HttpResponse(String type) {
Expand Down Expand Up @@ -156,6 +159,8 @@ public static class Builder {
private Value name;
private Value type;
private Value headers;
private boolean editable = false;
private boolean enabled = false;

public Builder statusCode(String statusCode, boolean editable) {
this.statusCode = createValue(statusCode, Value.FieldType.SINGLE_SELECT, editable);
Expand Down Expand Up @@ -188,6 +193,16 @@ public Builder headers(Object headers, boolean editable) {
return this;
}

public Builder editable(boolean editable) {
this.editable = editable;
return this;
}

public Builder enabled(boolean enabled) {
this.enabled = enabled;
return this;
}

public HttpResponse build() {
if (mediaType == null) {
this.mediaType = createValue("", Value.FieldType.EXPRESSION, true);
Expand All @@ -204,7 +219,7 @@ public HttpResponse build() {
if (body == null) {
this.body = createOptionalValue("", Value.FieldType.EXPRESSION, true);
}
return new HttpResponse(statusCode, body, mediaType, name, type, headers);
return new HttpResponse(statusCode, body, mediaType, name, type, headers, editable, enabled);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -513,8 +514,10 @@ public static Map<String, List<TextEdit>> processDatabindingForAdd(AddModelConte
new Value.ValueBuilder().value(typeName).build()
);

return createTypeDefinitionEdits(context.project(), typeName, baseType,
newDataBindingType, payloadFieldName, context.filePath(), context.workspaceManager());
Map<String, String> importsForTypeDef = dataBindingParam.getType().getImports();

return createTypeDefinitionEdits(context.project(), typeName, baseType, newDataBindingType, payloadFieldName,
context.filePath(), context.workspaceManager(), importsForTypeDef);
}

/**
Expand Down Expand Up @@ -625,27 +628,29 @@ public static Map<String, List<TextEdit>> processDatabindingUpdate(UpdateModelCo
Map<String, List<TextEdit>> typesEdits;
String typeName;

Map<String, String> importsForTypeDef = dataBindingParam.getType().getImports();
if (customWrapperTypeName != null && !customWrapperTypeName.equals(existingTypeName)) {
typeName = customWrapperTypeName;
if (existingTypeName != null) {
typesEdits = updateTypeDefinitionEdits(context, existingTypeName, baseType, newDataBindingType,
payloadFieldName, customWrapperTypeName);
payloadFieldName, customWrapperTypeName, importsForTypeDef);
} else {
typesEdits =
createTypeDefinitionEdits(context.project(), customWrapperTypeName, baseType,
newDataBindingType, payloadFieldName, context.filePath(), context.workspaceManager());
newDataBindingType, payloadFieldName, context.filePath(), context.workspaceManager(),
importsForTypeDef);
}
} else if (existingTypeName != null) {
typeName = existingTypeName;
typesEdits = updateTypeDefinitionEdits(context, existingTypeName, baseType, newDataBindingType,
payloadFieldName, null);
payloadFieldName, null, importsForTypeDef);
} else {
typeName =
generateNewDataBindTypeName(context.filePath(), context.workspaceManager(), context.semanticModel(),
context.functionNode(),
prefix);
typesEdits = createTypeDefinitionEdits(context.project(), typeName, baseType, newDataBindingType,
payloadFieldName, context.filePath(), context.workspaceManager());
payloadFieldName, context.filePath(), context.workspaceManager(), importsForTypeDef);
}

updateFunctionParameters(function, dataBindingParam, typeName, isArray);
Expand Down Expand Up @@ -885,10 +890,12 @@ private static String generateNewDataBindTypeName(String contextFilePath, Worksp
*
* @param baseType The base record type (e.g., "kafka:AnydataConsumerRecord")
* @param modulePartNode The module part node to check existing imports
* @param importsForTypeDef Map of imports needed for the type definition
* @return Set of import statements to add
*/
private static Set<String> extractRequiredImports(String baseType, ModulePartNode modulePartNode) {
Set<String> imports = new HashSet<>();
private static Set<String> extractRequiredImports(String baseType, ModulePartNode modulePartNode,
Map<String, String> importsForTypeDef) {
Set<String> imports = new LinkedHashSet<>();

if (baseType.contains(COLON)) {
String moduleName = baseType.substring(0, baseType.indexOf(COLON));
Expand All @@ -900,6 +907,17 @@ private static Set<String> extractRequiredImports(String baseType, ModulePartNod
}
}

if (importsForTypeDef != null) {
importsForTypeDef.values().forEach(moduleId -> {
String[] importParts = moduleId.split("/");
String orgName = importParts[0];
String moduleName = importParts[1].split(":")[0];
if (!importExists(modulePartNode, orgName, moduleName)) {
imports.add(getImportStmt(orgName, moduleName));
}
});
}

return imports;
}

Expand All @@ -915,14 +933,15 @@ private static Set<String> extractRequiredImports(String baseType, ModulePartNod
*/
private static TypeDefinitionEditContext prepareTypeDefinitionEditContext(Project project, String baseType,
String contextFilePath,
WorkspaceManager workspaceManager) {
WorkspaceManager workspaceManager,
Map<String, String> importsForTypeDef) {
Document typesDocument = getTypesDocument(contextFilePath, workspaceManager);
if (typesDocument == null || typesDocument.syntaxTree() == null) {
return null;
}

ModulePartNode modulePartNode = typesDocument.syntaxTree().rootNode();
Set<String> requiredImports = extractRequiredImports(baseType, modulePartNode);
Set<String> requiredImports = extractRequiredImports(baseType, modulePartNode, importsForTypeDef);

return new TypeDefinitionEditContext(typesDocument, modulePartNode, requiredImports, project);
}
Expand All @@ -935,15 +954,20 @@ private static TypeDefinitionEditContext prepareTypeDefinitionEditContext(Projec
* @param baseType The base record type (e.g., "kafka:AnydataConsumerRecord")
* @param dataBindingType The data binding field type (e.g., "Order")
* @param payloadFieldName The field name for the payload (e.g., "value" or "content")
* @param contextFilePath The context file path for locating types.bal
* @param workspaceManager The workspace manager for document retrieval
* @param importsForTypeDef Map of imports needed for the type definition
* @return Map of file paths to TextEdit lists
*/
private static Map<String, List<TextEdit>> createTypeDefinitionEdits(Project project, String typeName,
String baseType, String dataBindingType,
String payloadFieldName,
String contextFilePath,
WorkspaceManager workspaceManager) {
WorkspaceManager workspaceManager,
Map<String, String> importsForTypeDef) {
TypeDefinitionEditContext context =
prepareTypeDefinitionEditContext(project, baseType, contextFilePath, workspaceManager);
prepareTypeDefinitionEditContext(project, baseType, contextFilePath, workspaceManager,
importsForTypeDef);
if (context == null) {
return Map.of();
}
Expand Down Expand Up @@ -1172,17 +1196,21 @@ private static Path getFilePathForFile(String contextFilePath, WorkspaceManager
* @param newDataBindingType The new data binding field type (e.g., "Customer")
* @param payloadFieldName The field name for the payload (e.g., "value")
* @param newTypeName The new type name to rename to (optional, if null uses existingTypeName)
* @param importsForTypeDef Map of imports needed for the type definition
* @return Map of file paths to TextEdit lists
*/
private static Map<String, List<TextEdit>> updateTypeDefinitionEdits(UpdateModelContext context,
String existingTypeName,
String baseType,
String newDataBindingType,
String payloadFieldName,
String newTypeName) {
String newTypeName,
Map<String, String> importsForTypeDef) {

Project project = context.project() != null ? context.project() : context.document().module().project();
TypeDefinitionEditContext editContext =
prepareTypeDefinitionEditContext(project, baseType, context.filePath(), context.workspaceManager());
prepareTypeDefinitionEditContext(project, baseType, context.filePath(), context.workspaceManager(),
importsForTypeDef);
if (editContext == null) {
return Map.of();
}
Expand All @@ -1203,7 +1231,7 @@ private static Map<String, List<TextEdit>> updateTypeDefinitionEdits(UpdateModel
if (existingTypeDef == null) {
// Type doesn't exist, create it instead
return createTypeDefinitionEdits(context.project(), existingTypeName, baseType, newDataBindingType,
payloadFieldName, context.filePath(), context.workspaceManager());
payloadFieldName, context.filePath(), context.workspaceManager(), importsForTypeDef);
}

// Use newTypeName if provided for renaming, otherwise use existingTypeName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,13 @@ private static List<HttpResponse> getHttpResponses(TypeSymbol returnTypeSymbol,
TypeSymbol xmlType = typeBuilder.XML_TYPE.build();

anydataResponses.forEach(type -> {
HttpResponse.Builder builder = new HttpResponse.Builder()
HttpResponse response = new HttpResponse.Builder()
.statusCode(String.valueOf(defaultStatusCode), true)
.body(getTypeName(type, currentModuleName), true)
.mediaType(deriveMediaType(type, stringType, byteArrayType, xmlType), true);
HttpResponse response = builder.build();
response.setEnabled(true);
response.setEditable(true);
.mediaType(deriveMediaType(type, stringType, byteArrayType, xmlType), true)
.editable(true)
.enabled(true)
.build();
responses.add(response);
});

Expand Down Expand Up @@ -608,33 +608,34 @@ private static HttpResponse getHttpResponse(TypeSymbol statusCodeResponseType, S
String statusCode = getResponseCode(statusCodeResponseType, defaultStatusCode, semanticModel);
String signature = statusCodeResponseType.signature().trim();
if (signature.startsWith("record {") && signature.endsWith("}")) {
HttpResponse httpResponse = buildHttpResponseFromTypeSymbol(statusCodeResponseType, currentModuleName,
statusCode, null);
httpResponse.setEditable(true);
return httpResponse;
return buildHttpResponseFromTypeSymbol(statusCodeResponseType, currentModuleName, statusCode,
null, true);
}
String typeName = getTypeName(statusCodeResponseType, currentModuleName);
if (typeName.startsWith("http:")) {
String type = HTTP_CODES_DES.get(statusCode);
if (Objects.nonNull(type) && "http:%s".formatted(type).equals(typeName)) {
HttpResponse.Builder builder = new HttpResponse.Builder()
return new HttpResponse.Builder()
.statusCode(statusCode, true)
.type(typeName, true)
.body("", true)
.name("", true)
.headers("", true)
.mediaType("", true);
return builder.build();
.mediaType("", true)
.enabled(true)
.editable(true)
.build();
}
}

return buildHttpResponseFromTypeSymbol(statusCodeResponseType, currentModuleName, statusCode, typeName);
return buildHttpResponseFromTypeSymbol(statusCodeResponseType, currentModuleName, statusCode, typeName, false);
}

private static HttpResponse buildHttpResponseFromTypeSymbol(TypeSymbol statusCodeResponseType,
String currentModuleName,
String statusCode,
String typeName) {
String typeName,
boolean editable) {
List<Object> headers = new ArrayList<>();
String body = "anydata";
String mediaType = "";
Expand All @@ -659,14 +660,15 @@ private static HttpResponse buildHttpResponseFromTypeSymbol(TypeSymbol statusCod
}
}
}
HttpResponse.Builder builder = new HttpResponse.Builder()
.statusCode(statusCode, false)
.type(typeName, false)
.body(body, false)
.headers(headers, false)
.name("", false)
.mediaType(mediaType, false);
return builder.build();
return new HttpResponse.Builder()
.statusCode(statusCode, editable)
.type(typeName, editable)
.body(body, editable)
.headers(headers, editable)
.name("", editable)
.mediaType(mediaType, editable)
.editable(editable)
.build();
}

public static boolean isSubTypeOfHttpStatusCodeResponse(TypeSymbol typeSymbol, SemanticModel semanticModel) {
Expand Down
Loading
Loading