From 76875fd7c4844c700910c90e32ff458dbceb8712 Mon Sep 17 00:00:00 2001 From: Pierre Millot Date: Wed, 6 Apr 2022 17:47:29 +0200 Subject: [PATCH 1/2] fix(java): apply Mouaad suggestions --- .../algolia/codegen/AlgoliaJavaGenerator.java | 12 ++ scripts/playground.ts | 2 +- templates/java/JSON.mustache | 108 ++++-------------- templates/java/build.gradle.mustache | 6 +- .../java/libraries/okhttp-gson/api.mustache | 18 +-- templates/java/modelEnum.mustache | 2 +- templates/java/oneof_interface.mustache | 1 - templates/java/pojo.mustache | 8 +- 8 files changed, 48 insertions(+), 109 deletions(-) diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java index 05c7c247b2c..54792d797a3 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java @@ -231,4 +231,16 @@ public String toDefaultValue(Schema schema) { } return super.toDefaultValue(schema); } + + @Override + public String toEnumVarName(String value, String datatype) { + if ("String".equals(datatype)) { + // convert camelCase77String to CAMEL_CASE_77_STRING + return value + .replaceAll("\\W+", "_") + .replaceAll("(\\b[a-z]+|\\G(?!^))((?:[A-Z]|\\d+)[a-z]*)", "$1_$2") + .toUpperCase(Locale.ROOT); + } + return super.toEnumVarName(value, datatype); + } } diff --git a/scripts/playground.ts b/scripts/playground.ts index 981b4709d56..b7fd67eb139 100644 --- a/scripts/playground.ts +++ b/scripts/playground.ts @@ -13,7 +13,7 @@ export async function playground({ }); break; case 'java': - await run(`./gradle/gradlew --no-daemon -p playground/java run`, { + await run(`./gradle/gradlew -p playground/java run`, { verbose, }); break; diff --git a/templates/java/JSON.mustache b/templates/java/JSON.mustache index c412ab1b51b..a8b85f3384c 100644 --- a/templates/java/JSON.mustache +++ b/templates/java/JSON.mustache @@ -6,14 +6,9 @@ import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.text.DateFormat; import java.text.ParseException; import java.text.ParsePosition; -import java.time.LocalDate; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; import java.util.Collections; -import java.util.Date; import java.util.EnumMap; import java.util.HashMap; import java.util.Hashtable; @@ -52,13 +47,11 @@ import okio.ByteString; public class JSON { private static Gson gson; - private static DateTypeAdapter dateTypeAdapter = new DateTypeAdapter(); - private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); - private static RetainFieldMapFactory mapAdapter = new RetainFieldMapFactory(); + private static final ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); + private static final RetainFieldMapFactory mapAdapter = new RetainFieldMapFactory(); static { gson = createGson() - .registerTypeAdapter(Date.class, dateTypeAdapter) .registerTypeAdapter(byte[].class, byteArrayAdapter) .registerTypeAdapterFactory(mapAdapter) .create(); @@ -87,6 +80,11 @@ public class JSON { return fireBuilder.createGsonBuilder(); } + // Suppress default constructor for noninstantiability + private JSON() { + throw new AssertionError(); + } + /** * Get Gson. * @@ -137,95 +135,31 @@ public class JSON { } } } - - public static void setDateFormat(DateFormat dateFormat) { - dateTypeAdapter.setFormat(dateFormat); - } } /** * Gson TypeAdapter for Byte Array type */ class ByteArrayAdapter extends TypeAdapter { - -@Override -public void write(JsonWriter out, byte[] value) throws IOException { + @Override + public void write(JsonWriter out, byte[] value) throws IOException { if (value == null) { - out.nullValue(); - } else { - out.value(ByteString.of(value).base64()); - } -} - -@Override -public byte[] read(JsonReader in) throws IOException { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String bytesAsBase64 = in.nextString(); - ByteString byteString = ByteString.decodeBase64(bytesAsBase64); - return byteString.toByteArray(); - } -} -} - -/** -* Gson TypeAdapter for java.util.Date type -* If the dateFormat is null, ISO8601Utils will be used. -*/ -class DateTypeAdapter extends TypeAdapter { - -private DateFormat dateFormat; - -public DateTypeAdapter() {} - -public DateTypeAdapter(DateFormat dateFormat) { - this.dateFormat = dateFormat; -} - -public void setFormat(DateFormat dateFormat) { - this.dateFormat = dateFormat; -} - -@Override -public void write(JsonWriter out, Date date) throws IOException { - if (date == null) { - out.nullValue(); + out.nullValue(); } else { - String value; - if (dateFormat != null) { - value = dateFormat.format(date); - } else { - value = ISO8601Utils.format(date, true); - } - out.value(value); + out.value(ByteString.of(value).base64()); } -} + } -@Override -public Date read(JsonReader in) throws IOException { - try { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String date = in.nextString(); - try { - if (dateFormat != null) { - return dateFormat.parse(date); - } - return ISO8601Utils.parse(date, new ParsePosition(0)); - } catch (ParseException e) { - throw new JsonParseException(e); - } - } - } catch (IllegalArgumentException e) { - throw new JsonParseException(e); + @Override + public byte[] read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; } -} + String bytesAsBase64 = in.nextString(); + ByteString byteString = ByteString.decodeBase64(bytesAsBase64); + return byteString != null ? byteString.toByteArray() : new byte[0]; + } } // https://stackoverflow.com/questions/21458468/gson-wont-properly-serialise-a-class-that-extends-hashmap diff --git a/templates/java/build.gradle.mustache b/templates/java/build.gradle.mustache index 7e9909d7f89..f07a1b62bec 100644 --- a/templates/java/build.gradle.mustache +++ b/templates/java/build.gradle.mustache @@ -1,5 +1,5 @@ plugins { - id 'java' + id 'java-library' id 'maven-publish' } @@ -14,9 +14,9 @@ repositories { dependencies { implementation 'com.google.code.findbugs:jsr305:3.0.2' - implementation 'com.squareup.okhttp3:okhttp:4.9.1' + api 'com.squareup.okhttp3:okhttp:4.9.1' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' - implementation 'com.google.code.gson:gson:2.8.9' + api 'com.google.code.gson:gson:2.8.9' implementation 'io.gsonfire:gson-fire:1.8.5' } diff --git a/templates/java/libraries/okhttp-gson/api.mustache b/templates/java/libraries/okhttp-gson/api.mustache index a74df90a1e5..596c873befb 100644 --- a/templates/java/libraries/okhttp-gson/api.mustache +++ b/templates/java/libraries/okhttp-gson/api.mustache @@ -93,7 +93,7 @@ public class {{classname}} extends ApiClient { {{#operation}} /** * Build call for {{operationId}} - * @param _callback Callback for upload/download progress + * @param callback Callback for upload/download progress * @return Call to execute * @throws AlgoliaRuntimeException If fail to serialize the request body object {{#isDeprecated}} @@ -107,7 +107,7 @@ public class {{classname}} extends ApiClient { {{#isDeprecated}} @Deprecated {{/isDeprecated}} - private Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}> _callback) throws AlgoliaRuntimeException { + private Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}> callback) throws AlgoliaRuntimeException { Object bodyObj = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; // create path and map variables @@ -141,13 +141,13 @@ public class {{classname}} extends ApiClient { headers.put("Accept", "application/json"); headers.put("Content-Type", "application/json"); - return this.buildCall(requestPath, "{{httpMethod}}", queryParams, bodyObj, headers, _callback); + return this.buildCall(requestPath, "{{httpMethod}}", queryParams, bodyObj, headers, callback); } {{#isDeprecated}} @Deprecated {{/isDeprecated}} - private Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}> _callback) throws AlgoliaRuntimeException { + private Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}> callback) throws AlgoliaRuntimeException { {{#allParams}}{{#required}} // verify the required parameter '{{paramName}}' is set if ({{paramName}} == null) { @@ -155,7 +155,7 @@ public class {{classname}} extends ApiClient { } {{/required}}{{/allParams}} - return {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}_callback); + return {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}callback); } /** @@ -195,7 +195,7 @@ public class {{classname}} extends ApiClient { * (asynchronously) * {{notes}}{{#allParams}} * @param {{paramName}} {{{description}}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}{{/isContainer}}){{/required}}{{/allParams}} - * @param _callback The callback to be executed when the API call finishes + * @param callback The callback to be executed when the API call finishes * @return The request call * @throws AlgoliaRuntimeException If fail to process the API call, e.g. serializing the request body object {{#isDeprecated}} @@ -209,10 +209,10 @@ public class {{classname}} extends ApiClient { {{#isDeprecated}} @Deprecated {{/isDeprecated}} - public Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}{{^returnType}}Void{{/returnType}}> _callback) throws AlgoliaRuntimeException { - Call call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}_callback); + public Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{{returnType}}}{{^returnType}}Void{{/returnType}}> callback) throws AlgoliaRuntimeException { + Call call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}callback); {{#returnType}}Type returnType = new TypeToken<{{{returnType}}}>(){}.getType(); - this.executeAsync(call, returnType, _callback);{{/returnType}}{{^returnType}}this.executeAsync(call, _callback);{{/returnType}} + this.executeAsync(call, returnType, callback);{{/returnType}}{{^returnType}}this.executeAsync(call, callback);{{/returnType}} return call; } {{/operation}} diff --git a/templates/java/modelEnum.mustache b/templates/java/modelEnum.mustache index 7ba22c479f3..5bc0d7b97da 100644 --- a/templates/java/modelEnum.mustache +++ b/templates/java/modelEnum.mustache @@ -23,7 +23,7 @@ import com.google.gson.stream.JsonWriter; */{{/enumDescription}} {{{name}}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}} - private {{{dataType}}} value; + private final {{{dataType}}} value; {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) { this.value = value; diff --git a/templates/java/oneof_interface.mustache b/templates/java/oneof_interface.mustache index 577f7e5b71a..790a0409c12 100644 --- a/templates/java/oneof_interface.mustache +++ b/templates/java/oneof_interface.mustache @@ -17,7 +17,6 @@ public abstract class {{classname}} implements CompoundType { } {{/vendorExtensions.x-is-one-of-list}} - public abstract Object getInsideValue(); public static class Adapter extends TypeAdapter<{{classname}}> { @Override diff --git a/templates/java/pojo.mustache b/templates/java/pojo.mustache index 479efd798de..105d3aa1ff5 100644 --- a/templates/java/pojo.mustache +++ b/templates/java/pojo.mustache @@ -55,7 +55,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{ {{#vars}} {{^isReadOnly}} - public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + public {{classname}} {{setter}}({{{datatypeWithEnum}}} {{name}}) { this.{{name}} = {{name}}; return this; } @@ -124,12 +124,6 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{ return {{name}}; } - {{^isReadOnly}} - public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { - this.{{name}} = {{name}}; - } - {{/isReadOnly}} - {{/vars}} @Override From 6de8a0512c60543970aa5e7f304d00ad676bd922 Mon Sep 17 00:00:00 2001 From: Pierre Millot Date: Thu, 7 Apr 2022 10:40:34 +0200 Subject: [PATCH 2/2] better regex by @shortcuts --- .../main/java/com/algolia/codegen/AlgoliaJavaGenerator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java index 54792d797a3..2a8c7568766 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java @@ -237,8 +237,7 @@ public String toEnumVarName(String value, String datatype) { if ("String".equals(datatype)) { // convert camelCase77String to CAMEL_CASE_77_STRING return value - .replaceAll("\\W+", "_") - .replaceAll("(\\b[a-z]+|\\G(?!^))((?:[A-Z]|\\d+)[a-z]*)", "$1_$2") + .replaceAll("(.+?)([A-Z]|[0-9])", "$1_$2") .toUpperCase(Locale.ROOT); } return super.toEnumVarName(value, datatype);