/*
 * 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 org.bson;

import org.bson.codecs.Encoder;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistry;

import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

A BsonDocument that begins its life as a document of any type and an Encoder for that document, which lets an instance of any class with an Encoder be treated as a BsonDocument. If any methods are called which required access to the individual elements of the document, then, on demand, the document will be unwrapped into a BsonDocument using a BsonDocumentWriter and the Encoder. But if all that is done with this document is to encode it, then the Encoder will be used to do that.
Type parameters:
  • <T> – the type of the document that is wrapped
See Also:
Since:3.0
/** * A {@code BsonDocument} that begins its life as a document of any type and an {@code Encoder} for that document, which lets an instance of * any class with an Encoder be treated as a BsonDocument. If any methods are called which required access to the individual elements of the * document, then, on demand, the document will be unwrapped into a BsonDocument using a {@code BsonDocumentWriter} and the {@code Encoder}. * But if all that is done with this document is to encode it, then the {@code Encoder} will be used to do that. * * @param <T> the type of the document that is wrapped * @see org.bson.BsonDocumentWriter * @since 3.0 */
public final class BsonDocumentWrapper<T> extends BsonDocument { private static final long serialVersionUID = 1L; private final transient T wrappedDocument; private final transient Encoder<T> encoder; private BsonDocument unwrapped;
A helper to convert an document of type Object to a BsonDocument

If not already a BsonDocument it looks up the documents' class in the codecRegistry and wraps it into a BsonDocumentWrapper

Params:
  • document – the document to convert
  • codecRegistry – the codecRegistry that can be used in the conversion of the Object
Returns:a BsonDocument
/** * A helper to convert an document of type Object to a BsonDocument * * <p>If not already a BsonDocument it looks up the documents' class in the codecRegistry and wraps it into a BsonDocumentWrapper</p> * * @param document the document to convert * @param codecRegistry the codecRegistry that can be used in the conversion of the Object * @return a BsonDocument */
@SuppressWarnings({"rawtypes", "unchecked"}) public static BsonDocument asBsonDocument(final Object document, final CodecRegistry codecRegistry) { if (document == null) { return null; } if (document instanceof BsonDocument) { return (BsonDocument) document; } else { return new BsonDocumentWrapper(document, codecRegistry.get(document.getClass())); } }
Construct a new instance with the given document and encoder for the document.
Params:
  • wrappedDocument – the wrapped document
  • encoder – the encoder for the wrapped document
/** * Construct a new instance with the given document and encoder for the document. * * @param wrappedDocument the wrapped document * @param encoder the encoder for the wrapped document */
public BsonDocumentWrapper(final T wrappedDocument, final Encoder<T> encoder) { if (wrappedDocument == null) { throw new IllegalArgumentException("Document can not be null"); } this.wrappedDocument = wrappedDocument; this.encoder = encoder; }
Get the wrapped document.
Returns:the wrapped document
/** * Get the wrapped document. * * @return the wrapped document */
public T getWrappedDocument() { return wrappedDocument; }
Get the encoder to use for the wrapped document.
Returns:the encoder
/** * Get the encoder to use for the wrapped document. * * @return the encoder */
public Encoder<T> getEncoder() { return encoder; }
Determine whether the document has been unwrapped already.
Returns:true if the wrapped document has been unwrapped already
/** * Determine whether the document has been unwrapped already. * * @return true if the wrapped document has been unwrapped already */
public boolean isUnwrapped() { return unwrapped != null; } @Override public int size() { return getUnwrapped().size(); } @Override public boolean isEmpty() { return getUnwrapped().isEmpty(); } @Override public boolean containsKey(final Object key) { return getUnwrapped().containsKey(key); } @Override public boolean containsValue(final Object value) { return getUnwrapped().containsValue(value); } @Override public BsonValue get(final Object key) { return getUnwrapped().get(key); } @Override public BsonValue put(final String key, final BsonValue value) { return getUnwrapped().put(key, value); } @Override public BsonValue remove(final Object key) { return getUnwrapped().remove(key); } @Override public void putAll(final Map<? extends String, ? extends BsonValue> m) { super.putAll(m); } @Override public void clear() { super.clear(); } @Override public Set<String> keySet() { return getUnwrapped().keySet(); } @Override public Collection<BsonValue> values() { return getUnwrapped().values(); } @Override public Set<Entry<String, BsonValue>> entrySet() { return getUnwrapped().entrySet(); } @Override public boolean equals(final Object o) { return getUnwrapped().equals(o); } @Override public int hashCode() { return getUnwrapped().hashCode(); } @Override public String toString() { return getUnwrapped().toString(); } @Override public BsonDocument clone() { return getUnwrapped().clone(); } private BsonDocument getUnwrapped() { if (encoder == null) { throw new BsonInvalidOperationException("Can not unwrap a BsonDocumentWrapper with no Encoder"); } if (unwrapped == null) { BsonDocument unwrapped = new BsonDocument(); BsonWriter writer = new BsonDocumentWriter(unwrapped); encoder.encode(writer, wrappedDocument, EncoderContext.builder().build()); this.unwrapped = unwrapped; } return unwrapped; } // see https://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html private Object writeReplace() { return getUnwrapped(); } // see https://docs.oracle.com/javase/6/docs/platform/serialization/spec/input.html private void readObject(final ObjectInputStream stream) throws InvalidObjectException { throw new InvalidObjectException("Proxy required"); } }