Skip to content
Open
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
4 changes: 2 additions & 2 deletions examples/spec/twilio_flex_v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ paths:
description: OK
security:
- accountSid_authToken: [ ]
post:
operationId: UpdateCredentialAws
patch:
operationId: PatchCredentialAws
parameters:
- in: path
name: Sid
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/twilio/oai/common/EnumConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public enum OpenApiEnumType {
FORM_PARAM_REF,
FORM_PARAM_LIST_REF,
}

public enum ModelType {
SINGLE,
LIST
Expand All @@ -164,7 +164,8 @@ public enum SupportedOperation {
X_LIST("x-list-operation"),
X_UPDATE("x-update-operation"),
X_FETCH("x-fetch-operation"),
X_DELETE("x-delete-operation");
X_DELETE("x-delete-operation"),
X_PATCH("x-patch-operation");

private final String value;
}
Expand Down
29 changes: 24 additions & 5 deletions src/main/java/com/twilio/oai/java/JavaTemplateUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.twilio.oai.TwilioJavaGeneratorModern;
import com.twilio.oai.common.EnumConstants;
import com.twilio.oai.common.EnumConstants.SupportedOperation;
import com.twilio.oai.java.constants.MustacheConstants;
import org.openapitools.codegen.CodegenOperation;

Expand All @@ -12,9 +13,9 @@
import static com.twilio.oai.java.constants.MustacheConstants.ActionType;

/*
The JavaTemplateFile class is responsible for managing template mappings for Java code generation.
It defines mappings between operation IDs (starting strings)
and corresponding template files (mustache files) along with their generated file extensions.
The JavaTemplateFile class is responsible for managing template mappings for Java code generation.
It defines mappings between operation IDs (starting strings)
and corresponding template files (mustache files) along with their generated file extensions.
Example:
Key: Represents the starting string of the operationId (e.g., "create", "fetch").
Value: Represents a mapping between the mustache template file and the generated file extension using AbstractMap.SimpleEntry.
Expand All @@ -34,7 +35,8 @@ public JavaTemplateUpdater() {
"fetch", new AbstractMap.SimpleEntry<>("fetcher.mustache", "Fetcher.java"),
"delete", new AbstractMap.SimpleEntry<>("deleter.mustache", "Deleter.java"),
"list", new AbstractMap.SimpleEntry<>("reader.mustache", "Reader.java"),
"update", new AbstractMap.SimpleEntry<>("updater.mustache", "Updater.java")
"update", new AbstractMap.SimpleEntry<>("updater.mustache", "Updater.java"),
"patch", new AbstractMap.SimpleEntry<>("patcher.mustache", "Patcher.java")
);
apiTemplate = Map.of(
API_TEMPLATE, new AbstractMap.SimpleEntry<>("api.mustache", ".java")
Expand All @@ -61,6 +63,8 @@ public void addApiTemplate(TwilioJavaGeneratorModern twilioJavaGenerator, java.u
Delete.add(twilioJavaGenerator, operation, apiOperationTemplate);
} else if (Fetch.isFetch(operation)) {
Fetch.add(twilioJavaGenerator, operation, apiOperationTemplate);
} else if (Patch.isPatch(operation)) {
Patch.add(twilioJavaGenerator, operation, apiOperationTemplate);
} else {
throw new RuntimeException("Unsupported operation type for operationId: " + operationId);
}
Expand Down Expand Up @@ -149,4 +153,19 @@ public static void add(TwilioJavaGeneratorModern twilioJavaGenerator, CodegenOpe
public static boolean isFetch(CodegenOperation codegenOperation) {
return codegenOperation.operationId.toLowerCase().startsWith("fetch");
}
}
}

class Patch {
public static void add(TwilioJavaGeneratorModern twilioJavaGenerator, CodegenOperation codegenOperation, Map<String, AbstractMap.SimpleEntry> apiOperationTemplate) {
codegenOperation.vendorExtensions.put(SupportedOperation.X_PATCH.getValue(), true);
String key = (String) apiOperationTemplate.get("patch").getKey();
String value = (String) apiOperationTemplate.get("patch").getValue();
twilioJavaGenerator.apiTemplateFiles().put(key, value);

codegenOperation.vendorExtensions.put(MustacheConstants.ACTION_TYPE, ActionType.PATCHER.getValue());
codegenOperation.vendorExtensions.put(MustacheConstants.ACTION_METHOD, ActionMethod.PATCH.getValue());
}
public static boolean isPatch(CodegenOperation codegenOperation) {
return codegenOperation.operationId.toLowerCase().startsWith("patch");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public class MustacheConstants {
public static final String X_IS_LIST_OP = "x-is-list-op";
public static final String ACTION_TYPE = "x-common-action-type";
public static final String ACTION_METHOD = "x-common-action-method";

public static final Map<String, String> serializaationMapping = Map.of(
"application/x-www-form-urlencoded", "if ($paramName != null) { request.addPostParam($stringCapParamName, $paramName.toString())}",
"application/x-www-form-urlencoded", "if ($paramName != null) { request.addPostParam($stringCapParamName, $paramName.toString())}",
"application/json", "Json",
"multipart/form-data", "MultipartFormData"
);
Expand All @@ -34,7 +34,8 @@ public enum ActionType {
READER("Reader"),
UPDATER("Updater"),
DELETER("Deleter"),
FETCHER("Fetcher");
FETCHER("Fetcher"),
PATCHER("Patcher");

private final String value;
}
Expand All @@ -47,9 +48,10 @@ public enum ActionMethod {
READ("read"),
UPDATE("update"),
DELETE("delete"),
FETCH("fetch");
FETCH("fetch"),
PATCH("patch");

private final String value;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public Map<String, List<String>> mapping() {
Arrays.asList("reader.mustache", "Reader.java"),
"update",
Arrays.asList("updater.mustache", "Updater.java"),
"patch",
Arrays.asList("updater.mustache", "Updater.java"),
API_TEMPLATE,
Arrays.asList("api.mustache", ".java"),
NESTED_MODELS,
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/twilio-java/common/imports.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.twilio.base.Deleter;
import com.twilio.base.Fetcher;
import com.twilio.base.Reader;
import com.twilio.base.Updater;
import com.twilio.base.Patcher;
import com.twilio.constant.EnumConstants;
import com.twilio.constant.EnumConstants.ParameterType;
import com.twilio.converter.Promoter;
Expand Down Expand Up @@ -57,4 +58,4 @@ import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonProcessingException;
28 changes: 28 additions & 0 deletions src/main/resources/twilio-java/patcher.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{>licenseInfo}}
{{#resources}}
package com.twilio.rest.{{domainPackage}}.{{apiVersion}}{{namespaceSubPart}};
{{>common/imports}}

{{#operations}}
{{#vendorExtensions.x-patch-operation}}
public class {{resourceName}}Patcher extends Patcher<{{resourceName}}> {
{{>common/instanceVariables}}
{{>common/constructors}}
{{>patcher/setters}}
{{>patcher/operationMethod}}
{{#queryParams.0}}
{{>common/addQueryParams}}
{{/queryParams.0}}
{{#formParams.0}}
{{>common/addPostParams}}
{{/formParams.0}}
{{#headerParams.0}}
{{>common/addHeaderParams}}
{{/headerParams.0}}
{{#bodyParams.0}}
{{>common/addPostParamsJson}}
{{/bodyParams.0}}
}
{{/vendorExtensions.x-patch-operation}}
{{/operations}}
{{/resources}}
54 changes: 54 additions & 0 deletions src/main/resources/twilio-java/patcher/operationMethod.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{{!
resourceName: Api Name as identified by Directory Structure service
x-common-action-method: used to define operation method and can have values: create, read, update, delete, fetch, patch
Example: https://github.com/twilio/twilio-java/blob/9c2ba4dbc185c5576e67fbeb82ec6f4899093e79/src/main/java/com/twilio/rest/api/v2010/account/MessageCreator.java#L309

httpMethod: http method associated in the current operation.
domainName: example api, video, chat, etc. These can be found in Domains.java in twilio-java
vendorExtensions.x-content-type: content type of the request, example: application/json, application/x-www-form-urlencoded
}}
@Override
public {{resourceName}} {{vendorExtensions.x-common-action-method}}(final TwilioRestClient client) {
{{>common/generateUri}}

Request request = new Request(
HttpMethod.{{httpMethod}},
Domains.{{#lambda.uppercase}}{{domainName}}{{/lambda.uppercase}}.toString(),
path
);
{{#vendorExtensions.x-request-content-type}}
request.setContentType(EnumConstants.ContentType.{{vendorExtensions.x-request-content-type}});
{{/vendorExtensions.x-request-content-type}}
{{#vendorExtensions.x-no-auth}}
request.setAuth(NoAuthStrategy.getInstance());
{{/vendorExtensions.x-no-auth}}
{{#queryParams.0}}
addQueryParams(request);
{{/queryParams.0}}
{{#headerParams.0}}
addHeaderParams(request);
{{/headerParams.0}}
{{#formParams.0}}
addPostParams(request);
{{/formParams.0}}
{{#bodyParams.0}}
addPostParams(request, client);
{{/bodyParams.0}}

Response response = client.request(request);

if (response == null) {
throw new ApiConnectionException("{{resourceName}} patch failed: Unable to connect to server");
} else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) {
RestException restException = RestException.fromJson(
response.getStream(),
client.getObjectMapper()
);
if (restException == null) {
throw new ApiException("Server Error, no content", response.getStatusCode());
}
throw new ApiException(restException);
}

return {{resourceName}}.fromJson(response.getStream(), client.getObjectMapper());
}
20 changes: 20 additions & 0 deletions src/main/resources/twilio-java/patcher/setters.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{#vendorExtensions.x-setter-methods}}

public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final {{{dataType}}} {{paramName}}){
this.{{paramName}} = {{paramName}};
return this;
}

{{! Optional setter-- Ideally this shouldn't exists, keeping it for backward compatibility }}
{{#isArray}}
public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final {{{baseType}}} {{paramName}}){
return set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(Promoter.listOfOne({{paramName}}));
}
{{/isArray}}
{{! Optional setter, vendorExtensions.x-promotion stores promotion method}}
{{#vendorExtensions.x-promotion}}
public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final String {{paramName}}){
return set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}({{vendorExtensions.x-promotion}});
}
{{/vendorExtensions.x-promotion}}
{{/vendorExtensions.x-setter-methods}}
Loading