This is an automated email from the ASF dual-hosted git repository.
dkulp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new 04d4423 Squashed commit of the following:
04d4423 is described below
commit 04d4423d4ee4f86e308fa761c6918223b55a6c5c
Author: Daniel Kulp <dkulp@apache.org>
AuthorDate: Tue Nov 20 14:05:03 2018 -0500
Squashed commit of the following:
commit 6a919437bff0977926b33cd56165994b22fbdf74
Author: Niels Basjes <nbasjes@bol.com>
Date: Fri Nov 25 10:31:40 2016 +0100
AVRO-1961: Extra flag to replace the regular getters with getters that return an Optional
commit 91d58b5dba7562240a84f6885037f9c74dc973e6
Author: Niels Basjes <nbasjes@bol.com>
Date: Tue Nov 22 17:23:18 2016 +0100
AVRO-1961: Java: Generate getters that return a Java 8 Optional.
Closes #162
---
.../avro/compiler/specific/SpecificCompiler.java | 34 +++++++++++++++
.../specific/templates/java/classic/record.vm | 37 ++++++++++++++++
lang/java/ipc/pom.xml | 3 ++
.../avro/specific/TestSpecificBuilderTree.java | 49 ++++++++++++++++++++++
.../org/apache/avro/mojo/AbstractAvroMojo.java | 19 +++++++++
.../java/org/apache/avro/mojo/IDLProtocolMojo.java | 2 +
.../java/org/apache/avro/mojo/ProtocolMojo.java | 2 +
.../main/java/org/apache/avro/mojo/SchemaMojo.java | 2 +
share/test/schemas/http.avdl | 2 +-
9 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
index 5ee2bdc..b92025f 100644
--- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
+++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
@@ -118,6 +118,8 @@ public class SpecificCompiler {
private VelocityEngine velocityEngine;
private String templateDir;
private FieldVisibility fieldVisibility = FieldVisibility.PUBLIC_DEPRECATED;
+ private boolean createOptionalGetters = false;
+ private boolean gettersReturnOptional = false;
private boolean createSetters = true;
private boolean createAllArgsConstructor = true;
private String outputCharacterEncoding;
@@ -257,6 +259,28 @@ public class SpecificCompiler {
this.createSetters = createSetters;
}
+ public boolean isCreateOptionalGetters() {
+ return this.createOptionalGetters;
+ }
+
+ /**
+ * Set to false to not create the getters that return an Optional.
+ */
+ public void setCreateOptionalGetters(boolean createOptionalGetters) {
+ this.createOptionalGetters = createOptionalGetters;
+ }
+
+ public boolean isGettersReturnOptional() {
+ return this.gettersReturnOptional;
+ }
+
+ /**
+ * Set to false to not create the getters that return an Optional.
+ */
+ public void setGettersReturnOptional(boolean gettersReturnOptional) {
+ this.gettersReturnOptional = gettersReturnOptional;
+ }
+
/**
* Set to true to use {@link java.math.BigDecimal} instead of
* {@link java.nio.ByteBuffer} for logical type "decimal"
@@ -900,6 +924,16 @@ public class SpecificCompiler {
}
/**
+ * Generates the name of a field accessor method that returns a Java 8 Optional.
+ * @param schema the schema in which the field is defined.
+ * @param field the field for which to generate the accessor name.
+ * @return the name of the accessor method for the given field.
+ */
+ public static String generateGetOptionalMethod(Schema schema, Field field) {
+ return generateMethodName(schema, field, "getOptional", "");
+ }
+
+ /**
* Generates the name of a field mutator method.
* @param schema the schema in which the field is defined.
* @param field the field for which to generate the mutator name.
diff --git a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
index bc0c1d4..523c151 100644
--- a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
+++ b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
@@ -27,6 +27,7 @@ import org.apache.avro.message.BinaryMessageEncoder;
import org.apache.avro.message.BinaryMessageDecoder;
import org.apache.avro.message.SchemaStore;
#end
+#if (${this.gettersReturnOptional} || ${this.createOptionalGetters})import java.util.Optional;#end
#if ($schema.getDoc())
/** $schema.getDoc() */
@@ -202,6 +203,17 @@ public class ${this.mangle($schema.getName())}#if ($schema.isError())
extends or
}
#foreach ($field in $schema.getFields())
+#if (${this.gettersReturnOptional})
+ /**
+ * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field as an
Optional<${this.javaType($field.schema())}>.
+#if ($field.doc()) * $field.doc()
+#end
+ * @return The value wrapped in an Optional<${this.javaType($field.schema())}>.
+ */
+ public Optional<${this.javaType($field.schema())}> ${this.generateGetMethod($schema,
$field)}() {
+ return Optional.<${this.javaType($field.schema())}>ofNullable(${this.mangle($field.name(),
$schema.isError())});
+ }
+#else
/**
* Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc()) * @return $field.doc()
@@ -211,6 +223,19 @@ public class ${this.mangle($schema.getName())}#if ($schema.isError())
extends or
public ${this.javaType($field.schema())} ${this.generateGetMethod($schema, $field)}() {
return ${this.mangle($field.name(), $schema.isError())};
}
+#end
+
+#if (${this.createOptionalGetters})
+ /**
+ * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field as an
Optional<${this.javaType($field.schema())}>.
+#if ($field.doc()) * $field.doc()
+#end
+ * @return The value wrapped in an Optional<${this.javaType($field.schema())}>.
+ */
+ public Optional<${this.javaType($field.schema())}> ${this.generateGetOptionalMethod($schema,
$field)}() {
+ return Optional.<${this.javaType($field.schema())}>ofNullable(${this.mangle($field.name(),
$schema.isError())});
+ }
+#end
#if ($this.createSetters)
/**
@@ -355,6 +380,18 @@ public class ${this.mangle($schema.getName())}#if ($schema.isError())
extends or
return ${this.mangle($field.name(), $schema.isError())};
}
+#if (${this.createOptionalGetters})
+ /**
+ * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field as
an Optional<${this.javaType($field.schema())}>.
+#if ($field.doc()) * $field.doc()
+#end
+ * @return The Optional<value>.
+ */
+ public Optional<${this.javaType($field.schema())}> ${this.generateGetOptionalMethod($schema,
$field)}() {
+ return Optional.<${this.javaType($field.schema())}>ofNullable(${this.mangle($field.name(),
$schema.isError())});
+ }
+#end
+
/**
* Sets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc()) * $field.doc()
diff --git a/lang/java/ipc/pom.xml b/lang/java/ipc/pom.xml
index d0767a8..1c5fef0 100644
--- a/lang/java/ipc/pom.xml
+++ b/lang/java/ipc/pom.xml
@@ -73,6 +73,8 @@
<exclude>org/apache/avro/data/Json.avsc</exclude>
</excludes>
<stringType>String</stringType>
+ <createOptionalGetters>true</createOptionalGetters>
+ <!--<gettersReturnOptional>true</gettersReturnOptional>-->
<sourceDirectory>${parent.project.basedir}/../../../../share/schemas/</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
<testSourceDirectory>${parent.project.basedir}/../../../../share/test/schemas/</testSourceDirectory>
@@ -81,6 +83,7 @@
</execution>
</executions>
</plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
diff --git a/lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificBuilderTree.java
b/lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificBuilderTree.java
index 53ed754..54fc97b 100644
--- a/lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificBuilderTree.java
+++ b/lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificBuilderTree.java
@@ -23,6 +23,8 @@ import org.apache.avro.test.nullable.RecordWithNullables;
import org.junit.Test;
import java.util.ArrayList;
+import java.util.Optional;
+import java.util.function.Consumer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -363,5 +365,52 @@ public class TestSpecificBuilderTree {
// In the past this caused an NPE
RecordWithNullables.newBuilder((RecordWithNullables.Builder)null);
}
+ @Test
+ public void validateBrowsingOptionals() {
+ Request.Builder requestBuilder = Request.newBuilder();
+ requestBuilder.setTimestamp(1234567890);
+
+ requestBuilder
+ .getHttpRequestBuilder()
+ .getUserAgentBuilder()
+ .setUseragent("Chrome 123");
+
+ requestBuilder
+ .getHttpRequestBuilder()
+ .getURIBuilder()
+ .setMethod(HttpMethod.GET)
+ .setPath("/index.html");
+
+ Request request = requestBuilder.build();
+
+ assertEquals("Chrome 123", Optional
+ .of(request)
+ .flatMap(Request::getOptionalHttpRequest)
+ .flatMap(HttpRequest::getOptionalUserAgent)
+ .flatMap(UserAgent::getOptionalUseragent)
+ .orElse("UNKNOWN"));
+
+ assertFalse(Optional
+ .of(request)
+ .flatMap(Request::getOptionalHttpRequest)
+ .flatMap(HttpRequest::getOptionalUserAgent)
+ .flatMap(UserAgent::getOptionalId)
+ .isPresent());
+
+ assertEquals(HttpMethod.GET, Optional
+ .of(request)
+ .flatMap(Request::getOptionalHttpRequest)
+ .flatMap(HttpRequest::getOptionalURI)
+ .flatMap(HttpURI::getOptionalMethod)
+ .orElse(null));
+
+ assertEquals("/index.html", Optional
+ .of(request)
+ .flatMap(Request::getOptionalHttpRequest)
+ .flatMap(HttpRequest::getOptionalURI)
+ .flatMap(HttpURI::getOptionalPath)
+ .orElse(null));
+
+ }
}
diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
index 3ddb062..23b77d5 100644
--- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
+++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
@@ -115,6 +115,25 @@ public abstract class AbstractAvroMojo extends AbstractMojo {
protected String templateDirectory = "/org/apache/avro/compiler/specific/templates/java/classic/";
/**
+ * The createOptionalGetters parameter enables generating the getOptional...
+ * methods that return an Optional of the requested type.
+ * This works ONLY on Java 8+
+ *
+ * @parameter property="createOptionalGetters"
+ */
+ protected boolean createOptionalGetters = false;
+
+ /**
+ * The gettersReturnOptional parameter enables generating get...
+ * methods that return an Optional of the requested type.
+ * This will replace the
+ * This works ONLY on Java 8+
+ *
+ * @parameter property="gettersReturnOptional"
+ */
+ protected boolean gettersReturnOptional = false;
+
+ /**
* Determines whether or not to create setters for the fields of the record.
* The default is to create setters.
*
diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
index 92b7b40..da1ae33 100644
--- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
+++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
@@ -92,6 +92,8 @@ public class IDLProtocolMojo extends AbstractAvroMojo {
compiler.setStringType(GenericData.StringType.valueOf(stringType));
compiler.setTemplateDir(templateDirectory);
compiler.setFieldVisibility(getFieldVisibility());
+ compiler.setCreateOptionalGetters(createOptionalGetters);
+ compiler.setGettersReturnOptional(gettersReturnOptional);
compiler.setCreateSetters(createSetters);
compiler.setEnableDecimalLogicalType(enableDecimalLogicalType);
compiler.setOutputCharacterEncoding(project.getProperties().getProperty("project.build.sourceEncoding"));
diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java
index 0be3d69..d4b3bf5 100644
--- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java
+++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java
@@ -60,6 +60,8 @@ public class ProtocolMojo extends AbstractAvroMojo {
compiler.setTemplateDir(templateDirectory);
compiler.setStringType(StringType.valueOf(stringType));
compiler.setFieldVisibility(getFieldVisibility());
+ compiler.setCreateOptionalGetters(createOptionalGetters);
+ compiler.setGettersReturnOptional(gettersReturnOptional);
compiler.setCreateSetters(createSetters);
compiler.setEnableDecimalLogicalType(enableDecimalLogicalType);
compiler.setOutputCharacterEncoding(project.getProperties().getProperty("project.build.sourceEncoding"));
diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java
index ab9d0eb..9b4840c 100644
--- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java
+++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java
@@ -77,6 +77,8 @@ public class SchemaMojo extends AbstractAvroMojo {
compiler.setTemplateDir(templateDirectory);
compiler.setStringType(StringType.valueOf(stringType));
compiler.setFieldVisibility(getFieldVisibility());
+ compiler.setCreateOptionalGetters(createOptionalGetters);
+ compiler.setGettersReturnOptional(gettersReturnOptional);
compiler.setCreateSetters(createSetters);
compiler.setEnableDecimalLogicalType(enableDecimalLogicalType);
compiler.setOutputCharacterEncoding(project.getProperties().getProperty("project.build.sourceEncoding"));
diff --git a/share/test/schemas/http.avdl b/share/test/schemas/http.avdl
index 52313e7..7e371f0 100644
--- a/share/test/schemas/http.avdl
+++ b/share/test/schemas/http.avdl
@@ -59,7 +59,7 @@ protocol Http {
record Request {
long timestamp;
- NetworkConnection connection;
+ union { null, NetworkConnection } connection = null;
HttpRequest httpRequest;
}
|