org.infinispan.schematic.document.MergeDocument Maven / Gradle / Ivy
/*
* ModeShape (http://www.modeshape.org)
*
* 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.infinispan.schematic.document;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
import org.infinispan.schematic.internal.document.BsonUtils;
/**
* A {@link Document} implementation that presents the merger of two other documents, where the first document is used before the
* second.
*
* @author Randall Hauch (C) 2011 Red Hat Inc.
* @since 5.1
*/
public class MergeDocument implements Document {
private static final long serialVersionUID = 1L;
private final Document doc1;
private final Document doc2;
/**
* Create a document that contains all of the fields from the two documents, with the first document taking precedence.
*
* @param document1 the first (preceding) document; may not be null
* @param document2 the second document; may not be null
*/
public MergeDocument( Document document1,
Document document2 ) {
this.doc1 = document1;
this.doc2 = document2;
}
/**
* Create a document that contains all of the fields from the three documents, with the first document taking precedence over
* the others, and the second taking precedence over the third.
*
* @param document1 the first (preceding) document; may not be null
* @param document2 the second document; may not be null
* @param document3 the third document; may not be null
*/
public MergeDocument( Document document1,
Document document2,
Document document3 ) {
this.doc1 = document1;
this.doc2 = new MergeDocument(document2, document3);
}
@Override
public MergeDocument clone() {
return new MergeDocument(doc1.clone(), doc2.clone());
}
@Override
public MergeDocument with( Map changedFields ) {
Document clone1 = doc1.with(changedFields);
Document clone2 = doc2.with(changedFields);
if (clone1 == doc1 && clone2 == doc2) return this;
return new MergeDocument(clone1, clone2);
}
@Override
public Document with( String fieldName,
Object value ) {
Document clone1 = doc1.with(fieldName, value);
Document clone2 = doc2.with(fieldName, value);
if (clone1 == doc1 && clone2 == doc2) return this;
return new MergeDocument(clone1, clone2);
}
@Override
public Document with( ValueTransformer transformer ) {
Document clone1 = doc1.with(transformer);
Document clone2 = doc2.with(transformer);
if (clone1 == doc1 && clone2 == doc2) return this;
return new MergeDocument(clone1, clone2);
}
@Override
public Document withVariablesReplaced( Properties properties ) {
Document clone1 = doc1.withVariablesReplaced(properties);
Document clone2 = doc2.withVariablesReplaced(properties);
if (clone1 == doc1 && clone2 == doc2) return this;
return new MergeDocument(clone1, clone2);
}
@Override
public Document withVariablesReplacedWithSystemProperties() {
Document clone1 = doc1.withVariablesReplacedWithSystemProperties();
Document clone2 = doc2.withVariablesReplacedWithSystemProperties();
if (clone1 == doc1 && clone2 == doc2) return this;
return new MergeDocument(clone1, clone2);
}
@Override
public Object get( String name ) {
Object result = doc1.get(name);
return result != null ? result : doc2.get(name);
}
@Override
public Boolean getBoolean( String name ) {
Boolean result = doc1.getBoolean(name);
return result != null ? result : doc2.getBoolean(name);
}
@Override
public boolean getBoolean( String name,
boolean defaultValue ) {
Boolean result = doc1.getBoolean(name);
return result != null ? result : doc2.getBoolean(name, defaultValue);
}
@Override
public Integer getInteger( String name ) {
Integer result = doc1.getInteger(name);
return result != null ? result : doc2.getInteger(name);
}
@Override
public int getInteger( String name,
int defaultValue ) {
Integer result = doc1.getInteger(name);
return result != null ? result : doc2.getInteger(name, defaultValue);
}
@Override
public Long getLong( String name ) {
Long result = doc1.getLong(name);
return result != null ? result : doc2.getLong(name);
}
@Override
public long getLong( String name,
long defaultValue ) {
Long result = doc1.getLong(name);
return result != null ? result : doc2.getLong(name, defaultValue);
}
@Override
public Double getDouble( String name ) {
Double result = doc1.getDouble(name);
return result != null ? result : doc2.getDouble(name);
}
@Override
public double getDouble( String name,
double defaultValue ) {
Double result = doc1.getDouble(name);
return result != null ? result : doc2.getDouble(name, defaultValue);
}
@Override
public Number getNumber( String name ) {
Number result = doc1.getNumber(name);
return result != null ? result : doc2.getNumber(name);
}
@Override
public Number getNumber( String name,
Number defaultValue ) {
Number result = doc1.getNumber(name);
return result != null ? result : doc2.getNumber(name, defaultValue);
}
@Override
public String getString( String name ) {
return getString(name, null);
}
@Override
public String getString( String name,
String defaultValue ) {
String result = doc1.getString(name);
return result != null ? result : doc2.getString(name, defaultValue);
}
@Override
public List> getArray( String name ) {
List> result = doc1.getArray(name);
return result != null ? result : doc2.getArray(name);
}
@Override
public Document getDocument( String name ) {
Document result1 = doc1.getDocument(name);
Document result2 = doc2.getDocument(name);
if (result1 == null) return result2;
return result2 != null ? new MergeDocument(result1, result2) : result1;
}
@Override
public boolean isNull( String name ) {
return doc1.isNull(name) && doc2.isNull(name);
}
@Override
public boolean isNullOrMissing( String name ) {
return doc1.isNullOrMissing(name) && doc2.isNullOrMissing(name);
}
@Override
public MaxKey getMaxKey( String name ) {
MaxKey result = doc1.getMaxKey(name);
return result != null ? result : doc2.getMaxKey(name);
}
@Override
public MinKey getMinKey( String name ) {
MinKey result = doc1.getMinKey(name);
return result != null ? result : doc2.getMinKey(name);
}
@Override
public Code getCode( String name ) {
Code result = doc1.getCode(name);
return result != null ? result : doc2.getCode(name);
}
@Override
public CodeWithScope getCodeWithScope( String name ) {
CodeWithScope result = doc1.getCodeWithScope(name);
return result != null ? result : doc2.getCodeWithScope(name);
}
@Override
public ObjectId getObjectId( String name ) {
ObjectId result = doc1.getObjectId(name);
return result != null ? result : doc2.getObjectId(name);
}
@Override
public Binary getBinary( String name ) {
Binary result = doc1.getBinary(name);
return result != null ? result : doc2.getBinary(name);
}
@Override
public Symbol getSymbol( String name ) {
Symbol result = doc1.getSymbol(name);
return result != null ? result : doc2.getSymbol(name);
}
@Override
public Pattern getPattern( String name ) {
Pattern result = doc1.getPattern(name);
return result != null ? result : doc2.getPattern(name);
}
@Override
public UUID getUuid( String name ) {
UUID result = doc1.getUuid(name);
return result != null ? result : doc2.getUuid(name);
}
@Override
public UUID getUuid( String name,
UUID defaultValue ) {
UUID result = doc1.getUuid(name);
return result != null ? result : doc2.getUuid(name, defaultValue);
}
@Override
public int getType( String name ) {
int type = doc1.getType(name);
return type > -1 ? type : doc2.getType(name);
}
@Override
public Map toMap() {
// Add the vaues from 'doc2' first, since they'd be overwritten by those in 'doc1' ...
Map result = new HashMap(doc2.toMap());
result.putAll(doc1.toMap());
return result;
}
@Override
public Iterable fields() {
if (doc1.isEmpty()) return doc2.fields();
if (doc2.isEmpty()) return doc1.fields();
// Otherwise, they're both not empty ...
final Iterator iter1 = doc1.fields().iterator();
final Iterator iter2 = doc2.fields().iterator();
return new Iterable() {
@Override
public Iterator iterator() {
return new Iterator() {
private boolean first = true;
@Override
public boolean hasNext() {
boolean result = false;
if (first) {
result = iter1.hasNext();
if (result) {
return result;
}
// No more in iter1 ...
first = false;
}
return iter2.hasNext();
}
@Override
public Field next() {
return first ? iter1.next() : iter2.next();
}
@Override
public void remove() {
if (first) {
iter1.remove();
} else {
iter2.remove();
}
}
};
}
};
}
@Override
public boolean containsField( String name ) {
return doc1.containsField(name) || doc2.containsField(name);
}
@Override
public boolean containsAll( Document document ) {
if (document == null) {
return true;
}
for (Field field : document.fields()) {
Object thisValue = this.get(field.getName());
Object thatValue = field.getValue();
if (!BsonUtils.valuesAreEqual(thisValue, thatValue)) {
return false;
}
}
return true;
}
@Override
public Set keySet() {
Set keys = new HashSet(doc1.keySet());
keys.addAll(doc2.keySet());
return keys;
}
@Override
public int size() {
return keySet().size();
}
@Override
public boolean isEmpty() {
return doc1.isEmpty() && doc2.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy