/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.mongodb.dialect.impl; import java.util.Set; import java.util.regex.Pattern; import org.hibernate.ogm.datastore.mongodb.MongoDBDialect; import org.hibernate.ogm.model.key.spi.EntityKeyMetadata; import org.hibernate.ogm.model.spi.TupleSnapshot; import org.bson.Document; /** * A {@link TupleSnapshot} based on a {@link Document} retrieved from MongoDB. * * @author Guillaume Scheibel <guillaume.scheibel@gmail.com> * @author Christopher Auston * @author Davide D'Alto <davide@hibernate.org> */ public class MongoDBTupleSnapshot implements TupleSnapshot { public static final Pattern EMBEDDED_FIELDNAME_SEPARATOR = Pattern.compile( "\\." ); private final Document dbObject; private final EntityKeyMetadata keyMetadata; public MongoDBTupleSnapshot(Document dbObject, EntityKeyMetadata meta) { this.dbObject = dbObject; this.keyMetadata = meta; } public Document getDbObject() { return dbObject; } @Override public Set<String> getColumnNames() { return dbObject.keySet(); } @Override public boolean isEmpty() { return dbObject.keySet().isEmpty(); } public boolean isKeyColumn(String column) { return keyMetadata != null && keyMetadata.isKeyColumn( column ); } @Override public Object get(String column) { return isKeyColumn( column ) ? getKeyColumnValue( column ) : getValue( dbObject, column ); } private Object getKeyColumnValue(String column) { Object idField = dbObject.get( MongoDBDialect.ID_FIELDNAME ); // single-column key will be stored as is if ( keyMetadata.getColumnNames().length == 1 ) { return idField; } // multi-column key nested within Document else { // the name of the column within the id object if ( column.contains( MongoDBDialect.PROPERTY_SEPARATOR ) ) { column = column.substring( column.indexOf( MongoDBDialect.PROPERTY_SEPARATOR ) + 1 ); } return getValue( (Document) idField, column ); } } /** * The internal structure of a {@link Document} is like a tree. Each embedded object is a new {@code Document} * itself. We traverse the tree until we've arrived at a leaf and retrieve the value from it. */ private Object getValue(Document dbObject, String column) { Object valueOrNull = MongoHelpers.getValueOrNull( dbObject, column ); return valueOrNull; } }