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 8197803 [AVRO-2630] Part 2 - allow the JSR310 conversions to truncate
at the appropriate value
8197803 is described below
commit 8197803dceb89d53d6f5a3e9143f46c035d6558b
Author: Daniel Kulp <[email protected]>
AuthorDate: Thu Mar 28 13:39:58 2019 -0400
[AVRO-2630] Part 2 - allow the JSR310 conversions to truncate at the
appropriate value
---
.../src/main/java/org/apache/avro/Conversion.java | 13 +
.../apache/avro/data/Jsr310TimeConversions.java | 20 +
.../avro/compiler/specific/SpecificCompiler.java | 11 +
.../specific/templates/java/classic/record.vm | 6 +-
.../tools/src/test/compiler/input/fieldtest.avsc | 10 +
.../avro/examples/baseball/FieldTest.java | 664 +++++++++++++++++++++
.../apache/avro/tool/TestSpecificCompilerTool.java | 12 +
pom.xml | 1 +
8 files changed, 734 insertions(+), 3 deletions(-)
diff --git a/lang/java/avro/src/main/java/org/apache/avro/Conversion.java
b/lang/java/avro/src/main/java/org/apache/avro/Conversion.java
index 9e036df..b0cf701 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/Conversion.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/Conversion.java
@@ -61,6 +61,19 @@ public abstract class Conversion<T> {
*/
public abstract String getLogicalTypeName();
+ /**
+ * Certain logical types may require adjusting the code within the "setter"
+ * methods to make sure the data that is set is properly formatted. This
method
+ * allows teh Conversion to generate custom setter code if required.
+ *
+ * @param varName
+ * @param valParamName
+ * @return a String for the body of the setter method
+ */
+ public String adjustAndSetValue(String varName, String valParamName) {
+ return varName + " = " + valParamName + ";";
+ }
+
public Schema getRecommendedSchema() {
throw new UnsupportedOperationException("No recommended schema for " +
getLogicalTypeName());
}
diff --git
a/lang/java/avro/src/main/java/org/apache/avro/data/Jsr310TimeConversions.java
b/lang/java/avro/src/main/java/org/apache/avro/data/Jsr310TimeConversions.java
index a717bbc..0f608dc 100644
---
a/lang/java/avro/src/main/java/org/apache/avro/data/Jsr310TimeConversions.java
+++
b/lang/java/avro/src/main/java/org/apache/avro/data/Jsr310TimeConversions.java
@@ -71,6 +71,11 @@ public class Jsr310TimeConversions {
}
@Override
+ public String adjustAndSetValue(String varName, String valParamName) {
+ return varName + " = " + valParamName +
".truncatedTo(java.time.temporal.ChronoUnit.MILLIS);";
+ }
+
+ @Override
public LocalTime fromInt(Integer millisFromMidnight, Schema schema,
LogicalType type) {
return
LocalTime.ofNanoOfDay(TimeUnit.MILLISECONDS.toNanos(millisFromMidnight));
}
@@ -98,6 +103,11 @@ public class Jsr310TimeConversions {
}
@Override
+ public String adjustAndSetValue(String varName, String valParamName) {
+ return varName + " = " + valParamName +
".truncatedTo(java.time.temporal.ChronoUnit.MICROS);";
+ }
+
+ @Override
public LocalTime fromLong(Long microsFromMidnight, Schema schema,
LogicalType type) {
return
LocalTime.ofNanoOfDay(TimeUnit.MICROSECONDS.toNanos(microsFromMidnight));
}
@@ -125,6 +135,11 @@ public class Jsr310TimeConversions {
}
@Override
+ public String adjustAndSetValue(String varName, String valParamName) {
+ return varName + " = " + valParamName +
".truncatedTo(java.time.temporal.ChronoUnit.MILLIS);";
+ }
+
+ @Override
public Instant fromLong(Long millisFromEpoch, Schema schema, LogicalType
type) {
return Instant.ofEpochMilli(millisFromEpoch);
}
@@ -152,6 +167,11 @@ public class Jsr310TimeConversions {
}
@Override
+ public String adjustAndSetValue(String varName, String valParamName) {
+ return varName + " = " + valParamName +
".truncatedTo(java.time.temporal.ChronoUnit.MICROS);";
+ }
+
+ @Override
public Instant fromLong(Long microsFromEpoch, Schema schema, LogicalType
type) {
long epochSeconds = microsFromEpoch / (1_000_000);
long nanoAdjustment = (microsFromEpoch % (1_000_000)) * 1_000;
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 cf86c5d..730a1e9 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
@@ -820,6 +820,17 @@ public class SpecificCompiler {
}
/**
+ * Utility for template use.
+ */
+ public String generateSetterCode(Schema schema, String name, String pname) {
+ Conversion<?> conversion =
specificData.getConversionFor(schema.getLogicalType());
+ if (conversion != null) {
+ return conversion.adjustAndSetValue("this." + name, pname);
+ }
+ return "this." + name + " = " + pname + ";";
+ }
+
+ /**
* Utility for template use. Returns the unboxed java type for a Schema.
*
* @Deprecated use javaUnbox(Schema, boolean), kept for backward
compatibiliby
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 23b5848..738ffac 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
@@ -152,7 +152,7 @@ static {
*/
public ${this.mangle($schema.getName())}(#foreach($field in
$schema.getFields())${this.javaType($field.schema())}
${this.mangle($field.name())}#if($foreach.count < $schema.getFields().size()),
#end#end) {
#foreach ($field in $schema.getFields())
- this.${this.mangle($field.name())} = ${this.mangle($field.name())};
+ ${this.generateSetterCode($field.schema(), ${this.mangle($field.name())},
${this.mangle($field.name())})}
#end
}
#else
@@ -251,7 +251,7 @@ static {
* @param value the value to set.
*/
public void ${this.generateSetMethod($schema,
$field)}(${this.javaUnbox($field.schema())} value) {
- this.${this.mangle($field.name(), $schema.isError())} = value;
+ ${this.generateSetterCode($field.schema(), ${this.mangle($field.name(),
$schema.isError())}, "value")}
}
#end
@@ -410,7 +410,7 @@ static {
#if (${this.hasBuilder($field.schema())})
this.${this.mangle($field.name(), $schema.isError())}Builder = null;
#end
- this.${this.mangle($field.name(), $schema.isError())} = value;
+ ${this.generateSetterCode($field.schema(), ${this.mangle($field.name(),
$schema.isError())}, "value")}
fieldSetFlags()[$field.pos()] = true;
return this;
}
diff --git a/lang/java/tools/src/test/compiler/input/fieldtest.avsc
b/lang/java/tools/src/test/compiler/input/fieldtest.avsc
new file mode 100644
index 0000000..fad6355
--- /dev/null
+++ b/lang/java/tools/src/test/compiler/input/fieldtest.avsc
@@ -0,0 +1,10 @@
+{"type":"record", "name":"FieldTest", "namespace":
"avro.examples.baseball","doc":"Test various field types",
+ "fields": [
+ {"name": "number", "type": "int", "doc": "The number of the player"},
+ {"name": "last_name", "type": "string"},
+ {"name": "timestamp", "type": { "type": "long", "logicalType":
"timestamp-millis"}},
+ {"name": "timestampMicros", "type": { "type": "long", "logicalType":
"timestamp-micros"}},
+ {"name": "timeMillis", "type": { "type": "int", "logicalType":
"time-millis"}},
+ {"name": "timeMicros", "type": { "type": "long", "logicalType":
"time-micros"}}
+ ]
+}
diff --git
a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/FieldTest.java
b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/FieldTest.java
new file mode 100644
index 0000000..5187554
--- /dev/null
+++
b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/FieldTest.java
@@ -0,0 +1,664 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package avro.examples.baseball;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+/** Test various field types */
[email protected]
+public class FieldTest extends org.apache.avro.specific.SpecificRecordBase
implements org.apache.avro.specific.SpecificRecord {
+ private static final long serialVersionUID = 4609235620572341636L;
+ public static final org.apache.avro.Schema SCHEMA$ = new
org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"FieldTest\",\"namespace\":\"avro.examples.baseball\",\"doc\":\"Test
various field
types\",\"fields\":[{\"name\":\"number\",\"type\":\"int\",\"doc\":\"The number
of the
player\"},{\"name\":\"last_name\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"timestamp\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"na
[...]
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+ private static SpecificData MODEL$ = new SpecificData();
+static {
+ MODEL$.addLogicalTypeConversion(new
org.apache.avro.data.Jsr310TimeConversions.TimestampMillisConversion());
+ MODEL$.addLogicalTypeConversion(new
org.apache.avro.data.Jsr310TimeConversions.TimeMillisConversion());
+ }
+
+ private static final BinaryMessageEncoder<FieldTest> ENCODER =
+ new BinaryMessageEncoder<FieldTest>(MODEL$, SCHEMA$);
+
+ private static final BinaryMessageDecoder<FieldTest> DECODER =
+ new BinaryMessageDecoder<FieldTest>(MODEL$, SCHEMA$);
+
+ /**
+ * Return the BinaryMessageEncoder instance used by this class.
+ * @return the message encoder used by this class
+ */
+ public static BinaryMessageEncoder<FieldTest> getEncoder() {
+ return ENCODER;
+ }
+
+ /**
+ * Return the BinaryMessageDecoder instance used by this class.
+ * @return the message decoder used by this class
+ */
+ public static BinaryMessageDecoder<FieldTest> getDecoder() {
+ return DECODER;
+ }
+
+ /**
+ * Create a new BinaryMessageDecoder instance for this class that uses the
specified {@link SchemaStore}.
+ * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+ * @return a BinaryMessageDecoder instance for this class backed by the
given SchemaStore
+ */
+ public static BinaryMessageDecoder<FieldTest> createDecoder(SchemaStore
resolver) {
+ return new BinaryMessageDecoder<FieldTest>(MODEL$, SCHEMA$, resolver);
+ }
+
+ /**
+ * Serializes this FieldTest to a ByteBuffer.
+ * @return a buffer holding the serialized data for this instance
+ * @throws java.io.IOException if this instance could not be serialized
+ */
+ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+ return ENCODER.encode(this);
+ }
+
+ /**
+ * Deserializes a FieldTest from a ByteBuffer.
+ * @param b a byte buffer holding serialized data for an instance of this
class
+ * @return a FieldTest instance decoded from the given buffer
+ * @throws java.io.IOException if the given bytes could not be deserialized
into an instance of this class
+ */
+ public static FieldTest fromByteBuffer(
+ java.nio.ByteBuffer b) throws java.io.IOException {
+ return DECODER.decode(b);
+ }
+
+ /** The number of the player */
+ private int number;
+ private java.lang.String last_name;
+ private java.time.Instant timestamp;
+ private java.time.Instant timestampMicros;
+ private java.time.LocalTime timeMillis;
+ private java.time.LocalTime timeMicros;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use <code>newBuilder()</code>.
+ */
+ public FieldTest() {}
+
+ /**
+ * All-args constructor.
+ * @param number The number of the player
+ * @param last_name The new value for last_name
+ * @param timestamp The new value for timestamp
+ * @param timestampMicros The new value for timestampMicros
+ * @param timeMillis The new value for timeMillis
+ * @param timeMicros The new value for timeMicros
+ */
+ public FieldTest(java.lang.Integer number, java.lang.String last_name,
java.time.Instant timestamp, java.time.Instant timestampMicros,
java.time.LocalTime timeMillis, java.time.LocalTime timeMicros) {
+ this.number = number;
+ this.last_name = last_name;
+ this.timestamp =
timestamp.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ this.timestampMicros =
timestampMicros.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ this.timeMillis =
timeMillis.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ this.timeMicros =
timeMicros.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ }
+
+ public org.apache.avro.specific.SpecificData getSpecificData() { return
MODEL$; }
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return number;
+ case 1: return last_name;
+ case 2: return timestamp;
+ case 3: return timestampMicros;
+ case 4: return timeMillis;
+ case 5: return timeMicros;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ private static final org.apache.avro.Conversion<?>[] conversions =
+ new org.apache.avro.Conversion<?>[] {
+ null,
+ null,
+ new
org.apache.avro.data.Jsr310TimeConversions.TimestampMillisConversion(),
+ new
org.apache.avro.data.Jsr310TimeConversions.TimestampMicrosConversion(),
+ new org.apache.avro.data.Jsr310TimeConversions.TimeMillisConversion(),
+ new org.apache.avro.data.Jsr310TimeConversions.TimeMicrosConversion(),
+ null
+ };
+
+ @Override
+ public org.apache.avro.Conversion<?> getConversion(int field) {
+ return conversions[field];
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: number = (java.lang.Integer)value$; break;
+ case 1: last_name = (java.lang.String)value$; break;
+ case 2: timestamp = (java.time.Instant)value$; break;
+ case 3: timestampMicros = (java.time.Instant)value$; break;
+ case 4: timeMillis = (java.time.LocalTime)value$; break;
+ case 5: timeMicros = (java.time.LocalTime)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'number' field.
+ * @return The number of the player
+ */
+ public int getNumber() {
+ return number;
+ }
+
+
+ /**
+ * Sets the value of the 'number' field.
+ * The number of the player
+ * @param value the value to set.
+ */
+ public void setNumber(int value) {
+ this.number = value;
+ }
+
+ /**
+ * Gets the value of the 'last_name' field.
+ * @return The value of the 'last_name' field.
+ */
+ public java.lang.String getLastName() {
+ return last_name;
+ }
+
+
+ /**
+ * Sets the value of the 'last_name' field.
+ * @param value the value to set.
+ */
+ public void setLastName(java.lang.String value) {
+ this.last_name = value;
+ }
+
+ /**
+ * Gets the value of the 'timestamp' field.
+ * @return The value of the 'timestamp' field.
+ */
+ public java.time.Instant getTimestamp() {
+ return timestamp;
+ }
+
+
+ /**
+ * Sets the value of the 'timestamp' field.
+ * @param value the value to set.
+ */
+ public void setTimestamp(java.time.Instant value) {
+ this.timestamp = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ }
+
+ /**
+ * Gets the value of the 'timestampMicros' field.
+ * @return The value of the 'timestampMicros' field.
+ */
+ public java.time.Instant getTimestampMicros() {
+ return timestampMicros;
+ }
+
+
+ /**
+ * Sets the value of the 'timestampMicros' field.
+ * @param value the value to set.
+ */
+ public void setTimestampMicros(java.time.Instant value) {
+ this.timestampMicros =
value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ }
+
+ /**
+ * Gets the value of the 'timeMillis' field.
+ * @return The value of the 'timeMillis' field.
+ */
+ public java.time.LocalTime getTimeMillis() {
+ return timeMillis;
+ }
+
+
+ /**
+ * Sets the value of the 'timeMillis' field.
+ * @param value the value to set.
+ */
+ public void setTimeMillis(java.time.LocalTime value) {
+ this.timeMillis = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ }
+
+ /**
+ * Gets the value of the 'timeMicros' field.
+ * @return The value of the 'timeMicros' field.
+ */
+ public java.time.LocalTime getTimeMicros() {
+ return timeMicros;
+ }
+
+
+ /**
+ * Sets the value of the 'timeMicros' field.
+ * @param value the value to set.
+ */
+ public void setTimeMicros(java.time.LocalTime value) {
+ this.timeMicros = value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ }
+
+ /**
+ * Creates a new FieldTest RecordBuilder.
+ * @return A new FieldTest RecordBuilder
+ */
+ public static avro.examples.baseball.FieldTest.Builder newBuilder() {
+ return new avro.examples.baseball.FieldTest.Builder();
+ }
+
+ /**
+ * Creates a new FieldTest RecordBuilder by copying an existing Builder.
+ * @param other The existing builder to copy.
+ * @return A new FieldTest RecordBuilder
+ */
+ public static avro.examples.baseball.FieldTest.Builder
newBuilder(avro.examples.baseball.FieldTest.Builder other) {
+ if (other == null) {
+ return new avro.examples.baseball.FieldTest.Builder();
+ } else {
+ return new avro.examples.baseball.FieldTest.Builder(other);
+ }
+ }
+
+ /**
+ * Creates a new FieldTest RecordBuilder by copying an existing FieldTest
instance.
+ * @param other The existing instance to copy.
+ * @return A new FieldTest RecordBuilder
+ */
+ public static avro.examples.baseball.FieldTest.Builder
newBuilder(avro.examples.baseball.FieldTest other) {
+ if (other == null) {
+ return new avro.examples.baseball.FieldTest.Builder();
+ } else {
+ return new avro.examples.baseball.FieldTest.Builder(other);
+ }
+ }
+
+ /**
+ * RecordBuilder for FieldTest instances.
+ */
+ public static class Builder extends
org.apache.avro.specific.SpecificRecordBuilderBase<FieldTest>
+ implements org.apache.avro.data.RecordBuilder<FieldTest> {
+
+ /** The number of the player */
+ private int number;
+ private java.lang.String last_name;
+ private java.time.Instant timestamp;
+ private java.time.Instant timestampMicros;
+ private java.time.LocalTime timeMillis;
+ private java.time.LocalTime timeMicros;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(SCHEMA$);
+ }
+
+ /**
+ * Creates a Builder by copying an existing Builder.
+ * @param other The existing Builder to copy.
+ */
+ private Builder(avro.examples.baseball.FieldTest.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.number)) {
+ this.number = data().deepCopy(fields()[0].schema(), other.number);
+ fieldSetFlags()[0] = other.fieldSetFlags()[0];
+ }
+ if (isValidValue(fields()[1], other.last_name)) {
+ this.last_name = data().deepCopy(fields()[1].schema(),
other.last_name);
+ fieldSetFlags()[1] = other.fieldSetFlags()[1];
+ }
+ if (isValidValue(fields()[2], other.timestamp)) {
+ this.timestamp = data().deepCopy(fields()[2].schema(),
other.timestamp);
+ fieldSetFlags()[2] = other.fieldSetFlags()[2];
+ }
+ if (isValidValue(fields()[3], other.timestampMicros)) {
+ this.timestampMicros = data().deepCopy(fields()[3].schema(),
other.timestampMicros);
+ fieldSetFlags()[3] = other.fieldSetFlags()[3];
+ }
+ if (isValidValue(fields()[4], other.timeMillis)) {
+ this.timeMillis = data().deepCopy(fields()[4].schema(),
other.timeMillis);
+ fieldSetFlags()[4] = other.fieldSetFlags()[4];
+ }
+ if (isValidValue(fields()[5], other.timeMicros)) {
+ this.timeMicros = data().deepCopy(fields()[5].schema(),
other.timeMicros);
+ fieldSetFlags()[5] = other.fieldSetFlags()[5];
+ }
+ }
+
+ /**
+ * Creates a Builder by copying an existing FieldTest instance
+ * @param other The existing instance to copy.
+ */
+ private Builder(avro.examples.baseball.FieldTest other) {
+ super(SCHEMA$);
+ if (isValidValue(fields()[0], other.number)) {
+ this.number = data().deepCopy(fields()[0].schema(), other.number);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.last_name)) {
+ this.last_name = data().deepCopy(fields()[1].schema(),
other.last_name);
+ fieldSetFlags()[1] = true;
+ }
+ if (isValidValue(fields()[2], other.timestamp)) {
+ this.timestamp = data().deepCopy(fields()[2].schema(),
other.timestamp);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.timestampMicros)) {
+ this.timestampMicros = data().deepCopy(fields()[3].schema(),
other.timestampMicros);
+ fieldSetFlags()[3] = true;
+ }
+ if (isValidValue(fields()[4], other.timeMillis)) {
+ this.timeMillis = data().deepCopy(fields()[4].schema(),
other.timeMillis);
+ fieldSetFlags()[4] = true;
+ }
+ if (isValidValue(fields()[5], other.timeMicros)) {
+ this.timeMicros = data().deepCopy(fields()[5].schema(),
other.timeMicros);
+ fieldSetFlags()[5] = true;
+ }
+ }
+
+ /**
+ * Gets the value of the 'number' field.
+ * The number of the player
+ * @return The value.
+ */
+ public int getNumber() {
+ return number;
+ }
+
+
+ /**
+ * Sets the value of the 'number' field.
+ * The number of the player
+ * @param value The value of 'number'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder setNumber(int value) {
+ validate(fields()[0], value);
+ this.number = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'number' field has been set.
+ * The number of the player
+ * @return True if the 'number' field has been set, false otherwise.
+ */
+ public boolean hasNumber() {
+ return fieldSetFlags()[0];
+ }
+
+
+ /**
+ * Clears the value of the 'number' field.
+ * The number of the player
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearNumber() {
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'last_name' field.
+ * @return The value.
+ */
+ public java.lang.String getLastName() {
+ return last_name;
+ }
+
+
+ /**
+ * Sets the value of the 'last_name' field.
+ * @param value The value of 'last_name'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder
setLastName(java.lang.String value) {
+ validate(fields()[1], value);
+ this.last_name = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'last_name' field has been set.
+ * @return True if the 'last_name' field has been set, false otherwise.
+ */
+ public boolean hasLastName() {
+ return fieldSetFlags()[1];
+ }
+
+
+ /**
+ * Clears the value of the 'last_name' field.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearLastName() {
+ last_name = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'timestamp' field.
+ * @return The value.
+ */
+ public java.time.Instant getTimestamp() {
+ return timestamp;
+ }
+
+
+ /**
+ * Sets the value of the 'timestamp' field.
+ * @param value The value of 'timestamp'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder
setTimestamp(java.time.Instant value) {
+ validate(fields()[2], value);
+ this.timestamp = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ fieldSetFlags()[2] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'timestamp' field has been set.
+ * @return True if the 'timestamp' field has been set, false otherwise.
+ */
+ public boolean hasTimestamp() {
+ return fieldSetFlags()[2];
+ }
+
+
+ /**
+ * Clears the value of the 'timestamp' field.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearTimestamp() {
+ fieldSetFlags()[2] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'timestampMicros' field.
+ * @return The value.
+ */
+ public java.time.Instant getTimestampMicros() {
+ return timestampMicros;
+ }
+
+
+ /**
+ * Sets the value of the 'timestampMicros' field.
+ * @param value The value of 'timestampMicros'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder
setTimestampMicros(java.time.Instant value) {
+ validate(fields()[3], value);
+ this.timestampMicros =
value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ fieldSetFlags()[3] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'timestampMicros' field has been set.
+ * @return True if the 'timestampMicros' field has been set, false
otherwise.
+ */
+ public boolean hasTimestampMicros() {
+ return fieldSetFlags()[3];
+ }
+
+
+ /**
+ * Clears the value of the 'timestampMicros' field.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearTimestampMicros() {
+ fieldSetFlags()[3] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'timeMillis' field.
+ * @return The value.
+ */
+ public java.time.LocalTime getTimeMillis() {
+ return timeMillis;
+ }
+
+
+ /**
+ * Sets the value of the 'timeMillis' field.
+ * @param value The value of 'timeMillis'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder
setTimeMillis(java.time.LocalTime value) {
+ validate(fields()[4], value);
+ this.timeMillis =
value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ fieldSetFlags()[4] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'timeMillis' field has been set.
+ * @return True if the 'timeMillis' field has been set, false otherwise.
+ */
+ public boolean hasTimeMillis() {
+ return fieldSetFlags()[4];
+ }
+
+
+ /**
+ * Clears the value of the 'timeMillis' field.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearTimeMillis() {
+ fieldSetFlags()[4] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'timeMicros' field.
+ * @return The value.
+ */
+ public java.time.LocalTime getTimeMicros() {
+ return timeMicros;
+ }
+
+
+ /**
+ * Sets the value of the 'timeMicros' field.
+ * @param value The value of 'timeMicros'.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder
setTimeMicros(java.time.LocalTime value) {
+ validate(fields()[5], value);
+ this.timeMicros =
value.truncatedTo(java.time.temporal.ChronoUnit.MICROS);
+ fieldSetFlags()[5] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'timeMicros' field has been set.
+ * @return True if the 'timeMicros' field has been set, false otherwise.
+ */
+ public boolean hasTimeMicros() {
+ return fieldSetFlags()[5];
+ }
+
+
+ /**
+ * Clears the value of the 'timeMicros' field.
+ * @return This builder.
+ */
+ public avro.examples.baseball.FieldTest.Builder clearTimeMicros() {
+ fieldSetFlags()[5] = false;
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public FieldTest build() {
+ try {
+ FieldTest record = new FieldTest();
+ record.number = fieldSetFlags()[0] ? this.number : (java.lang.Integer)
defaultValue(fields()[0]);
+ record.last_name = fieldSetFlags()[1] ? this.last_name :
(java.lang.String) defaultValue(fields()[1]);
+ record.timestamp = fieldSetFlags()[2] ? this.timestamp :
(java.time.Instant) defaultValue(fields()[2]);
+ record.timestampMicros = fieldSetFlags()[3] ? this.timestampMicros :
(java.time.Instant) defaultValue(fields()[3]);
+ record.timeMillis = fieldSetFlags()[4] ? this.timeMillis :
(java.time.LocalTime) defaultValue(fields()[4]);
+ record.timeMicros = fieldSetFlags()[5] ? this.timeMicros :
(java.time.LocalTime) defaultValue(fields()[5]);
+ return record;
+ } catch (org.apache.avro.AvroMissingFieldException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumWriter<FieldTest>
+ WRITER$ =
(org.apache.avro.io.DatumWriter<FieldTest>)MODEL$.createDatumWriter(SCHEMA$);
+
+ @Override public void writeExternal(java.io.ObjectOutput out)
+ throws java.io.IOException {
+ WRITER$.write(this, SpecificData.getEncoder(out));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumReader<FieldTest>
+ READER$ =
(org.apache.avro.io.DatumReader<FieldTest>)MODEL$.createDatumReader(SCHEMA$);
+
+ @Override public void readExternal(java.io.ObjectInput in)
+ throws java.io.IOException {
+ READER$.read(this, SpecificData.getDecoder(in));
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
diff --git
a/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java
b/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java
index 85aec64..cc5c38f 100644
---
a/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java
+++
b/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java
@@ -49,6 +49,8 @@ public class TestSpecificCompilerTool {
"avro/examples/baseball/Position.java");
private static final File TEST_EXPECTED_STRING_PLAYER = new
File(TEST_EXPECTED_STRING_OUTPUT_DIR,
"avro/examples/baseball/Player.java");
+ private static final File TEST_EXPECTED_STRING_FIELDTEST = new
File(TEST_EXPECTED_STRING_OUTPUT_DIR,
+ "avro/examples/baseball/FieldTest.java");
// where test output goes
private static final File TEST_OUTPUT_DIR = new
File("target/compiler/output");
@@ -60,6 +62,8 @@ public class TestSpecificCompilerTool {
"avro/examples/baseball/Player.java");
private static final File TEST_OUTPUT_STRING_POSITION = new
File(TEST_OUTPUT_STRING_DIR,
"avro/examples/baseball/Position.java");
+ private static final File TEST_OUTPUT_STRING_FIELDTEST = new
File(TEST_OUTPUT_STRING_DIR,
+ "avro/examples/baseball/FieldTest.java");
@Before
public void setUp() {
@@ -101,6 +105,14 @@ public class TestSpecificCompilerTool {
assertFileMatch(TEST_EXPECTED_STRING_PLAYER, TEST_OUTPUT_STRING_PLAYER);
}
+ @Test
+ public void testCompileSchemasWithVariousFieldTypes() throws Exception {
+
+ doCompile(new String[] { "-encoding", "UTF-8", "-string", "schema",
TEST_INPUT_DIR.toString() + "/fieldtest.avsc",
+ TEST_INPUT_DIR.toString() + "/fieldtest.avsc",
TEST_OUTPUT_STRING_DIR.getPath() });
+ assertFileMatch(TEST_EXPECTED_STRING_FIELDTEST,
TEST_OUTPUT_STRING_FIELDTEST);
+ }
+
// Runs the actual compiler tool with the given input args
private void doCompile(String[] args) throws Exception {
SpecificCompilerTool tool = new SpecificCompilerTool();
diff --git a/pom.xml b/pom.xml
index 4f76d42..6e52c34 100644
--- a/pom.xml
+++ b/pom.xml
@@ -291,6 +291,7 @@
<exclude>lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithoutLogicalTypes.java</exclude>
<exclude>lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java</exclude>
<exclude>lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Position.java</exclude>
+
<exclude>lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/FieldTest.java</exclude>
<exclude>lang/java/tools/src/test/compiler/output-string/Position.java</exclude>
<exclude>lang/java/tools/src/test/compiler/output/Player.java</exclude>
<exclude>lang/java/tools/src/test/compiler/output/Position.java</exclude>