/* Copyright 2010-2014 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.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
namespace MongoDB.Bson
{
// this class is a wrapper for an object that we intend to serialize as a BsonDocument
// it is a subclass of BsonDocument so that it may be used where a BsonDocument is expected
// this class is mostly used by MongoCollection and MongoCursor when supporting generic query objects
// if all that ever happens with this wrapped object is that it gets serialized then the BsonDocument is never materialized
///
/// Represents a BsonDocument wrapper.
///
public class BsonDocumentWrapper : MaterializedOnDemandBsonDocument
{
// private fields
private Type _wrappedNominalType;
private object _wrappedObject;
private IBsonSerializer _serializer;
private IBsonSerializationOptions _serializationOptions;
private bool _isUpdateDocument;
// constructors
// needed for Deserialize
// (even though we're going to end up throwing an InvalidOperationException)
private BsonDocumentWrapper()
{
}
///
/// Initializes a new instance of the BsonDocumentWrapper class.
///
/// The wrapped object.
public BsonDocumentWrapper(object wrappedObject)
: this((wrappedObject == null) ? typeof(object) : wrappedObject.GetType(), wrappedObject)
{
}
///
/// Initializes a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
public BsonDocumentWrapper(Type wrappedNominalType, object wrappedObject)
: this(wrappedNominalType, wrappedObject, false)
{
}
///
/// Initializes a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// Whether the wrapped object is an update document that needs to be checked.
public BsonDocumentWrapper(Type wrappedNominalType, object wrappedObject, bool isUpdateDocument)
: this(wrappedNominalType, wrappedObject, BsonSerializer.LookupSerializer(wrappedNominalType), null, isUpdateDocument)
{
}
///
/// Initializes a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// The serializer.
/// The serialization options.
/// Whether the wrapped object is an update document that needs to be checked.
public BsonDocumentWrapper(Type wrappedNominalType, object wrappedObject, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions, bool isUpdateDocument)
{
if (wrappedNominalType == null)
{
throw new ArgumentNullException("wrappedNominalType");
}
if (serializer == null)
{
throw new ArgumentNullException("serializer");
}
_wrappedNominalType = wrappedNominalType;
_wrappedObject = wrappedObject;
_serializer = serializer;
_serializationOptions = serializationOptions;
_isUpdateDocument = isUpdateDocument;
}
// public properties
///
/// Gets whether the wrapped document is an update document.
///
public bool IsUpdateDocument
{
get { return _isUpdateDocument; }
}
///
/// Gets the serialization options.
///
///
/// The serialization options.
///
public IBsonSerializationOptions SerializationOptions
{
get { return _serializationOptions; }
}
///
/// Gets the serializer.
///
///
/// The serializer.
///
public IBsonSerializer Serializer
{
get { return _serializer; }
}
///
/// Gets the nominal type of the wrapped document.
///
public Type WrappedNominalType
{
get { return _wrappedNominalType; }
}
///
/// Gets the wrapped object.
///
public object WrappedObject
{
get { return _wrappedObject; }
}
// public static methods
///
/// Creates a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// A BsonDocumentWrapper.
public static BsonDocumentWrapper Create(TNominalType value)
{
return Create(typeof(TNominalType), value);
}
///
/// Creates a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// Whether the wrapped object is an update document.
/// A BsonDocumentWrapper.
public static BsonDocumentWrapper Create(TNominalType value, bool isUpdateDocument)
{
return Create(typeof(TNominalType), value, isUpdateDocument);
}
///
/// Creates a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// A BsonDocumentWrapper.
public static BsonDocumentWrapper Create(Type nominalType, object value)
{
return Create(nominalType, value, false); // isUpdateDocument = false
}
///
/// Creates a new instance of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// The wrapped object.
/// Whether the wrapped object is an update document.
/// A BsonDocumentWrapper.
public static BsonDocumentWrapper Create(Type nominalType, object value, bool isUpdateDocument)
{
return new BsonDocumentWrapper(nominalType, value, isUpdateDocument);
}
///
/// Creates a list of new instances of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped objects.
/// A list of wrapped objects.
/// A list of BsonDocumentWrappers.
public static IEnumerable CreateMultiple(IEnumerable values)
{
if (values == null)
{
throw new ArgumentNullException("values");
}
return values.Select(v => new BsonDocumentWrapper(typeof(TNominalType), v));
}
///
/// Creates a list of new instances of the BsonDocumentWrapper class.
///
/// The nominal type of the wrapped object.
/// A list of wrapped objects.
/// A list of BsonDocumentWrappers.
public static IEnumerable CreateMultiple(Type nominalType, IEnumerable values)
{
if (nominalType == null)
{
throw new ArgumentNullException("nominalType");
}
if (values == null)
{
throw new ArgumentNullException("values");
}
return values.Cast