Skip to content

Commit 58425b7

Browse files
committed
Docs Site: New sections for Codec, BsonReader/Writer, and CRUD.
General editing JAVA-1691
1 parent 136760f commit 58425b7

File tree

15 files changed

+628
-147
lines changed

15 files changed

+628
-147
lines changed

docs/reference/content/getting-started/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
date = "2015-03-17T15:36:56Z"
33
title = "Getting Started"
44
[menu.main]
5-
weight = 10
5+
weight = 20
66
pre = "<i class='fa fa-road'></i>"
77
+++
88

docs/reference/content/index.md

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,17 @@ type = "index"
88

99
Welcome to the MongoDB Java driver documentation hub for the 3.0 driver release.
1010

11-
### Getting Started
12-
13-
The [Getting Started]({{< relref "getting-started/index.md" >}}) guide contains installation instructions
14-
and a simple tutorial to get up and running quickly.
15-
1611

17-
### What's new in 2.0
12+
### What's New in 2.0
1813

19-
The [What's New]({{< relref "whats-new/index.md" >}}) guide explains the major new features of the driver.
14+
The [What's New]({{< relref "whats-new/index.md" >}}) guide explains the major new features of the driver. If you are coming from the 2.x
15+
series of the driver, consult the [Upgrading]({{< relref "whats-new/upgrading.md" >}}) documentation on breaking changes.
2016

2117

22-
### Upgrading
23-
24-
If you are coming from the 2.x series of the driver, consult the [upgrading]({{< relref "whats-new/upgrading.md" >}})
25-
documentation on breaking changes.
18+
### Getting Started
2619

20+
The [Getting Started]({{< relref "getting-started/index.md" >}}) guide contains installation instructions
21+
and a simple tutorial to get up and running quickly.
2722

2823
### Reference
2924

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
+++
2+
date = "2015-03-19T14:27:51-04:00"
3+
title = "Codec and CodecRegistry"
4+
[menu.main]
5+
parent = "BSON"
6+
weight = 10
7+
pre = "<i class='fa'></i>"
8+
+++
9+
10+
## Codec and CodecRegistry
11+
12+
In the last section we saw how to use the [`BsonReader`]({{< apiref "org/bson/BsonReader" >}}) and
13+
[`BsonWriter`]({{< apiref "org/bson/BsonWriter" >}}) API to read and write BSON documents. But writing code at that
14+
low a level is tedious and error-prone, so in practice these algorithms are packaged in implementations of the
15+
[`Codec`]({{< apiref "org/bson/codecs/Codec" >}}) interface.
16+
17+
### Codec
18+
19+
The `Codec` interface abstracts the processes of decoding a BSON value into a Java object using a `BsonReader` and encoding a Java object
20+
into a BSON value using a `BsonWriter`. The BSON value can be as simple as a boolean or as complex as a document or array.
21+
22+
Let's look at a simple `Codec` implementation that encodes a Java `Integer` to a BSON Int32, and vice versa:
23+
24+
```java
25+
public class IntegerCodec implements Codec<Integer> {
26+
@Override
27+
public void encode(final BsonWriter writer, final Integer value, final EncoderContext encoderContext) {
28+
writer.writeInt32(value);
29+
}
30+
31+
@Override
32+
public Integer decode(final BsonReader reader, final DecoderContext decoderContext) {
33+
return reader.readInt32();
34+
}
35+
36+
@Override
37+
public Class<Integer> getEncoderClass() {
38+
return Integer.class;
39+
}
40+
}
41+
```
42+
43+
The `encode` method takes a `BsonWriter` and an `Integer` and calls the `writeInt32` method on the `BsonWriter` with the value of the
44+
`Integer`, while the `decode` method takes a `BsonReader` and calls the `readInt32` method on the `BsonReader`, returning the value as an
45+
`Integer`.
46+
47+
A `Codec` implementation than encodes to and decodes from a BSON document or array is more complicated, and would typically
48+
rely on a set of simpler `Codec` implementations for the basic BSON value types. For this, it can rely on a `CodecRegistry`.
49+
50+
### CodecRegistry
51+
52+
A [`CodecRegistry`]({{< apiref "org/bson/codecs/configuration/CodecRegistry" >}}) contains a set of `Codec` instances that are accessed
53+
according to the Java classes that they encode from and decode to. Instances of `CodecRegistry` are generally created via static factory
54+
methods on the [`CodecRegistries`]({{< apiref "org/bson/codecs/configuration/CodecRegistries" >}}) class. Consider the simplest of these
55+
methods, one that takes a list of `Codec`s:
56+
57+
```java
58+
CodecRegistry registry = CodecRegistries.fromCodecs(new IntegerCodec(), new LongCodec(), ...);
59+
```
60+
61+
This returns an immutable `CodecRegistry` instance containing all the `Codec` instances passed to the `fromCodecs` method. They can be
62+
accessed like this:
63+
64+
```java
65+
Codec<Integer> integerCodec = codecRegistry.get(Integer.class);
66+
Codec<Long> longCodec = codecRegistry.get(Long.class);
67+
```
68+
69+
Now consider a `Codec` for the `Document` class. This `Codec` implementation, in order to decode and
70+
encode the values for each field in the document, must be constructed with a `CodecRegistry` to look up the `Codec` instances for each type
71+
of value. But how could one construct an instance of that `Codec`? You would have to pass an instance to the
72+
`CodecRegistries.fromCodecs` method, but you don't have a `CodecRegistry` yet to pass to the constructor. You need some way to delay the
73+
construction of the `Document` `Codec` until after the `CodecRegistry` has been constructed. For that we use a `CodecProvider`.
74+
75+
### CodecProvider
76+
77+
A [`CodecProvider`]({{< apiref "org/bson/codecs/configuration/CodecProvider" >}}) is a factory for `Codec` instances. Unlike
78+
`CodecRegistry`, its `get` method takes not only a Class, but also a `CodecRegistry`, allowing a `CodecProvider` implementation to
79+
construct `Codec` instances that require a `CodecRegistry` to look up `Codec` instances for the values contained within it. Consider a
80+
`CodecProvider` for the `Document` class:
81+
82+
```java
83+
public class DocumentCodecProvider implements CodecProvider {
84+
@Override
85+
public <T> Codec<T> get(final Class<T> clazz, final CodecRegistry registry) {
86+
if (clazz == Document.class) {
87+
// construct DocumentCodec with a CodecRegistry
88+
return (Codec<T>) new DocumentCodec(registry);
89+
}
90+
91+
// CodecProvider returns null if it's not a provider for the requresed Class
92+
return null;
93+
}
94+
}
95+
```
96+
97+
The `DocumentCodec`, because it is constructed with a `CodecRegistry`, can now use that registry to look up `Codec` instances for the
98+
values contained in each Document that it encodes.
99+
100+
One more problem remains, however. Consider the problem of encoding values to a BSON DateTime. An application may want to
101+
encode to a BSON DateTime instances of both the original Java `Date` class as well as the Java 8 `Instance` class. It's easy to create
102+
implemenations of `Codec<Date>` and `Codec<Instant>`, and either one can be used for encoding. But when decoding, a Document `Codec`
103+
also has to choose which Java type to decode a BSON DateTime to. Rather than hard-coding it in the `DocumentCodec`, the decision is
104+
abstracted via the `BsonTypeClassMap` class.
105+
106+
### BsonTypeClassMap
107+
108+
The [`BsonTypeClassMap`]({{< apiref "org/bson/codecs/BsonTypeClassMap" >}}) class simply maps each value in the `BsonType`
109+
enumeration to a Java class. It contains a sensible set of default mappings that can easily be changed by passing an a `Map<BsonType,
110+
Class<?>>` instance to the constructor with any replacement mappings to apply. Consider the case where an application wants to decode
111+
all BSON DateTime values to a Java 8 `Instant` instead of the default `Date`:
112+
113+
```java
114+
Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();
115+
replacements.put(BsonType.DATE_TIME, Instant.class);
116+
BsonTypeClassMap bsonTypeClassMap = new BsonTypeClassMap(replacements);
117+
```
118+
119+
This will replace the default mapping of BSON DateTime to `Date` to one from BSON DateTime to `Instant`.
120+
121+
Putting it all together, we can added a BsonTypeClassMap to the DocumentCodecProvider shown above:
122+
123+
```java
124+
public class DocumentCodecProvider implements CodecProvider {
125+
private final BsonTypeClassMap bsonTypeClassMap;
126+
127+
public DocumentCodecProvider(final BsonTypeClassMap bsonTypeClassMap) {
128+
this.bsonTypeClassMap = bsonTypeClassMap;
129+
}
130+
131+
@Override
132+
public <T> Codec<T> get(final Class<T> clazz, final CodecRegistry registry) {
133+
if (clazz == Document.class) {
134+
// construct DocumentCodec with a CodecRegistry and a BsonTypeClassMap
135+
return (Codec<T>) new DocumentCodec(registry, bsonTypeClassMap);
136+
}
137+
138+
return null;
139+
}
140+
}
141+
```
142+
143+
The `DocumentCodec`, because it is constructed with both a `BsonTypeClassMap` and a `CodecRegistry`, can first use the `BsonTypeClassMap`
144+
to determine with type to decode each BSON value to, then use the `CodecRegistry` to look up the `Codec` for that Java type.
145+
146+
Finally, we create a `CodecRegistry` instance
147+
148+
```java
149+
CodecRegistry defaultCodecRegistry = ...
150+
DocumentCodecProvider documentCodecProvider = ...
151+
Codec<Instant> instantCodec = ...
152+
codecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(instantCodec),
153+
CodecRegistries.fromProviders(documentCodecProvider),
154+
defaultCodecRegistry);
155+
```
156+
157+
using two additional static factory methods from the `CodecRegistries` class: one that takes a list of `CodecProvider`s and one which
158+
takes a list of `CodecRegistry`s.
159+
160+
161+

docs/reference/content/reference/bson/documents.md

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ date = "2015-03-19T14:27:51-04:00"
33
title = "Documents"
44
[menu.main]
55
parent = "BSON"
6-
weight = 50
6+
weight = 1
77
pre = "<i class='fa'></i>"
88
+++
99

@@ -14,59 +14,69 @@ The driver includes several classes and interfaces used for representing BSON do
1414
### BsonDocument
1515

1616
Although generally not needed by users of the high-level driver API, the [`BsonDocument`]({{< apiref "org/bson/BsonDocument" >}}) class is
17-
central to the way that documents are managed internally by the driver. The BsonDocument class can represent dynamically structured
18-
documents of any complexity with a type-safe API. For instance, the document `{ a: "MongoDB", b: [ { c: 1 } ] }` can be constructed as a
19-
BsonDocument as follows:
17+
central to the way that documents are managed internally by the driver. The `BsonDocument` class can represent dynamically structured
18+
documents of any complexity with a type-safe API. For instance, the document
19+
20+
```javascript
21+
{
22+
"a" : "MongoDB",
23+
"b" : [ 1, 2 ]
24+
}
25+
```
26+
27+
can be constructed as a BsonDocument as follows:
2028

2129
```java
2230
new BsonDocument().append("a", new BsonString("MongoDB"))
2331
.append("b", new BsonArray(Arrays.asList(new BsonInt32(1), new BsonInt32(2))));
2432
```
2533

26-
The type safety comes from BsonDocument implementing `Map<String, BsonValue>`, so even built-in types like `int`, `String` and `List` must
27-
be wrapped in a sub-class of `BsonValue`. For a complete list of BsonValue sub-types, please consult the
34+
The type safety comes from `BsonDocument` implementing `Map<String, BsonValue>`, so even built-in types like `int`, `String` and `List` must
35+
be wrapped in a sub-class of `BsonValue`. For a complete list of `BsonValue` sub-types, please consult the
2836
[`BsonValue`]({{< apiref "org/bson/BsonValue" >}}) API documentation.
2937

3038
### Document
3139

32-
Most applications will use the [`Document`]({{< apiref "org/bson/Document" >}}) class instead. Like BsonDocument, the
33-
Document class can represent dynamically structured documents of any complexity; however, the typing is much looser, as Document
40+
Most applications will use the [`Document`]({{< apiref "org/bson/Document" >}}) class instead. Like `BsonDocument`, the
41+
`Document` class can represent dynamically structured documents of any complexity; however, the typing is much looser, as `Document`
3442
implements `Map<String, Object>`. As a result, the same document as above can be constructed using the Document class as follows:
3543

3644
```java
3745
new Document().append("a", "MongoDB")
3846
.append("b", Arrays.asList(1, 2));
3947
```
4048

41-
There is less code to write, but runtime errors are possible if you inadvertently add an instance of an unsupported value type. The most
42-
commonly used value types are:
49+
There is less code to write, but runtime errors are possible if you inadvertently add an instance of an unsupported value type.
50+
51+
The most commonly used value types are:
4352

4453
| BSON type | Java type |
4554
|-----------|-------------------------|
46-
| Document | org.bson.Document |
47-
| Array | java.util.List |
48-
| Date | java.util.Date |
49-
| Boolean | java.lang.Boolean |
50-
| Double | java.lang.Double |
51-
| Int32 | java.lang.Integer |
52-
| Int64 | java.lang.Long |
53-
| String | java.lang.String |
54-
| Binary | org.bson.types.Binary |
55-
| ObjectId | org.bson.types.ObjectId |
56-
| Null | null |
57-
58-
It is actually possible to change these mappings; the mechanism for doing so is currently beyond the scope of this reference.
55+
| Document | `org.bson.Document` |
56+
| Array | `java.util.List` |
57+
| Date | `java.util.Date` |
58+
| Boolean | `java.lang.Boolean` |
59+
| Double | `java.lang.Double` |
60+
| Int32 | `java.lang.Integer` |
61+
| Int64 | `java.lang.Long` |
62+
| String | `java.lang.String` |
63+
| Binary | `org.bson.types.Binary` |
64+
| ObjectId | `org.bson.types.ObjectId` |
65+
| Null | `null` |
66+
67+
It is actually possible to change these mappings; the mechanism for doing so is covered [later]({{< relref "codecs.md" >}}) in this
68+
reference .
5969

6070
### DBObject
6171

6272
Although not recommended for new applications, those upgrading from the 2.x driver series may continue to use the
63-
[`DBObject`]({{< apiref "com/mongodb/DBObject" >}}) interface to represent BSON documents. DBObject is similar to Document in that it
73+
[`DBObject`]({{< apiref "com/mongodb/DBObject" >}}) interface to represent BSON documents. `DBObject` is similar to Document in that it
6474
represents BSON values as `Object`, but it has a few shortcomings that were impossible to overcome:
6575

6676
- it is an interface rather than a class, so it's API can not be extended without breaking binary compatibility
6777
- it doesn't actually implement `Map<String, Object>`
68-
- because it is an interface, a separate concrete class called [BasicDBObject]({{< apiref "com/mongodb/BasicDBObject" >}}) which implements
69-
that interface, is required
78+
- because it is an interface, a separate concrete class called [`BasicDBObject`]({{< apiref "com/mongodb/BasicDBObject" >}}) which
79+
implements that interface, is required
7080

7181
### Bson
7282

docs/reference/content/reference/bson/extended-json.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@ date = "2015-03-19T14:27:51-04:00"
33
title = "Extended JSON"
44
[menu.main]
55
parent = "BSON"
6-
weight = 50
6+
weight = 20
77
pre = "<i class='fa'></i>"
88
+++
99

1010
## MongoDB Extended JSON
1111

12-
The Java driver supports reading and writing JSON-like documents with the [`JsonReader`]({{< apiref "org/bson/json/JsonReader" >}}) and
13-
[`JsonWriter`]({{< apiref "org/bson/json/JsonWriter" >}}) classes, which can read/write both flavors of
14-
[MongoDB Extended JSON](http://docs.mongodb.org/manual/reference/mongodb-extended-json/):
12+
As discussed earlier, the Java driver supports reading and writing BSON documents represented as
13+
[MongoDB Extended JSON](http://docs.mongodb.org/manual/reference/mongodb-extended-json/). Both variants are supported:
1514

1615
- Strict Mode: representations of BSON types that conform to the [JSON RFC](http://www.json.org/). This is the
1716
format that [mongoexport](http://docs.mongodb.org/manual/reference/program/mongoexport/) produces and
1817
[mongoimport](http://docs.mongodb.org/manual/reference/program/mongoimport/) consumes.
1918
- Shell Mode: a superset of JSON that the
2019
[MongoDB shell](http://docs.mongodb.org/manual/tutorial/getting-started-with-the-mongo-shell/) can parse.
21-
2220

21+
Furthermore, the `Document` class provides two sets of convenience methods for this purpose:
22+
23+
- toJson(): a set of overloaded methods that convert a `Document` instance to a JSON string
24+
- parse(): a set of overloaded static factory methods that convert a JSON string to a `Document` instance
25+
2326
## Writing JSON
2427

2528
Consider the task of implementing a [mongoexport](http://docs.mongodb.org/manual/reference/program/mongoexport/)-like tool using the
@@ -40,10 +43,10 @@ try {
4043
}
4144
```
4245

43-
The `Document.toJson()` method is the key part of this code snippet. The implementation of this method constructs an instance of a
44-
`JsonWriter` with its default settings, which will write in strict mode with no new lines or indentation.
46+
The `Document.toJson()` method constructs an instance of a `JsonWriter` with its default settings, which will write in strict mode with
47+
no new lines or indentation.
4548

46-
You can override this default behavior by using one of the overloads of Document.toJson(). As an example, consider the task of writing a
49+
You can override this default behavior by using one of the overloads of `toJson()`. As an example, consider the task of writing a
4750
JSON string that can be copied and pasted into the MongoDB shell:
4851

4952
```java
@@ -82,9 +85,8 @@ try {
8285
}
8386
```
8487

85-
The `Document.parse()` static factory method is the key part of this code snippet. The implementation of this method constructs an
86-
instance of a `JsonReader` with the given string and returns an instance of an equivalent Document instance. `JsonReader`
87-
automatically detects the JSON flavor in the string, so you do not need to specify it.
88+
The `Document.parse()` static factory method constructs an instance of a `JsonReader` with the given string and returns an instance of an
89+
equivalent Document instance. `JsonReader` automatically detects the JSON flavor in the string, so you do not need to specify it.
8890

8991

9092

docs/reference/content/reference/bson/index.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ title = "BSON"
1212
The driver comprehensively supports [BSON](http://www.bsonspec.org), the data storage and network transfer format that MongoDB uses for
1313
“documents". BSON, short for Binary [JSON](http://json.org/), is a binary-encoded serialization of JSON-like documents.
1414

15-
- [Documents]({{< relref "documents.md" >}}): Documentation of the driver's support for BSON documents
15+
- [Documents]({{< relref "documents.md" >}}): Documentation of the driver's support for BSON document representations
16+
- [Readers and Writers]({{< relref "readers-and-writers.md" >}}): Documentation of the driver's support for stream-based reading and writing
17+
of BSON documents
18+
- [Codec and CodecRegistry]({{< relref "codecs.md" >}}): Documentation of the driver's `Codec` API, an abstraction for producing and
19+
consuming BSON document representations using the stream-based readers and writers
1620
- [Extended JSON]({{< relref "extended-json.md" >}}): Documentation of the driver's support for MongoDB Extended JSON

0 commit comments

Comments
 (0)