Skip to content

Commit 864f1a2

Browse files
committed
Start 2.10 with builder()-based factory creation
1 parent a9f07bc commit 864f1a2

File tree

22 files changed

+727
-30
lines changed

22 files changed

+727
-30
lines changed

avro/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.fasterxml.jackson.dataformat</groupId>
66
<artifactId>jackson-dataformats-binary</artifactId>
7-
<version>2.9.7-SNAPSHOT</version>
7+
<version>2.10.0-SNAPSHOT</version>
88
</parent>
99
<artifactId>jackson-dataformat-avro</artifactId>
1010
<name>Jackson dataformat: Avro</name>

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/AvroFactory.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,15 @@ public class AvroFactory extends JsonFactory
4343
protected int _avroParserFeatures;
4444

4545
protected int _avroGeneratorFeatures;
46-
46+
47+
/**
48+
* Flag that is set if Apache Avro lib's decoder is to be used for decoding;
49+
* `false` to use Jackson native Avro decoder.
50+
*
51+
* @since 2.9
52+
*/
53+
protected boolean _useApacheLibDecoder;
54+
4755
/*
4856
/**********************************************************
4957
/* Factory construction, configuration
@@ -60,7 +68,13 @@ public class AvroFactory extends JsonFactory
6068
* and this reuse only works within context of a single
6169
* factory instance.
6270
*/
63-
public AvroFactory() { this(null); }
71+
public AvroFactory() {
72+
// 09-Jan-2017, tatu: We must actually create and pass builder to be able to change
73+
// one of JsonGenerator.Features (See builder for details)
74+
super(new AvroFactoryBuilder(), false);
75+
_avroParserFeatures = DEFAULT_AVRO_PARSER_FEATURE_FLAGS;
76+
_avroGeneratorFeatures = DEFAULT_AVRO_GENERATOR_FEATURE_FLAGS;
77+
}
6478

6579
public AvroFactory(ObjectCodec oc)
6680
{
@@ -84,6 +98,54 @@ protected AvroFactory(AvroFactory src, ObjectCodec oc)
8498
_avroGeneratorFeatures = src._avroGeneratorFeatures;
8599
}
86100

101+
/**
102+
* Constructors used by {@link YAMLFactoryBuilder} for instantiation.
103+
*
104+
* @since 2.9
105+
*/
106+
protected AvroFactory(AvroFactoryBuilder b)
107+
{
108+
super(b, false);
109+
_avroParserFeatures = b.formatParserFeaturesMask();
110+
_avroGeneratorFeatures = b.formatGeneratorFeaturesMask();
111+
_useApacheLibDecoder = b.useApacheLibDecoder();
112+
}
113+
114+
@Override
115+
public AvroFactoryBuilder rebuild() {
116+
return new AvroFactoryBuilder(this);
117+
}
118+
119+
/**
120+
* Main factory method to use for constructing a builder for creating
121+
* {@link AvroFactory} instances with different configuration.
122+
* Builder is initialized to defaults and this is equivalent to calling
123+
* {@link #builderWithNativeDecoder}.
124+
*/
125+
public static AvroFactoryBuilder builder() {
126+
return new AvroFactoryBuilder();
127+
}
128+
129+
/**
130+
* Main factory method to use for constructing a builder for creating
131+
* {@link AvroFactory} instances with different configuration,
132+
* initialized to use Apache Avro library codec for decoding content
133+
* (instead of Jackson native decoder).
134+
*/
135+
public static AvroFactoryBuilder builderWithApacheDecoder() {
136+
return new AvroFactoryBuilder(true);
137+
}
138+
139+
/**
140+
* Main factory method to use for constructing a builder for creating
141+
* {@link AvroFactory} instances with different configuration,
142+
* initialized to use Jackson antive codec for decoding content
143+
* (instead of Apache Avro library decoder).
144+
*/
145+
public static AvroFactoryBuilder builderWithNativeDecoder() {
146+
return new AvroFactoryBuilder(false);
147+
}
148+
87149
@Override
88150
public AvroFactory copy()
89151
{
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.fasterxml.jackson.dataformat.avro;
2+
3+
import com.fasterxml.jackson.core.JsonGenerator;
4+
import com.fasterxml.jackson.core.TSFBuilder;
5+
import com.fasterxml.jackson.dataformat.avro.AvroFactoryBuilder;
6+
7+
/**
8+
* {@link com.fasterxml.jackson.core.TSFBuilder}
9+
* implementation for constructing {@link AvroFactory}
10+
* instances.
11+
*<p>
12+
* Note: one of standard features,
13+
* {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_JSON_CONTENT},
14+
* is disabled by default, as it does not play well with error handling. It may be
15+
* forcibly enabled (if there is ever reason to do so), just defaults to {@code false}.
16+
*
17+
* @since 3.0
18+
*/
19+
public class AvroFactoryBuilder extends TSFBuilder<AvroFactory, AvroFactoryBuilder>
20+
{
21+
/*
22+
/**********************************************************
23+
/* Configuration
24+
/**********************************************************
25+
*/
26+
27+
/**
28+
* Set of {@link AvroParser.Feature}s enabled, as bitmask.
29+
*/
30+
protected int _formatParserFeatures;
31+
32+
/**
33+
* Set of {@link AvroGenerator.Feature}s enabled, as bitmask.
34+
*/
35+
protected int _formatGeneratorFeatures;
36+
37+
/**
38+
* Flag that is set if Apache Avro lib's decoder is to be used for decoding;
39+
* `false` to use Jackson native Avro decoder.
40+
*/
41+
protected boolean _useApacheLibDecoder;
42+
43+
/*
44+
/**********************************************************
45+
/* Life cycle
46+
/**********************************************************
47+
*/
48+
49+
protected AvroFactoryBuilder() {
50+
// default is to use native Jackson Avro decoder
51+
this(false);
52+
}
53+
54+
protected AvroFactoryBuilder(boolean useApacheDecoder) {
55+
super();
56+
_formatParserFeatures = AvroFactory.DEFAULT_AVRO_PARSER_FEATURE_FLAGS;
57+
_formatGeneratorFeatures = AvroFactory.DEFAULT_AVRO_GENERATOR_FEATURE_FLAGS;
58+
_useApacheLibDecoder = useApacheDecoder;
59+
60+
// 04-Mar-2013, tatu: Content auto-closing is unfortunately a feature
61+
// that works poorly with Avro error reporting, and generally
62+
// manages to replace actual failure with a bogus one when
63+
// missing "END_OBJECT"s (etc) are called. So let's default
64+
// it to disabled, unlike for most JsonFactory sub-types.
65+
_generatorFeatures &= ~JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT.getMask();
66+
}
67+
68+
public AvroFactoryBuilder(AvroFactory base) {
69+
super(base);
70+
_formatParserFeatures = base._avroParserFeatures;
71+
_formatGeneratorFeatures = base._avroGeneratorFeatures;
72+
}
73+
74+
@Override
75+
public AvroFactory build() {
76+
// 28-Dec-2017, tatu: No special settings beyond base class ones, so:
77+
return new AvroFactory(this);
78+
}
79+
80+
/*
81+
/**********************************************************
82+
/* Accessors
83+
/**********************************************************
84+
*/
85+
86+
public int formatParserFeaturesMask() { return _formatParserFeatures; }
87+
public int formatGeneratorFeaturesMask() { return _formatGeneratorFeatures; }
88+
89+
public boolean useApacheLibDecoder() { return _useApacheLibDecoder; }
90+
91+
/*
92+
/**********************************************************
93+
/* Mutators
94+
/**********************************************************
95+
*/
96+
97+
98+
// // // Parser features
99+
100+
public AvroFactoryBuilder enable(AvroParser.Feature f) {
101+
_formatParserFeatures |= f.getMask();
102+
return _this();
103+
}
104+
105+
public AvroFactoryBuilder enable(AvroParser.Feature first, AvroParser.Feature... other) {
106+
_formatParserFeatures |= first.getMask();
107+
for (AvroParser.Feature f : other) {
108+
_formatParserFeatures |= f.getMask();
109+
}
110+
return _this();
111+
}
112+
113+
public AvroFactoryBuilder disable(AvroParser.Feature f) {
114+
_formatParserFeatures &= ~f.getMask();
115+
return _this();
116+
}
117+
118+
public AvroFactoryBuilder disable(AvroParser.Feature first, AvroParser.Feature... other) {
119+
_formatParserFeatures &= ~first.getMask();
120+
for (AvroParser.Feature f : other) {
121+
_formatParserFeatures &= ~f.getMask();
122+
}
123+
return _this();
124+
}
125+
126+
public AvroFactoryBuilder configure(AvroParser.Feature f, boolean state) {
127+
return state ? enable(f) : disable(f);
128+
}
129+
130+
// // // Generator features
131+
132+
public AvroFactoryBuilder enable(AvroGenerator.Feature f) {
133+
_formatGeneratorFeatures |= f.getMask();
134+
return _this();
135+
}
136+
137+
public AvroFactoryBuilder enable(AvroGenerator.Feature first, AvroGenerator.Feature... other) {
138+
_formatGeneratorFeatures |= first.getMask();
139+
for (AvroGenerator.Feature f : other) {
140+
_formatGeneratorFeatures |= f.getMask();
141+
}
142+
return _this();
143+
}
144+
145+
public AvroFactoryBuilder disable(AvroGenerator.Feature f) {
146+
_formatGeneratorFeatures &= ~f.getMask();
147+
return _this();
148+
}
149+
150+
public AvroFactoryBuilder disable(AvroGenerator.Feature first, AvroGenerator.Feature... other) {
151+
_formatGeneratorFeatures &= ~first.getMask();
152+
for (AvroGenerator.Feature f : other) {
153+
_formatGeneratorFeatures &= ~f.getMask();
154+
}
155+
return _this();
156+
}
157+
158+
public AvroFactoryBuilder configure(AvroGenerator.Feature f, boolean state) {
159+
return state ? enable(f) : disable(f);
160+
}
161+
}

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/AvroSchema.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.concurrent.atomic.AtomicReference;
55

66
import org.apache.avro.Schema;
7-
import org.apache.avro.Schema.Type;
87
import org.apache.avro.SchemaCompatibility;
98
import org.apache.avro.SchemaCompatibility.SchemaCompatibilityType;
109
import org.apache.avro.SchemaCompatibility.SchemaPairCompatibility;

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/deser/AvroParserImpl.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
public abstract class AvroParserImpl
1717
extends AvroParser
1818
{
19-
protected final static byte[] NO_BYTES = new byte[0];
20-
2119
/*
2220
/**********************************************************
2321
/* Other decoding state

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/interop/ApacheAvroInteropUtil.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,26 @@ protected Schema createSchema(Type type, Map<String, Schema> names) {
106106
((Map) names).put(genericParameters[i], createSchema(boundParameters[i], new HashMap<>(names)));
107107
}
108108
}
109-
}
110-
if (type instanceof Class<?> && ((Class<?>) type).getSuperclass() != null && !Enum.class.isAssignableFrom((Class<?>) type)) {
111-
// Raw class may extend a generic superclass
112-
// extract all the type bindings and add them to the map so they can be returned by the next block
113-
// Interfaces shouldn't matter here because interfaces can't have fields and avro only looks at fields.
114-
TypeVariable<?>[] genericParameters = ((Class<?>) type).getSuperclass().getTypeParameters();
115-
if (genericParameters.length > 0) {
116-
Type[] boundParameters = ((ParameterizedType) ((Class<?>) type).getGenericSuperclass()).getActualTypeArguments();
117-
for (int i = 0; i < boundParameters.length; i++) {
118-
((Map) names).put(genericParameters[i], createSchema(boundParameters[i], new HashMap<>(names)));
109+
} else if (type instanceof Class<?>) {
110+
Class<?> cls = (Class<?>) type;
111+
if (cls.getSuperclass() != null && !Enum.class.isAssignableFrom(cls)) {
112+
// Raw class may extend a generic superclass
113+
// extract all the type bindings and add them to the map so they can be returned by the next block
114+
// Interfaces shouldn't matter here because interfaces can't have fields and avro only looks at fields.
115+
TypeVariable<?>[] genericParameters = cls.getSuperclass().getTypeParameters();
116+
if (genericParameters.length > 0) {
117+
Type[] boundParameters = ((ParameterizedType) cls.getGenericSuperclass()).getActualTypeArguments();
118+
for (int i = 0; i < boundParameters.length; i++) {
119+
((Map) names).put(genericParameters[i], createSchema(boundParameters[i], new HashMap<>(names)));
120+
}
119121
}
120122
}
121-
}
122-
if (type instanceof TypeVariable) {
123+
} else if (type instanceof TypeVariable) {
123124
// Should only get here by recursion normally; names should be populated with the schema for this type variable by a
124125
// previous stack frame
126+
/* 14-Jun-2018, tatu: This is 99.9% certainly wrong; IDE gives warnings and
127+
* it just... doesn't fly. Either keys are NOT Strings or...
128+
*/
125129
if (names.containsKey(type)) {
126130
return names.get(type);
127131
}

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/schema/TestSimpleGeneration.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.fasterxml.jackson.annotation.JsonProperty;
88
import com.fasterxml.jackson.annotation.JsonValue;
99

10-
import com.fasterxml.jackson.databind.ObjectMapper;
1110
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
1211
import com.fasterxml.jackson.dataformat.avro.*;
1312

cbor/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.fasterxml.jackson.dataformat</groupId>
66
<artifactId>jackson-dataformats-binary</artifactId>
7-
<version>2.9.7-SNAPSHOT</version>
7+
<version>2.10.0-SNAPSHOT</version>
88
</parent>
99
<artifactId>jackson-dataformat-cbor</artifactId>
1010
<name>Jackson dataformat: CBOR</name>

cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORFactory.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public class CBORFactory extends JsonFactory
7676
* and this reuse only works within context of a single
7777
* factory instance.
7878
*/
79-
public CBORFactory() { this(null); }
79+
public CBORFactory() { this((ObjectCodec) null); }
8080

8181
public CBORFactory(ObjectCodec oc) {
8282
super(oc);
@@ -97,6 +97,30 @@ public CBORFactory(CBORFactory src, ObjectCodec oc)
9797
_formatGeneratorFeatures = src._formatGeneratorFeatures;
9898
}
9999

100+
/**
101+
* Constructors used by {@link CBORFactoryBuilder} for instantiation.
102+
*
103+
* @since 3.0
104+
*/
105+
protected CBORFactory(CBORFactoryBuilder b) {
106+
super(b, false);
107+
_formatParserFeatures = b.formatParserFeaturesMask();
108+
_formatGeneratorFeatures = b.formatGeneratorFeaturesMask();
109+
}
110+
111+
@Override
112+
public CBORFactoryBuilder rebuild() {
113+
return new CBORFactoryBuilder(this);
114+
}
115+
116+
/**
117+
* Main factory method to use for constructing {@link CBORFactory} instances with
118+
* different configuration.
119+
*/
120+
public static CBORFactoryBuilder builder() {
121+
return new CBORFactoryBuilder();
122+
}
123+
100124
@Override
101125
public CBORFactory copy()
102126
{

0 commit comments

Comments
 (0)