/*
NeoDatis ODB : Native Object Database (odb.info@neodatis.org)
Copyright (C) 2007 NeoDatis Inc. http://www.neodatis.org
"This file is part of the NeoDatis ODB open source object database".
NeoDatis ODB is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
NeoDatis ODB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.neodatis.odb.impl.core.query.criteria;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.neodatis.odb.ODBRuntimeException;
import org.neodatis.odb.OID;
import org.neodatis.odb.core.NeoDatisError;
import org.neodatis.odb.core.layers.layer2.meta.AbstractObjectInfo;
import org.neodatis.odb.core.layers.layer2.meta.AttributeValuesMap;
import org.neodatis.odb.core.layers.layer2.meta.NonNativeObjectInfo;
import org.neodatis.odb.core.layers.layer2.meta.ODBType;
import org.neodatis.odb.core.layers.layer3.IStorageEngine;
import org.neodatis.odb.core.query.IQuery;
import org.neodatis.odb.core.query.criteria.AbstractCriterion;
import org.neodatis.tool.wrappers.OdbReflection;
public class ContainsCriterion extends AbstractCriterion {
private Object criterionValue;
/**
* For criteria query on objects, we use the oid of the object instead of
* the object itself. So comparison will be done with OID It is faster and
* avoid the need of the object (class) having to implement Serializable in
* client server mode
*
*/
private OID oid;
private boolean objectIsNative;
public ContainsCriterion(String attributeName, String criterionValue) {
super(attributeName);
init(criterionValue);
}
public ContainsCriterion(String attributeName, int value) {
super(attributeName);
init(new Integer(value));
}
public ContainsCriterion(String attributeName, short value) {
super(attributeName);
init(new Short(value));
}
public ContainsCriterion(String attributeName, byte value) {
super(attributeName);
init(new Byte(value));
}
public ContainsCriterion(String attributeName, float value) {
super(attributeName);
init(new Float(value));
}
public ContainsCriterion(String attributeName, double value) {
super(attributeName);
init(new Double(value));
}
public ContainsCriterion(String attributeName, long value) {
super(attributeName);
init(new Long(value));
}
protected void init(Object value) {
this.criterionValue = value;
if (criterionValue == null) {
this.objectIsNative = true;
} else {
this.objectIsNative = ODBType.isNative(criterionValue.getClass());
}
}
public ContainsCriterion(String attributeName, Object value) {
super(attributeName);
init(value);
}
public ContainsCriterion(String attributeName, boolean value) {
super(attributeName);
init(value ? Boolean.TRUE : Boolean.FALSE);
}
public boolean match(Object valueToMatch) {
if (valueToMatch == null && criterionValue == null && oid == null) {
return true;
}
if (valueToMatch == null) {
return false;
}
Map m = null;
if (valueToMatch instanceof Map) {
// The value in the map, just take the object with the attributeName
m = (Map) valueToMatch;
valueToMatch = m.get(attributeName);
// The value valueToMatch was redefined, so we need to re-make some
// tests
if (valueToMatch == null && criterionValue == null && oid == null) {
return true;
}
if (valueToMatch == null) {
return false;
}
}
if (valueToMatch instanceof Collection) {
Collection c = (Collection) valueToMatch;
return checkIfCollectionContainsValue(c);
}
Class clazz = valueToMatch.getClass();
if (clazz.isArray()) {
return checkIfArrayContainsValue(valueToMatch);
}
throw new ODBRuntimeException(NeoDatisError.QUERY_CONTAINS_CRITERION_TYPE_NOT_SUPPORTED.addParameter(valueToMatch.getClass().getName()));
}
private boolean checkIfCollectionContainsValue(Collection c) {
IStorageEngine engine = getQuery().getStorageEngine();
if (engine == null) {
throw new ODBRuntimeException(NeoDatisError.QUERY_ENGINE_NOT_SET);
}
AbstractObjectInfo aoi = null;
Iterator iterator = c.iterator();
// If the object to compared is native
if (objectIsNative) {
while (iterator.hasNext()) {
aoi = (AbstractObjectInfo) iterator.next();
if (aoi == null && criterionValue == null) {
return true;
}
if (aoi != null && criterionValue == null) {
return false;
}
if (criterionValue.equals(aoi.getObject())) {
return true;
}
}
return false;
}
// Object is not native
while (iterator.hasNext()) {
aoi = (AbstractObjectInfo) iterator.next();
if (aoi.isNull() && criterionValue == null && oid ==null) {
return true;
}
if (aoi != null & oid !=null) {
if (aoi.isNonNativeObject()) {
NonNativeObjectInfo nnoi1 = (NonNativeObjectInfo) aoi;
boolean isEqual = nnoi1.getOid() != null && oid != null && nnoi1.getOid().equals(oid);
if (isEqual) {
return true;
}
}
}
}
return false;
}
private boolean checkIfArrayContainsValue(Object valueToMatch) {
int arrayLength = OdbReflection.getArrayLength(valueToMatch);
Object element = null;
AbstractObjectInfo aoi = null;
for (int i = 0; i < arrayLength; i++) {
element = OdbReflection.getArrayElement(valueToMatch, i);
if (element == null && criterionValue == null) {
return true;
}
aoi = (AbstractObjectInfo) element;
if (aoi != null && aoi.getObject() != null && aoi.getObject().equals(criterionValue)) {
return true;
}
}
return false;
}
public AttributeValuesMap getValues() {
return new AttributeValuesMap();
}
public void setQuery(IQuery query) {
super.setQuery(query);
}
public void ready() {
if (!objectIsNative) {
if (getQuery() == null) {
throw new ODBRuntimeException(NeoDatisError.CONTAINS_QUERY_WITH_NO_QUERY);
}
IStorageEngine engine = getQuery().getStorageEngine();
if (engine == null) {
throw new ODBRuntimeException(NeoDatisError.CONTAINS_QUERY_WITH_NO_STORAGE_ENGINE);
}
// For non native object, we just need the oid of it
oid = engine.getObjectId(criterionValue, false);
this.criterionValue = null;
}
}
}
Ads help maintain this website.