/*
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 org.neodatis.odb.ODBRuntimeException;
import org.neodatis.odb.OID;
import org.neodatis.odb.core.NeoDatisError;
import org.neodatis.odb.core.layers.layer2.meta.AttributeValuesMap;
import org.neodatis.odb.core.layers.layer2.meta.ODBType;
import org.neodatis.odb.core.layers.layer3.IStorageEngine;
import org.neodatis.odb.core.query.criteria.AbstractCriterion;
import org.neodatis.odb.impl.core.layers.layer2.meta.compare.AttributeValueComparator;
import org.neodatis.tool.wrappers.OdbString;
/**
* A criterion to match equality
*
* @author olivier s
*
*/
public class EqualCriterion extends AbstractCriterion {
private Object criterionValue;
private boolean isCaseSensitive;
/**
* 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 EqualCriterion(String attributeName, int value) {
super(attributeName);
init(new Integer(value));
}
public EqualCriterion(String attributeName, short value) {
super(attributeName);
init(new Short(value));
}
public EqualCriterion(String attributeName, byte value) {
super(attributeName);
init(new Byte(value));
}
public EqualCriterion(String attributeName, float value) {
super(attributeName);
init(new Float(value));
}
public EqualCriterion(String attributeName, double value) {
super(attributeName);
init(new Double(value));
}
public EqualCriterion(String attributeName, long value) {
super(attributeName);
init(new Long(value));
}
/**
*
* @param attributeName
* @param value
*/
public EqualCriterion(String attributeName, Object value) {
super(attributeName);
init(value);
}
protected void init(Object value) {
criterionValue = value;
isCaseSensitive = true;
if (criterionValue == null) {
this.objectIsNative = true;
} else {
this.objectIsNative = ODBType.isNative(criterionValue.getClass());
}
if(criterionValue!=null && criterionValue.getClass().isEnum()){
Enum enumObject = (Enum) criterionValue;
criterionValue = enumObject.name();
objectIsNative = true;
}
}
/**
*
* @param attributeName
* @param value
* @param isCaseSensitive
*/
public EqualCriterion(String attributeName, Object value, boolean isCaseSensitive) {
super(attributeName);
this.criterionValue = value;
this.isCaseSensitive = isCaseSensitive;
}
public EqualCriterion(String attributeName, String value, boolean isCaseSensitive) {
super(attributeName);
this.criterionValue = value;
this.isCaseSensitive = isCaseSensitive;
}
public EqualCriterion(String attributeName, boolean value) {
super(attributeName);
init(value ? Boolean.TRUE : Boolean.FALSE);
}
public boolean match(Object valueToMatch) {
// If it is a AttributeValuesMap, then gets the real value from the map
// AttributeValuesMap is used to optimize Criteria Query
// (reading only values of the object that the query needs to be
// evaluated instead of reading the entire object)
if (valueToMatch instanceof AttributeValuesMap) {
AttributeValuesMap attributeValues = (AttributeValuesMap) valueToMatch;
valueToMatch = attributeValues.getAttributeValue(attributeName);
}
if (valueToMatch == null && criterionValue == null && oid == null) {
return true;
}
// if case sensitive (default value), just call the equals on the
// objects
if (isCaseSensitive) {
if (objectIsNative) {
return valueToMatch != null && AttributeValueComparator.equals(valueToMatch, criterionValue);
}
OID objectOid = null;
try{
objectOid = (OID) valueToMatch;
}catch (Exception e) {
throw new ODBRuntimeException(NeoDatisError.EQUAL_CRITERIA_ON_OBJECT_WITH_WRONG_ATTRIBUTE_TYPE
.addParameter(this.toString())
.addParameter(attributeName)
.addParameter(valueToMatch.getClass().getName())
.addParameter(OdbString.exceptionToString(e, true)));
}
if (oid == null) {
// TODO Should we return false or thrown exception?
// See junit TestCriteriaQuery6.test1
return false;
// throw new
// ODBRuntimeException(NeoDatisError.CRITERIA_QUERY_ON_UNKNOWN_OBJECT);
}
return oid.equals(objectOid);
// && valueToMatch.equals(criterionValue);
}
// Case insensitive (iequal) only works on String or Character!
boolean canUseCaseInsensitive = (criterionValue.getClass() == String.class && valueToMatch.getClass() == String.class)
|| (criterionValue.getClass() == Character.class && valueToMatch.getClass() == Character.class);
if (!canUseCaseInsensitive) {
throw new ODBRuntimeException(NeoDatisError.QUERY_ATTRIBUTE_TYPE_NOT_SUPPORTED_IN_IEQUAL_EXPRESSION.addParameter(valueToMatch.getClass().getName()));
}
// Cast to string to make the right comparison using the
// equalsIgnoreCase
String s1 = (String) valueToMatch;
String s2 = (String) criterionValue;
return OdbString.equalsIgnoreCase(s1, s2);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
if(oid!=null){
buffer.append(attributeName).append(" = (Object Id ").append(oid).append(")");
}else{
buffer.append(attributeName).append(" = ").append(criterionValue);
}
return buffer.toString();
}
public AttributeValuesMap getValues() {
AttributeValuesMap map = new AttributeValuesMap();
if (criterionValue == null && oid != null) {
map.setOid(oid);
} else {
map.put(attributeName, criterionValue);
}
return map;
}
public boolean canUseIndex() {
return true;
}
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.