/*
* Copyright 2008-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mongodb;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.BsonBinaryWriter;
import org.bson.BsonDocument;
import org.bson.BsonDocumentWrapper;
import org.bson.codecs.Decoder;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.Encoder;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;
import org.bson.io.BasicOutputBuffer;
import org.bson.io.OutputBuffer;
import org.bson.json.JsonReader;
import org.bson.json.JsonWriter;
import org.bson.json.JsonWriterSettings;
import org.bson.types.BasicBSONList;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
A basic implementation of BSON object that is MongoDB specific. A DBObject
can be created as follows, using this class: DBObject obj = new BasicDBObject();
obj.put( "foo", "bar" );
@mongodb.driver.manual core/document/ MongoDB Documents
/**
* A basic implementation of BSON object that is MongoDB specific. A {@code DBObject} can be created as follows, using this class:
* <pre>
* DBObject obj = new BasicDBObject();
* obj.put( "foo", "bar" );
* </pre>
*
* @mongodb.driver.manual core/document/ MongoDB Documents
*/
@SuppressWarnings({"rawtypes"})
public class BasicDBObject extends BasicBSONObject implements DBObject, Bson {
private static final long serialVersionUID = -4415279469780082174L;
private boolean isPartialObject;
Parses a string in MongoDB Extended JSON format to a BasicDBObject
. Params: - json – the JSON string
See Also: Returns: a corresponding BasicDBObject
object @mongodb.driver.manual reference/mongodb-extended-json/ MongoDB Extended JSON
/**
* Parses a string in MongoDB Extended JSON format to a {@code BasicDBObject}.
*
* @param json the JSON string
* @return a corresponding {@code BasicDBObject} object
* @see org.bson.json.JsonReader
* @mongodb.driver.manual reference/mongodb-extended-json/ MongoDB Extended JSON
*/
public static BasicDBObject parse(final String json) {
return parse(json, DBObjectCodec.getDefaultRegistry().get(BasicDBObject.class));
}
Parses a string in MongoDB Extended JSON format to a BasicDBObject
. Params: - json – the JSON string
- decoder – the decoder to use to decode the BasicDBObject instance
See Also: Returns: a corresponding BasicDBObject
object @mongodb.driver.manual reference/mongodb-extended-json/ MongoDB Extended JSON
/**
* Parses a string in MongoDB Extended JSON format to a {@code BasicDBObject}.
*
* @param json the JSON string
* @param decoder the decoder to use to decode the BasicDBObject instance
* @return a corresponding {@code BasicDBObject} object
* @see org.bson.json.JsonReader
* @mongodb.driver.manual reference/mongodb-extended-json/ MongoDB Extended JSON
*/
public static BasicDBObject parse(final String json, final Decoder<BasicDBObject> decoder) {
return decoder.decode(new JsonReader(json), DecoderContext.builder().build());
}
Creates an empty object.
/**
* Creates an empty object.
*/
public BasicDBObject() {
super();
}
Creates an empty object
Params: - size – an estimate of number of fields that will be inserted
/**
* Creates an empty object
*
* @param size an estimate of number of fields that will be inserted
*/
public BasicDBObject(final int size) {
super(size);
}
Creates an object with the given key/value
Params: - key – key under which to store
- value – value to store
/**
* Creates an object with the given key/value
*
* @param key key under which to store
* @param value value to store
*/
public BasicDBObject(final String key, final Object value) {
super(key, value);
}
Creates an object from a map.
Params: - map – map to convert
/**
* Creates an object from a map.
*
* @param map map to convert
*/
public BasicDBObject(final Map map) {
super(map);
}
Add a key/value pair to this object
Params: - key – the field name
- val – the field value
Returns: this BasicDBObject with the new values added
/**
* Add a key/value pair to this object
*
* @param key the field name
* @param val the field value
* @return this BasicDBObject with the new values added
*/
@Override
public BasicDBObject append(final String key, final Object val) {
put(key, val);
return this;
}
Whether markAsPartialObject
was ever called only matters if you are going to upsert and do not want to risk losing fields. Returns: true if this has been marked as a partial object
/**
* Whether {@link #markAsPartialObject} was ever called only matters if you are going to upsert and do not want to risk losing fields.
*
* @return true if this has been marked as a partial object
*/
@Override
public boolean isPartialObject() {
return isPartialObject;
}
Gets a JSON representation of this document using the JsonMode.STRICT
output mode, and otherwise the default settings of Builder
and DBObjectCodec
. Throws: - CodecConfigurationException – if the document contains types not in the default registry
See Also: Returns: a JSON representation of this document
/**
* Gets a JSON representation of this document using the {@link org.bson.json.JsonMode#STRICT} output mode, and otherwise the default
* settings of {@link JsonWriterSettings.Builder} and {@link DBObjectCodec}.
*
* @return a JSON representation of this document
* @throws org.bson.codecs.configuration.CodecConfigurationException if the document contains types not in the default registry
* @see #toJson(JsonWriterSettings)
* @see JsonWriterSettings
*/
@SuppressWarnings("deprecation")
public String toJson() {
return toJson(new JsonWriterSettings());
}
Gets a JSON representation of this document
With the default DBObjectCodec
.
Params: - writerSettings – the json writer settings to use when encoding
Throws: - CodecConfigurationException – if the document contains types not in the default registry
Returns: a JSON representation of this document
/**
* Gets a JSON representation of this document
*
* <p>With the default {@link DBObjectCodec}.</p>
*
* @param writerSettings the json writer settings to use when encoding
* @return a JSON representation of this document
* @throws org.bson.codecs.configuration.CodecConfigurationException if the document contains types not in the default registry
*/
public String toJson(final JsonWriterSettings writerSettings) {
return toJson(writerSettings, DBObjectCodec.getDefaultRegistry().get(BasicDBObject.class));
}
Gets a JSON representation of this document
With the default JsonWriterSettings
.
Params: - encoder – the BasicDBObject codec instance to encode the document with
Throws: - CodecConfigurationException – if the registry does not contain a codec for the document values.
Returns: a JSON representation of this document
/**
* Gets a JSON representation of this document
*
* <p>With the default {@link JsonWriterSettings}.</p>
*
* @param encoder the BasicDBObject codec instance to encode the document with
* @return a JSON representation of this document
* @throws org.bson.codecs.configuration.CodecConfigurationException if the registry does not contain a codec for the document values.
*/
@SuppressWarnings("deprecation")
public String toJson(final Encoder<BasicDBObject> encoder) {
return toJson(new JsonWriterSettings(), encoder);
}
Gets a JSON representation of this document
Params: - writerSettings – the json writer settings to use when encoding
- encoder – the BasicDBObject codec instance to encode the document with
Throws: - CodecConfigurationException – if the registry does not contain a codec for the document values.
Returns: a JSON representation of this document
/**
* Gets a JSON representation of this document
*
* @param writerSettings the json writer settings to use when encoding
* @param encoder the BasicDBObject codec instance to encode the document with
* @return a JSON representation of this document
* @throws org.bson.codecs.configuration.CodecConfigurationException if the registry does not contain a codec for the document values.
*/
public String toJson(final JsonWriterSettings writerSettings, final Encoder<BasicDBObject> encoder) {
JsonWriter writer = new JsonWriter(new StringWriter(), writerSettings);
encoder.encode(writer, this, EncoderContext.builder().build());
return writer.getWriter().toString();
}
@Override
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof BSONObject)) {
return false;
}
BSONObject other = (BSONObject) o;
if (!keySet().equals(other.keySet())) {
return false;
}
return Arrays.equals(toBson(canonicalizeBSONObject(this)), toBson(canonicalizeBSONObject(other)));
}
@Override
public int hashCode() {
return Arrays.hashCode(toBson(canonicalizeBSONObject(this)));
}
private static byte[] toBson(final DBObject dbObject) {
OutputBuffer outputBuffer = new BasicOutputBuffer();
DBObjectCodec.getDefaultRegistry().get(DBObject.class).encode(new BsonBinaryWriter(outputBuffer), dbObject,
EncoderContext.builder().build());
return outputBuffer.toByteArray();
}
Returns a JSON serialization of this object
The output will look like: {"a":1, "b":["x","y","z"]}
Returns: JSON serialization
/**
* <p>Returns a JSON serialization of this object</p>
*
* <p>The output will look like: {@code {"a":1, "b":["x","y","z"]} }</p>
*
* @return JSON serialization
*/
@SuppressWarnings("deprecation")
public String toString() {
return toJson();
}
If this object was retrieved with only some fields (using a field filter) this method will be called to mark it as such.
/**
* If this object was retrieved with only some fields (using a field filter) this method will be called to mark it as such.
*/
@Override
public void markAsPartialObject() {
isPartialObject = true;
}
Creates a new instance which is a copy of this BasicDBObject.
Returns: a BasicDBObject with exactly the same values as this instance.
/**
* Creates a new instance which is a copy of this BasicDBObject.
*
* @return a BasicDBObject with exactly the same values as this instance.
*/
public Object copy() {
// copy field values into new object
BasicDBObject newCopy = new BasicDBObject(this.toMap());
// need to clone the sub obj
for (final String field : keySet()) {
Object val = get(field);
if (val instanceof BasicDBObject) {
newCopy.put(field, ((BasicDBObject) val).copy());
} else if (val instanceof BasicDBList) {
newCopy.put(field, ((BasicDBList) val).copy());
}
}
return newCopy;
}
@Override
public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> documentClass, final CodecRegistry codecRegistry) {
return new BsonDocumentWrapper<BasicDBObject>(this, codecRegistry.get(BasicDBObject.class));
}
// create a copy of "from", but with keys ordered alphabetically
@SuppressWarnings("unchecked")
private static Object canonicalize(final Object from) {
if (from instanceof BSONObject && !(from instanceof BasicBSONList)) {
return canonicalizeBSONObject((BSONObject) from);
} else if (from instanceof List) {
return canonicalizeList((List<Object>) from);
} else if (from instanceof Map) {
return canonicalizeMap((Map<String, Object>) from);
} else {
return from;
}
}
private static Map<String, Object> canonicalizeMap(final Map<String, Object> from) {
Map<String, Object> canonicalized = new LinkedHashMap<String, Object>(from.size());
TreeSet<String> keysInOrder = new TreeSet<String>(from.keySet());
for (String key : keysInOrder) {
Object val = from.get(key);
canonicalized.put(key, canonicalize(val));
}
return canonicalized;
}
private static DBObject canonicalizeBSONObject(final BSONObject from) {
BasicDBObject canonicalized = new BasicDBObject();
TreeSet<String> keysInOrder = new TreeSet<String>(from.keySet());
for (String key : keysInOrder) {
Object val = from.get(key);
canonicalized.put(key, canonicalize(val));
}
return canonicalized;
}
private static List canonicalizeList(final List<Object> list) {
List<Object> canonicalized = new ArrayList<Object>(list.size());
for (Object cur : list) {
canonicalized.add(canonicalize(cur));
}
return canonicalized;
}
}