Skip to content

Commit 26b15f3

Browse files
committed
Refactor: Extract superclass from IterableCodec and MapCodec
1 parent fc342ff commit 26b15f3

6 files changed

+167
-151
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.bson.codecs;
18+
19+
import org.bson.BsonReader;
20+
import org.bson.BsonType;
21+
import org.bson.BsonWriter;
22+
23+
import java.util.ArrayList;
24+
import java.util.List;
25+
26+
abstract class AbstractIterableCodec<T> implements Codec<Iterable<T>> {
27+
28+
abstract T readValue(BsonReader reader, DecoderContext decoderContext);
29+
30+
abstract void writeValue(BsonWriter writer, T cur, EncoderContext encoderContext);
31+
32+
@Override
33+
public Iterable<T> decode(final BsonReader reader, final DecoderContext decoderContext) {
34+
reader.readStartArray();
35+
36+
List<T> list = new ArrayList<>();
37+
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
38+
if (reader.getCurrentBsonType() == BsonType.NULL) {
39+
reader.readNull();
40+
list.add(null);
41+
} else {
42+
list.add(readValue(reader, decoderContext));
43+
}
44+
}
45+
46+
reader.readEndArray();
47+
48+
return list;
49+
}
50+
51+
@Override
52+
public void encode(final BsonWriter writer, final Iterable<T> value, final EncoderContext encoderContext) {
53+
writer.writeStartArray();
54+
for (final T cur : value) {
55+
if (cur == null) {
56+
writer.writeNull();
57+
} else {
58+
writeValue(writer, cur, encoderContext);
59+
}
60+
}
61+
writer.writeEndArray();
62+
}
63+
64+
@SuppressWarnings({"unchecked", "rawtypes"})
65+
@Override
66+
public Class<Iterable<T>> getEncoderClass() {
67+
return (Class<Iterable<T>>) ((Class) Iterable.class);
68+
}
69+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.bson.codecs;
18+
19+
import org.bson.BsonReader;
20+
import org.bson.BsonType;
21+
import org.bson.BsonWriter;
22+
23+
import java.util.HashMap;
24+
import java.util.Map;
25+
26+
public abstract class AbstractMapCodec<T> implements Codec<Map<String, T>> {
27+
28+
abstract T readValue(BsonReader reader, DecoderContext decoderContext);
29+
30+
abstract void writeValue(BsonWriter writer, T value, EncoderContext encoderContext);
31+
32+
@Override
33+
public void encode(final BsonWriter writer, final Map<String, T> map, final EncoderContext encoderContext) {
34+
writer.writeStartDocument();
35+
for (final Map.Entry<String, T> entry : map.entrySet()) {
36+
writer.writeName(entry.getKey());
37+
T value = entry.getValue();
38+
if (value == null) {
39+
writer.writeNull();
40+
} else {
41+
writeValue(writer, value, encoderContext);
42+
}
43+
}
44+
writer.writeEndDocument();
45+
}
46+
47+
48+
@Override
49+
public Map<String, T> decode(final BsonReader reader, final DecoderContext decoderContext) {
50+
Map<String, T> map = new HashMap<>();
51+
52+
reader.readStartDocument();
53+
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
54+
String fieldName = reader.readName();
55+
if (reader.getCurrentBsonType() == BsonType.NULL) {
56+
reader.readNull();
57+
map.put(fieldName, null);
58+
} else {
59+
map.put(fieldName, readValue(reader, decoderContext));
60+
}
61+
}
62+
63+
reader.readEndDocument();
64+
return map;
65+
}
66+
67+
@SuppressWarnings({"unchecked", "rawtypes"})
68+
@Override
69+
public Class<Map<String, T>> getEncoderClass() {
70+
return (Class<Map<String, T>>) ((Class) Map.class);
71+
}
72+
}

bson/src/main/org/bson/codecs/IterableCodec.java

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,26 @@
1717
package org.bson.codecs;
1818

1919
import org.bson.BsonReader;
20-
import org.bson.BsonType;
2120
import org.bson.BsonWriter;
2221
import org.bson.Transformer;
2322
import org.bson.UuidRepresentation;
2423
import org.bson.codecs.configuration.CodecConfigurationException;
2524
import org.bson.codecs.configuration.CodecRegistry;
2625

2726
import java.lang.reflect.Type;
28-
import java.util.ArrayList;
2927
import java.util.List;
3028

3129
import static org.bson.assertions.Assertions.notNull;
3230
import static org.bson.codecs.ContainerCodecHelper.getCodec;
33-
import static org.bson.codecs.ContainerCodecHelper.readValue;
3431

3532
/**
3633
* Encodes and decodes {@code Iterable} objects.
3734
*
3835
* @since 3.3
3936
*/
4037
@SuppressWarnings("rawtypes")
41-
public class IterableCodec implements Codec<Iterable>, OverridableUuidRepresentationCodec<Iterable>, Parameterizable {
38+
public class IterableCodec extends AbstractIterableCodec<Object>
39+
implements OverridableUuidRepresentationCodec<Iterable<Object>>, Parameterizable {
4240

4341
private final CodecRegistry registry;
4442
private final BsonTypeCodecMap bsonTypeCodecMap;
@@ -90,48 +88,22 @@ public Codec<?> parameterize(final CodecRegistry codecRegistry, final List<Type>
9088
}
9189

9290
@Override
93-
public Codec<Iterable> withUuidRepresentation(final UuidRepresentation uuidRepresentation) {
91+
public Codec<Iterable<Object>> withUuidRepresentation(final UuidRepresentation uuidRepresentation) {
9492
if (this.uuidRepresentation.equals(uuidRepresentation)) {
9593
return this;
9694
}
9795
return new IterableCodec(registry, bsonTypeCodecMap, valueTransformer, uuidRepresentation);
9896
}
9997

10098
@Override
101-
public Iterable decode(final BsonReader reader, final DecoderContext decoderContext) {
102-
reader.readStartArray();
103-
104-
List<Object> list = new ArrayList<Object>();
105-
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
106-
list.add(readValue(reader, decoderContext, bsonTypeCodecMap, uuidRepresentation, registry, valueTransformer));
107-
}
108-
109-
reader.readEndArray();
110-
111-
return list;
99+
Object readValue(final BsonReader reader, final DecoderContext decoderContext) {
100+
return ContainerCodecHelper.readValue(reader, decoderContext, bsonTypeCodecMap, uuidRepresentation, registry, valueTransformer);
112101
}
113102

103+
@SuppressWarnings("unchecked")
114104
@Override
115-
public void encode(final BsonWriter writer, final Iterable value, final EncoderContext encoderContext) {
116-
writer.writeStartArray();
117-
for (final Object cur : value) {
118-
writeValue(writer, encoderContext, cur);
119-
}
120-
writer.writeEndArray();
121-
}
122-
123-
@Override
124-
public Class<Iterable> getEncoderClass() {
125-
return Iterable.class;
126-
}
127-
128-
@SuppressWarnings({"unchecked", "rawtypes"})
129-
private void writeValue(final BsonWriter writer, final EncoderContext encoderContext, final Object value) {
130-
if (value == null) {
131-
writer.writeNull();
132-
} else {
133-
Codec codec = registry.get(value.getClass());
134-
encoderContext.encodeWithChildContext(codec, writer, value);
135-
}
105+
void writeValue(final BsonWriter writer, final Object value, final EncoderContext encoderContext) {
106+
Codec codec = registry.get(value.getClass());
107+
encoderContext.encodeWithChildContext(codec, writer, value);
136108
}
137109
}

bson/src/main/org/bson/codecs/MapCodec.java

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,27 @@
1717
package org.bson.codecs;
1818

1919
import org.bson.BsonReader;
20-
import org.bson.BsonType;
2120
import org.bson.BsonWriter;
2221
import org.bson.Transformer;
2322
import org.bson.UuidRepresentation;
2423
import org.bson.codecs.configuration.CodecConfigurationException;
2524
import org.bson.codecs.configuration.CodecRegistry;
2625

2726
import java.lang.reflect.Type;
28-
import java.util.HashMap;
2927
import java.util.List;
3028
import java.util.Map;
3129

3230
import static java.util.Arrays.asList;
3331
import static org.bson.assertions.Assertions.notNull;
3432
import static org.bson.codecs.ContainerCodecHelper.getCodec;
35-
import static org.bson.codecs.ContainerCodecHelper.readValue;
3633
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
3734

3835
/**
3936
* A Codec for Map instances.
4037
*
4138
* @since 3.5
4239
*/
43-
public class MapCodec implements Codec<Map<String, Object>>, OverridableUuidRepresentationCodec<Map<String, Object>>, Parameterizable {
40+
public class MapCodec extends AbstractMapCodec<Object> implements OverridableUuidRepresentationCodec<Map<String, Object>>, Parameterizable {
4441

4542
private static final CodecRegistry DEFAULT_REGISTRY = fromProviders(asList(new ValueCodecProvider(), new BsonValueCodecProvider(),
4643
new DocumentCodecProvider(), new IterableCodecProvider(), new MapCodecProvider()));
@@ -125,42 +122,14 @@ public Codec<?> parameterize(final CodecRegistry codecRegistry, final List<Type>
125122
}
126123

127124
@Override
128-
public void encode(final BsonWriter writer, final Map<String, Object> map, final EncoderContext encoderContext) {
129-
writer.writeStartDocument();
130-
for (final Map.Entry<String, Object> entry : map.entrySet()) {
131-
writer.writeName(entry.getKey());
132-
writeValue(writer, encoderContext, entry.getValue());
133-
}
134-
writer.writeEndDocument();
135-
}
136-
137-
@Override
138-
public Map<String, Object> decode(final BsonReader reader, final DecoderContext decoderContext) {
139-
Map<String, Object> map = new HashMap<String, Object>();
140-
141-
reader.readStartDocument();
142-
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
143-
String fieldName = reader.readName();
144-
map.put(fieldName, readValue(reader, decoderContext, bsonTypeCodecMap, uuidRepresentation, registry, valueTransformer));
145-
}
146-
147-
reader.readEndDocument();
148-
return map;
125+
Object readValue(final BsonReader reader, final DecoderContext decoderContext) {
126+
return ContainerCodecHelper.readValue(reader, decoderContext, bsonTypeCodecMap, uuidRepresentation, registry, valueTransformer);
149127
}
150128

151-
@SuppressWarnings("unchecked")
129+
@SuppressWarnings({"rawtypes", "unchecked"})
152130
@Override
153-
public Class<Map<String, Object>> getEncoderClass() {
154-
return (Class<Map<String, Object>>) ((Class) Map.class);
155-
}
156-
157-
@SuppressWarnings({"unchecked", "rawtypes"})
158-
private void writeValue(final BsonWriter writer, final EncoderContext encoderContext, final Object value) {
159-
if (value == null) {
160-
writer.writeNull();
161-
} else {
162-
Codec codec = registry.get(value.getClass());
163-
encoderContext.encodeWithChildContext(codec, writer, value);
164-
}
131+
void writeValue(final BsonWriter writer, final Object value, final EncoderContext encoderContext) {
132+
Codec codec = registry.get(value.getClass());
133+
encoderContext.encodeWithChildContext(codec, writer, value);
165134
}
166135
}

bson/src/main/org/bson/codecs/ParameterizedIterableCodec.java

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,53 +17,22 @@
1717
package org.bson.codecs;
1818

1919
import org.bson.BsonReader;
20-
import org.bson.BsonType;
2120
import org.bson.BsonWriter;
2221

23-
import java.util.ArrayList;
24-
import java.util.List;
25-
26-
class ParameterizedIterableCodec<T> implements Codec<Iterable<T>> {
22+
class ParameterizedIterableCodec<T> extends AbstractIterableCodec<T> {
2723
private final Codec<T> codec;
2824

2925
ParameterizedIterableCodec(final Codec<T> codec) {
3026
this.codec = codec;
3127
}
3228

3329
@Override
34-
public Iterable<T> decode(final BsonReader reader, final DecoderContext decoderContext) {
35-
reader.readStartArray();
36-
37-
List<T> list = new ArrayList<>();
38-
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
39-
if (reader.getCurrentBsonType() == BsonType.NULL) {
40-
list.add(null);
41-
} else {
42-
list.add(decoderContext.decodeWithChildContext(codec, reader));
43-
}
44-
}
45-
46-
reader.readEndArray();
47-
48-
return list;
49-
}
50-
51-
@Override
52-
public void encode(final BsonWriter writer, final Iterable<T> value, final EncoderContext encoderContext) {
53-
writer.writeStartArray();
54-
for (final T cur : value) {
55-
if (cur == null) {
56-
writer.writeNull();
57-
} else {
58-
encoderContext.encodeWithChildContext(codec, writer, cur);
59-
}
60-
}
61-
writer.writeEndArray();
30+
T readValue(final BsonReader reader, final DecoderContext decoderContext) {
31+
return decoderContext.decodeWithChildContext(codec, reader);
6232
}
6333

64-
@SuppressWarnings({"unchecked", "rawtypes"})
6534
@Override
66-
public Class<Iterable<T>> getEncoderClass() {
67-
return (Class<Iterable<T>>) ((Class) Iterable.class);
35+
void writeValue(final BsonWriter writer, final T cur, final EncoderContext encoderContext) {
36+
encoderContext.encodeWithChildContext(codec, writer, cur);
6837
}
6938
}

0 commit comments

Comments
 (0)