[ 
https://issues.apache.org/jira/browse/AVRO-1961?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16693669#comment-16693669
 ] 

ASF GitHub Bot commented on AVRO-1961:
--------------------------------------

dkulp closed pull request #162: AVRO-1961: Java: Generate getters that return a 
Java 8 Optional.
URL: https://github.com/apache/avro/pull/162
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/CHANGES.txt b/CHANGES.txt
index 3553e2a93..e145d1cc1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -16,6 +16,8 @@ Trunk (not yet released)
     AVRO-1932: Java: Allow setting the SchemaStore on generated classes. 
     (Niels Basjes)
 
+    AVRO-1961: Java: Generate getters that return a Java 8 Optional. (Niels 
Basjes)
+
   OPTIMIZATIONS
 
   IMPROVEMENTS
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 295949313..36e51c9fc 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
@@ -105,6 +105,8 @@
   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;
@@ -217,6 +219,28 @@ public void setCreateSetters(boolean createSetters) {
     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"
@@ -778,6 +802,16 @@ public static String generateGetMethod(Schema schema, 
Field field) {
     return generateMethodName(schema, field, "get", "");
   }
 
+  /**
+   * 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.
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 85c5e9d2f..04666e42a 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
@@ -25,6 +25,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
 
 @SuppressWarnings("all")
 #if ($schema.getDoc())
@@ -184,6 +185,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&lt;${this.javaType($field.schema())}&gt;.
+   */
+  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()
@@ -193,6 +205,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&lt;${this.javaType($field.schema())}&gt;.
+   */
+  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)
   /**
@@ -329,6 +354,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&lt;value&gt;.
+      */
+    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 186967fc9..38d6b7087 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,17 @@
           </execution>
         </executions>
       </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>${jdkVersion}</source>
+          <target>${jdkVersion}</target>
+          <testSource>${jdk8Version}</testSource>
+          <testTarget>${jdk8Version}</testTarget>
+        </configuration>
+      </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 a0ad619e3..10cda9a39 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
@@ -21,8 +21,11 @@
 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;
 import static org.junit.Assert.fail;
 
 public class TestSpecificBuilderTree {
@@ -254,4 +257,53 @@ public void lastOneWins_Builder() {
     assertEquals("/index.html",     
request.getHttpRequest().getURI().getPath());
   }
 
+  @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 9d78ede91..e192f4cda 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
@@ -114,6 +114,25 @@
    */
   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 3f61ac2a2..b1ed7fbfc 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 @@ protected void doCompile(String filename, File 
sourceDirectory, File outputDirec
       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.compileToDestination(null, outputDirectory);
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 a30a08245..c2a2a4927 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 @@ protected void doCompile(String filename, File 
sourceDirectory, File outputDirec
     compiler.setTemplateDir(templateDirectory);
     compiler.setStringType(StringType.valueOf(stringType));
     compiler.setFieldVisibility(getFieldVisibility());
+    compiler.setCreateOptionalGetters(createOptionalGetters);
+    compiler.setGettersReturnOptional(gettersReturnOptional);
     compiler.setCreateSetters(createSetters);
     compiler.setEnableDecimalLogicalType(enableDecimalLogicalType);
     compiler.compileToDestination(src, outputDirectory);
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 9a849207f..b6d58daae 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
@@ -65,7 +65,7 @@ protected void doCompile(String filename, File 
sourceDirectory, File outputDirec
 
     // This is necessary to maintain backward-compatibility. If there are
     // no imported files then isolate the schemas from each other, otherwise
-    // allow them to share a single schema so resuse and sharing of schema
+    // allow them to share a single schema so reuse and sharing of schema
     // is possible.
     if (imports == null) {
       schema = new Schema.Parser().parse(src);
@@ -77,6 +77,8 @@ protected void doCompile(String filename, File 
sourceDirectory, File outputDirec
     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/pom.xml b/lang/java/pom.xml
index 8afcefd5d..789b8d74e 100644
--- a/lang/java/pom.xml
+++ b/lang/java/pom.xml
@@ -35,6 +35,8 @@
 
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <jdkVersion>1.6</jdkVersion>
+    <jdk8Version>1.8</jdk8Version> <!-- Some tests need java 8 or newer -->
 
     <!-- version properties for dependencies -->
 
@@ -75,7 +77,7 @@
 
     <!-- version properties for plugins -->
     <bundle-plugin-version>2.5.3</bundle-plugin-version>
-    <compiler-plugin.version>3.1</compiler-plugin.version>
+    <compiler-plugin.version>3.6.0</compiler-plugin.version>
     <exec-plugin.version>1.3.2</exec-plugin.version>
     <jar-plugin.version>2.5</jar-plugin.version>
     <javacc-plugin.version>2.6</javacc-plugin.version>
diff --git a/share/docker/Dockerfile b/share/docker/Dockerfile
index 01760554d..f97416749 100644
--- a/share/docker/Dockerfile
+++ b/share/docker/Dockerfile
@@ -17,7 +17,7 @@
 # Dockerfile for installing the necessary dependencies for building Avro.
 # See BUILD.txt.
 
-FROM java:7-jdk
+FROM java:8-jdk
 
 WORKDIR /root
 
diff --git a/share/test/schemas/http.avdl b/share/test/schemas/http.avdl
index 52313e704..7e371f072 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;
     }
 


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> [JAVA] Generate getters that return an Optional
> -----------------------------------------------
>
>                 Key: AVRO-1961
>                 URL: https://issues.apache.org/jira/browse/AVRO-1961
>             Project: Apache Avro
>          Issue Type: New Feature
>            Reporter: Niels Basjes
>            Assignee: Niels Basjes
>            Priority: Minor
>
> A colleague of mine indicated that having getters that return an Optional 
> (java 8 thingy) would be very useful for him.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to