/*
 * 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 com.mongodb.lang.Nullable;
import org.bson.BSONObject;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import static java.util.Collections.synchronizedMap;

This class enables to map simple Class fields to a BSON object fields
Deprecated:Replaced by PojoCodecProvider
/** * This class enables to map simple Class fields to a BSON object fields * @deprecated Replaced by {@link org.bson.codecs.pojo.PojoCodecProvider} */
@SuppressWarnings({"unchecked", "rawtypes"}) @Deprecated public abstract class ReflectionDBObject implements DBObject { @Override @Nullable public Object get(final String key) { return getWrapper().get(this, key); } @Override public Set<String> keySet() { return getWrapper().keySet(); } @SuppressWarnings("deprecation") @Override public boolean containsKey(final String key) { return containsField(key); } @Override public boolean containsField(final String fieldName) { return getWrapper().containsKey(fieldName); } @Override public Object put(final String key, final Object v) { return getWrapper().set(this, key, v); } @SuppressWarnings("unchecked") @Override public void putAll(final Map m) { for (final Map.Entry entry : (Set<Map.Entry>) m.entrySet()) { put(entry.getKey().toString(), entry.getValue()); } } @Override public void putAll(final BSONObject o) { for (final String k : o.keySet()) { put(k, o.get(k)); } }
Gets the _id
Returns:the _id of this document
/** * Gets the _id * * @return the _id of this document */
public Object get_id() { return _id; }
Sets the _id
Params:
  • id – the unique identifier for this DBObject
/** * Sets the _id * * @param id the unique identifier for this DBObject */
public void set_id(final Object id) { _id = id; } @Override public boolean isPartialObject() { return false; } @SuppressWarnings("unchecked") @Override public Map toMap() { Map m = new HashMap(); Iterator i = this.keySet().iterator(); while (i.hasNext()) { Object s = i.next(); m.put(s, this.get(s + "")); } return m; }
ReflectionDBObjects can't be partial. This operation is not supported.
Throws:
  • RuntimeException – ReflectionDBObjects can't be partial
/** * ReflectionDBObjects can't be partial. This operation is not supported. * * @throws RuntimeException ReflectionDBObjects can't be partial */
@Override public void markAsPartialObject() { throw new RuntimeException("ReflectionDBObjects can't be partial"); }
This operation is not supported.
Params:
  • key – The name of the field to remove
Throws:
Returns:The value removed from this object
/** * This operation is not supported. * * @param key The name of the field to remove * @return The value removed from this object * @throws UnsupportedOperationException can't remove from a ReflectionDBObject */
@Override public Object removeField(final String key) { throw new UnsupportedOperationException("can't remove from a ReflectionDBObject"); } JavaWrapper getWrapper() { if (_wrapper != null) { return _wrapper; } _wrapper = getWrapper(this.getClass()); return _wrapper; } //CHECKSTYLE:OFF JavaWrapper _wrapper; Object _id; //CHECKSTYLE:ON
Represents a wrapper around the DBObject to interface with the Class fields
/** * Represents a wrapper around the DBObject to interface with the Class fields */
public static class JavaWrapper { JavaWrapper(final Class c) { clazz = c; name = c.getName(); fields = new TreeMap<String, FieldInfo>(); for (final Method m : c.getMethods()) { if (!(m.getName().startsWith("get") || m.getName().startsWith("set"))) { continue; } String name = m.getName().substring(3); if (name.length() == 0 || IGNORE_FIELDS.contains(name)) { continue; } Class type = m.getName().startsWith("get") ? m.getReturnType() : m.getParameterTypes()[0]; FieldInfo fi = fields.get(name); if (fi == null) { fi = new FieldInfo(name, type); fields.put(name, fi); } if (m.getName().startsWith("get")) { fi.getter = m; } else { fi.setter = m; } } Set<String> names = new HashSet<String>(fields.keySet()); for (final String name : names) { if (!fields.get(name).ok()) { fields.remove(name); } } keys = Collections.unmodifiableSet(fields.keySet()); }
Gets all the fields on this object.
Returns:a Set of all the field names.
/** * Gets all the fields on this object. * * @return a Set of all the field names. */
public Set<String> keySet() { return keys; }
Whether the document this represents contains the given field.
Params:
  • key – a field name
Returns:true if the key exists
Deprecated:
/** * Whether the document this represents contains the given field. * * @param key a field name * @return true if the key exists * @deprecated */
@Deprecated public boolean containsKey(final String key) { return keys.contains(key); }
Gets the value for the given field from the given document.
Params:
  • document – a ReflectionDBObject representing a MongoDB document
  • fieldName – the name of the field to get the value for
Returns:the value for the given field name
/** * Gets the value for the given field from the given document. * * @param document a ReflectionDBObject representing a MongoDB document * @param fieldName the name of the field to get the value for * @return the value for the given field name */
@Nullable public Object get(final ReflectionDBObject document, final String fieldName) { FieldInfo i = fields.get(fieldName); if (i == null) { return null; } try { return i.getter.invoke(document); } catch (Exception e) { throw new RuntimeException("could not invoke getter for [" + fieldName + "] on [" + this.name + "]", e); } }
Adds or sets the given field to the given value on the document.
Params:
  • document – a ReflectionDBObject representing a MongoDB document
  • fieldName – the name of the field to get the value for
  • value – the value to set the field to
Returns:the result of setting this value
/** * Adds or sets the given field to the given value on the document. * * @param document a ReflectionDBObject representing a MongoDB document * @param fieldName the name of the field to get the value for * @param value the value to set the field to * @return the result of setting this value */
public Object set(final ReflectionDBObject document, final String fieldName, final Object value) { FieldInfo i = fields.get(fieldName); if (i == null) { throw new IllegalArgumentException("no field [" + fieldName + "] on [" + this.name + "]"); } try { return i.setter.invoke(document, value); } catch (Exception e) { throw new RuntimeException("could not invoke setter for [" + fieldName + "] on [" + this.name + "]", e); } } @Nullable Class<? extends DBObject> getInternalClass(final List<String> path) { String cur = path.get(0); FieldInfo fi = fields.get(cur); if (fi == null) { return null; } if (path.size() == 1) { return fi.clazz; } JavaWrapper w = getWrapperIfReflectionObject(fi.clazz); if (w == null) { return null; } return w.getInternalClass(path.subList(1, path.size())); } //CHECKSTYLE:OFF final Class clazz; final String name; final Map<String, FieldInfo> fields; final Set<String> keys; //CHECKSTYLE:ON } static class FieldInfo { FieldInfo(final String name, final Class<? extends DBObject> clazz) { this.name = name; this.clazz = clazz; } boolean ok() { return getter != null && setter != null; } //CHECKSTYLE:OFF final String name; final Class<? extends DBObject> clazz; Method getter; Method setter; //CHECKSTYLE:ON }
Returns the wrapper if this object can be assigned from this class.
Params:
  • c – the class to be wrapped
Returns:the wrapper
/** * Returns the wrapper if this object can be assigned from this class. * * @param c the class to be wrapped * @return the wrapper */
@Nullable public static JavaWrapper getWrapperIfReflectionObject(final Class c) { if (ReflectionDBObject.class.isAssignableFrom(c)) { return getWrapper(c); } return null; }
Returns an existing Wrapper instance associated with a class, or creates a new one.
Params:
  • c – the class to be wrapped
Returns:the wrapped
/** * Returns an existing Wrapper instance associated with a class, or creates a new one. * * @param c the class to be wrapped * @return the wrapped */
public static JavaWrapper getWrapper(final Class c) { JavaWrapper w = _wrappers.get(c); if (w == null) { w = new JavaWrapper(c); _wrappers.put(c, w); } return w; } private static final Map<Class, JavaWrapper> _wrappers = synchronizedMap(new HashMap<Class, JavaWrapper>()); private static final Set<String> IGNORE_FIELDS = new HashSet<String>(); static { IGNORE_FIELDS.add("Int"); } }