THRIFT-5521: [java gen] use jdk8 option type in java generator code
Client: Java
Patch: Jiayu Liu

This closes #2525
diff --git a/lib/java/gradle/functionalTests.gradle b/lib/java/gradle/functionalTests.gradle
index f00f74b..f197520 100644
--- a/lib/java/gradle/functionalTests.gradle
+++ b/lib/java/gradle/functionalTests.gradle
@@ -91,8 +91,8 @@
 def javaExe = file("${System.getProperty('java.home')}/bin/java${execExt}").canonicalPath
 // The common Uber jar path
 def jarPath = shadowJar.archivePath.canonicalPath
-def trustStore = file('test/.truststore').canonicalPath
-def keyStore = file('test/.keystore').canonicalPath
+def trustStore = file('test/resources/.truststore').canonicalPath
+def keyStore = file('test/resources/.keystore').canonicalPath
 
 task generateRunnerScriptForClient(group: 'Build') {
     description = 'Generate a runner script for cross-check tests with TestClient'
diff --git a/lib/java/gradle/generateTestThrift.gradle b/lib/java/gradle/generateTestThrift.gradle
index d5bc3af..c48845e 100644
--- a/lib/java/gradle/generateTestThrift.gradle
+++ b/lib/java/gradle/generateTestThrift.gradle
@@ -24,11 +24,12 @@
 ext.genBeanSrc = file("$buildDir/gen-javabean")
 ext.genReuseSrc = file("$buildDir/gen-javareuse")
 ext.genFullCamelSrc = file("$buildDir/gen-fullcamel")
+ext.genOptionTypeJdk8Src = file("$buildDir/gen-option-type-jdk8")
 ext.genUnsafeSrc = file("$buildDir/gen-unsafe")
 
 // Add the generated code directories to the test source set
 sourceSets {
-    test.java.srcDirs genSrc, genBeanSrc, genReuseSrc, genFullCamelSrc, genUnsafeSrc
+    test.java.srcDirs genSrc, genBeanSrc, genReuseSrc, genFullCamelSrc, genUnsafeSrc, genOptionTypeJdk8Src
 }
 
 // ----------------------------------------------------------------------------
@@ -37,7 +38,10 @@
 // A callable closure to make this easier
 ext.thriftCompile = { Task task, String thriftFileName, String generator = 'java', File outputDir = genSrc ->
     def thriftFile = file("$thriftRoot/test/$thriftFileName")
-    assert thriftFile.exists()
+    if (!thriftFile.exists()) {
+        thriftFile = file("$projectDir/test/resources/$thriftFileName")
+        assert thriftFile.exists(), "can't find $thriftFile"
+    }
 
     task.inputs.file thriftFile
     task.outputs.dir outputDir
@@ -85,6 +89,15 @@
     thriftCompile(it, 'partial/thrift_test_schema.thrift')
 }
 
+task generateOptionalTypeJava(group: 'Build') {
+    description = 'Generate the thrift gen-option-type-jdk8 source'
+    generate.dependsOn it
+
+    ext.outputBuffer = new ByteArrayOutputStream()
+
+    thriftCompile(it, 'JavaOptionTypeJdk8Test.thrift', 'java:option_type=jdk8', genOptionTypeJdk8Src)
+}
+
 task generateBeanJava(group: 'Build') {
     description = 'Generate the thrift gen-javabean source'
     generate.dependsOn it
diff --git a/lib/java/gradle/sourceConfiguration.gradle b/lib/java/gradle/sourceConfiguration.gradle
index ce0db75..c510a40 100644
--- a/lib/java/gradle/sourceConfiguration.gradle
+++ b/lib/java/gradle/sourceConfiguration.gradle
@@ -37,7 +37,7 @@
             exclude '**/test/TestTServletServer.java'
         }
         resources {
-            srcDir 'test'
+            srcDir 'test/resources'
             include 'log4j.properties'
         }
     }
diff --git a/lib/java/gradle/unitTests.gradle b/lib/java/gradle/unitTests.gradle
index 61f2fbd..2bf1c03 100644
--- a/lib/java/gradle/unitTests.gradle
+++ b/lib/java/gradle/unitTests.gradle
@@ -74,9 +74,9 @@
     systemProperties = [
         'build.test': "${compileTestJava.destinationDir}",
         'test.port': "${testPort}",
-        'javax.net.ssl.trustStore': "${projectDir}/test/.truststore",
+        'javax.net.ssl.trustStore': "${projectDir}/test/resources/.truststore",
         'javax.net.ssl.trustStorePassword': 'thrift',
-        'javax.net.ssl.keyStore': "${projectDir}/test/.keystore",
+        'javax.net.ssl.keyStore': "${projectDir}/test/resources/.keystore",
         'javax.net.ssl.keyStorePassword': 'thrift'
     ]
 }
diff --git a/lib/java/test/org/apache/thrift/TestOptionType.java b/lib/java/test/org/apache/thrift/TestOptionType.java
index f70285f..ddde9d3 100644
--- a/lib/java/test/org/apache/thrift/TestOptionType.java
+++ b/lib/java/test/org/apache/thrift/TestOptionType.java
@@ -20,11 +20,10 @@
 package org.apache.thrift;
 
 import junit.framework.TestCase;
-import org.apache.thrift.Option;
 
 // Tests and documents behavior for the "Option<T>" type
 public class TestOptionType extends TestCase {
-    public void testSome() throws Exception {
+    public void testSome() {
         String name = "Chuck Norris";
         Option<String> option = Option.fromNullable(name);
 
diff --git a/lib/java/test/org/apache/thrift/TestOptionals.java b/lib/java/test/org/apache/thrift/TestOptionals.java
index f3d4cfc..b34e06d 100644
--- a/lib/java/test/org/apache/thrift/TestOptionals.java
+++ b/lib/java/test/org/apache/thrift/TestOptionals.java
@@ -26,7 +26,7 @@
 import thrift.test.Opt64;
 import thrift.test.Opt80;
 
-// Exercises the isSet methods using structs from from ManyOptionals.thrift
+// Exercises the isSet methods using structs from ManyOptionals.thrift
 public class TestOptionals extends TestCase {
   public void testEncodingUtils() throws Exception {
     assertEquals((short)0x8, EncodingUtils.setBit((short)0, 3, true));
diff --git a/lib/java/test/org/apache/thrift/TestOptionalsWithJdk8.java b/lib/java/test/org/apache/thrift/TestOptionalsWithJdk8.java
new file mode 100644
index 0000000..93daced
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/TestOptionalsWithJdk8.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift;
+
+import junit.framework.TestCase;
+import thrift.test.optiontypejdk8.Person;
+
+// Tests and documents behavior for the JDK8 "Option<T>" type
+public class TestOptionalsWithJdk8 extends TestCase {
+
+    public void testConstruction() {
+        Person person = new Person(1L, "name");
+        assertFalse(person.getAge().isPresent());
+        assertFalse(person.isSetAge());
+        assertFalse(person.getPhone().isPresent());
+        assertFalse(person.isSetPhone());
+        assertEquals(1L, person.getId());
+        assertTrue(person.isSetId());
+        assertEquals("name", person.getName());
+        assertTrue(person.isSetName());
+
+        assertFalse(person.getAddresses().isPresent());
+        assertEquals(Integer.valueOf(0), person.getAddressesSize().orElse(0));
+        assertFalse(person.getPets().isPresent());
+        assertEquals(Integer.valueOf(0), person.getPetsSize().orElse(0));
+    }
+
+    public void testEmpty() {
+        Person person = new Person();
+        person.setPhone("phone");
+        assertFalse(person.getAge().isPresent());
+        assertFalse(person.isSetAge());
+        assertTrue(person.getPhone().isPresent());
+        assertEquals("phone", person.getPhone().get());
+        assertTrue(person.isSetPhone());
+        assertEquals(0L, person.getId());
+        assertFalse(person.isSetId());
+        assertNull(person.getName());
+        assertFalse(person.isSetName());
+
+        assertFalse(person.getAddresses().isPresent());
+        assertEquals(Integer.valueOf(0), person.getAddressesSize().orElse(0));
+        assertFalse(person.getPets().isPresent());
+        assertEquals(Integer.valueOf(0), person.getPetsSize().orElse(0));
+    }
+}
diff --git a/lib/java/test/.keystore b/lib/java/test/resources/.keystore
similarity index 100%
rename from lib/java/test/.keystore
rename to lib/java/test/resources/.keystore
Binary files differ
diff --git a/lib/java/test/.truststore b/lib/java/test/resources/.truststore
similarity index 100%
rename from lib/java/test/.truststore
rename to lib/java/test/resources/.truststore
Binary files differ
diff --git a/lib/java/test/resources/JavaBeansTest.thrift b/lib/java/test/resources/JavaBeansTest.thrift
new file mode 100644
index 0000000..b6c3ea8
--- /dev/null
+++ b/lib/java/test/resources/JavaBeansTest.thrift
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+namespace java thrift.test
+
+struct OneOfEachBeans {
+  1: bool boolean_field,
+  2: byte a_bite,
+  3: i16 integer16,
+  4: i32 integer32,
+  5: i64 integer64,
+  6: double double_precision,
+  7: string some_characters,
+  8: binary base64,
+  9: list<byte> byte_list,
+  10: list<i16> i16_list,
+  11: list<i64> i64_list
+}
+
+
+service Service {
+  i64 mymethod(i64 blah);
+}
\ No newline at end of file
diff --git a/lib/java/test/resources/JavaBinaryDefault.thrift b/lib/java/test/resources/JavaBinaryDefault.thrift
new file mode 100644
index 0000000..5517802
--- /dev/null
+++ b/lib/java/test/resources/JavaBinaryDefault.thrift
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+namespace java thrift.test
+
+struct StringAndBinary {
+  1: optional string strval = ""
+  2: optional binary binval = ""
+}
diff --git a/lib/java/test/resources/JavaDeepCopyTest.thrift b/lib/java/test/resources/JavaDeepCopyTest.thrift
new file mode 100644
index 0000000..fc974ae
--- /dev/null
+++ b/lib/java/test/resources/JavaDeepCopyTest.thrift
@@ -0,0 +1,19 @@
+include "JavaTypes.thrift"
+
+namespace java thrift.test
+
+struct DeepCopyFoo {
+  1: optional list<DeepCopyBar> l,
+  2: optional set<DeepCopyBar> s,
+  3: optional map<string, DeepCopyBar> m,
+  4: optional list<JavaTypes.Object> li,
+  5: optional set<JavaTypes.Object> si,
+  6: optional map<string, JavaTypes.Object> mi,
+  7: optional DeepCopyBar bar,
+}
+
+struct DeepCopyBar {
+  1: optional string a,
+  2: optional i32 b,
+  3: optional bool c,
+}
diff --git a/lib/java/test/resources/JavaOptionTypeJdk8Test.thrift b/lib/java/test/resources/JavaOptionTypeJdk8Test.thrift
new file mode 100644
index 0000000..193e079
--- /dev/null
+++ b/lib/java/test/resources/JavaOptionTypeJdk8Test.thrift
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace java thrift.test.optiontypejdk8
+
+struct Person {
+  1: required i64 id;
+  2: required string name;
+  3: optional i64 age;
+  4: optional string phone;
+  5: optional list<string> addresses;
+  6: optional map<string, Pet> pets;
+}
+
+enum PetType {
+  Cat = 1
+  Dog = 2
+  Bunny = 3
+}
+
+struct Pet {
+  1: required string name;
+  2: optional PetType type;
+}
diff --git a/lib/java/test/resources/JavaTypes.thrift b/lib/java/test/resources/JavaTypes.thrift
new file mode 100644
index 0000000..5553340
--- /dev/null
+++ b/lib/java/test/resources/JavaTypes.thrift
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+namespace java thrift.test
+
+struct Integer {
+  1: i32 val
+}
+
+struct String {
+  1: string val
+}
+
+struct Binary {
+  1: binary val
+}
+
+struct Boolean {
+  1: bool val
+}
+
+struct Double {
+  1: double val
+}
+
+struct Long {
+  1: i64 val
+}
+
+struct Byte {
+  1: byte val
+}
+
+struct Float {
+  1: double val
+}
+
+struct List {
+  1: list<string> vals
+}
+
+struct ArrayList {
+  1: list<string> vals
+}
+
+struct SortedMap {
+  1: map<string, string> vals
+}
+
+struct TreeMap {
+  1: map<string, string> vals
+}
+
+struct HashMap {
+  1: map<string, String> vals
+}
+
+struct Map {
+  1: map<double, Double> vals
+}
+
+struct Object {
+  1: Integer integer,
+  2: String str,
+  3: Boolean boolean_field,
+  4: Double dbl,
+  5: Byte bite,
+  6: map<i32, Integer> intmap,
+  7: Map somemap,
+}
+
+exception Exception {
+  1: string msg
+}
+
+service AsyncNonblockingService {
+  Object mymethod(
+    1: Integer integer,
+    2: String str,
+    3: Boolean boolean_field,
+    4: Double dbl,
+    5: Byte bite,
+    6: map<i32, Integer> intmap,
+    7: Map somemap,
+  ) throws (1:Exception ex);
+}
+
+struct SafeBytes {
+  1: binary bytes;
+}
+
diff --git a/lib/java/test/log4j.properties b/lib/java/test/resources/log4j.properties
similarity index 100%
rename from lib/java/test/log4j.properties
rename to lib/java/test/resources/log4j.properties