Skip to content

Commit 57f811b

Browse files
committed
Start fixing #39, fix first verified problems (possibly not full)
1 parent 08468c2 commit 57f811b

File tree

6 files changed

+99
-12
lines changed

6 files changed

+99
-12
lines changed

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,33 @@ public String getSchemaType() {
3636

3737
public Schema getAvroSchema() { return _avroSchema; }
3838

39+
/**
40+
* Method that will consider this schema instance (used as so-called "Writer Schema"),
41+
* and specified "Reader Schema" instance, and will either construct a new schema
42+
* with appropriate translations, to use for reading (if reader and writer schemas are
43+
* not same); or, if schemas are the same, return `this`.
44+
*<p>
45+
* Note that neither `this` instance nor `readerSchema` is ever modified: if an altered
46+
* version is needed, a new schema object will be constructed.
47+
*
48+
* @param readerSchema "Reader Schema" to use (in Avro terms): schema that specified how
49+
* reader wants to see the data; specifies part of translation needed along with this
50+
* schema (which would be "Writer Schema" in Avro terms).
51+
*
52+
* @since 2.9
53+
*/
54+
public AvroSchema withReaderSchema(AvroSchema readerSchema) {
55+
Schema w = _avroSchema;
56+
Schema r = readerSchema.getAvroSchema();
57+
58+
if (r.equals(w)) {
59+
return this;
60+
}
61+
Schema newSchema = Schema.applyAliases(w, r);
62+
System.err.println("Translated schema ->\n"+newSchema.toString(true));
63+
return new AvroSchema(newSchema);
64+
}
65+
3966
public AvroStructureReader getReader()
4067
{
4168
AvroStructureReader r = _reader.get();
@@ -46,4 +73,22 @@ public AvroStructureReader getReader()
4673
}
4774
return r;
4875
}
76+
77+
@Override
78+
public String toString() {
79+
return String.format("{AvroSchema: name=%s}", _avroSchema.getFullName());
80+
}
81+
82+
@Override
83+
public int hashCode() {
84+
return _avroSchema.hashCode();
85+
}
86+
87+
@Override
88+
public boolean equals(Object o) {
89+
if (o == this) return true;
90+
if ((o == null) || o.getClass() != getClass()) return false;
91+
AvroSchema other = (AvroSchema) o;
92+
return _avroSchema.equals(other._avroSchema);
93+
}
4994
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
import org.apache.avro.Schema;
1111
import org.apache.avro.io.BinaryDecoder;
1212

13+
/**
14+
* Helper classes for reading non-structured values, and can thereby usually
15+
* be accessed using simpler interface (although sometimes not: if so,
16+
* instances are wrapped in <code>ScalarReaderWrapper</code>s).
17+
*/
1318
public abstract class AvroScalarReader
1419
{
1520
protected abstract JsonToken readValue(AvroParserImpl parser, BinaryDecoder decoder)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public JsonToken nextToken() throws IOException
5858
switch (_state) {
5959
case STATE_START:
6060
_parser.setAvroContext(this);
61-
_count = _decoder.readArrayStart();
61+
_count = _decoder.readMapStart();
6262
_state = (_count > 0) ? STATE_NAME : STATE_END;
6363
return (_currToken = JsonToken.START_OBJECT);
6464
case STATE_NAME:
@@ -68,7 +68,7 @@ public JsonToken nextToken() throws IOException
6868
return (_currToken = JsonToken.FIELD_NAME);
6969
}
7070
// need more data...
71-
_count = _decoder.arrayNext();
71+
_count = _decoder.mapNext();
7272
// more stuff?
7373
if (_count > 0L) {
7474
_index = 0;

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,24 @@ final class ScalarReaderWrapper extends AvroStructureReader
1414
private final boolean _rootReader;
1515

1616
public ScalarReaderWrapper(AvroScalarReader wrappedReader) {
17-
this(wrappedReader, null, null, false);
17+
this(null, null, null, wrappedReader, false);
1818
}
1919

20-
private ScalarReaderWrapper(AvroScalarReader wrappedReader,
21-
AvroParserImpl parser, BinaryDecoder decoder, boolean root) {
22-
super(null, TYPE_ROOT);
20+
private ScalarReaderWrapper(AvroReadContext parent,
21+
AvroParserImpl parser, BinaryDecoder decoder,
22+
AvroScalarReader wrappedReader, boolean rootReader)
23+
{
24+
super(parent, TYPE_ROOT);
2325
_wrappedReader = wrappedReader;
2426
_parser = parser;
2527
_decoder = decoder;
26-
_rootReader = root;
28+
_rootReader = rootReader;
2729
}
2830

2931
@Override
3032
public ScalarReaderWrapper newReader(AvroReadContext parent,
3133
AvroParserImpl parser, BinaryDecoder decoder) {
32-
return new ScalarReaderWrapper(_wrappedReader, parser, decoder, parent.inRoot());
34+
return new ScalarReaderWrapper(parent, parser, decoder, _wrappedReader, parent.inRoot());
3335
}
3436

3537
@Override
@@ -41,6 +43,7 @@ public JsonToken nextToken() throws IOException
4143
if (_rootReader && _decoder.isEnd()) {
4244
return (_currToken = null);
4345
}
46+
_parser.setAvroContext(getParent());
4447
return (_currToken = _wrappedReader.readValue(_parser, _decoder));
4548
}
4649

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ public JsonToken nextToken() throws IOException
5151
// also: must pass our parent (not this instance)
5252
_currentReader = _memberReaders[index].newReader(_parent, _parser, _decoder);
5353
}
54-
JsonToken t = _currentReader.nextToken();
55-
_currToken = t;
56-
return t;
54+
return (_currToken = _currentReader.nextToken());
5755
}
5856

5957
@Override
@@ -66,4 +64,4 @@ public String nextFieldName() throws IOException {
6664
protected void appendDesc(StringBuilder sb) {
6765
sb.append('?');
6866
}
69-
}
67+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.fasterxml.jackson.dataformat.avro;
2+
3+
import java.util.*;
4+
5+
public class MapWithUnionTest extends AvroTestBase
6+
{
7+
protected final String MAP_WITH_UNION_SCHEMA_JSON = aposToQuotes(
8+
"{"
9+
+"'name': 'Map',\n"
10+
+"'type': 'map',\n"
11+
+"'values': [ 'string', {\n"
12+
+ " 'type' : 'map', 'values' : 'string' \n"
13+
+ " }\n"
14+
+ " ] \n"
15+
+"}\n");
16+
17+
private final AvroMapper MAPPER = getMapper();
18+
19+
public void testRecordWithMap() throws Exception
20+
{
21+
AvroSchema schema = MAPPER.schemaFrom(MAP_WITH_UNION_SCHEMA_JSON);
22+
Map<String,Object> input = new LinkedHashMap<String,Object>();
23+
input.put("a", "123");
24+
input.put("xy", "foobar");
25+
byte[] avro = MAPPER.writer(schema)
26+
.writeValueAsBytes(input);
27+
28+
Map<String,Object> result = MAPPER.readerFor(Map.class)
29+
.with(schema)
30+
.readValue(avro);
31+
32+
assertEquals(2, result.size());
33+
assertEquals("123", result.get("a"));
34+
assertEquals("foobar", result.get("xy"));
35+
}
36+
}

0 commit comments

Comments
 (0)