/*
* Copyright (C) 2000 - 2008 TagServlet Ltd
*
* This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
*
* OpenBD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Free Software Foundation,version 3.
*
* OpenBD 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBD. If not, see http://www.gnu.org/licenses/
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with any of the JARS listed in the README.txt (or a modified version of
* (that library), containing parts covered by the terms of that JAR, the
* licensors of this Program grant you additional permission to convey the
* resulting work.
* README.txt @ http://www.openbluedragon.org/license/README.txt
*
* http://www.openbluedragon.org/
*/
package com.naryx.tagfusion.cfm.queryofqueries;
/**
* This class represents a between condition.
* NOTE it is left and right INCLUSIVE
*/
import java.util.List;
import java.util.Map;
import com.nary.util.date.dateTimeTokenizer;
import com.naryx.tagfusion.cfm.engine.catchDataFactory;
import com.naryx.tagfusion.cfm.engine.cfData;
import com.naryx.tagfusion.cfm.engine.cfDateData;
import com.naryx.tagfusion.cfm.engine.cfmRunTimeException;
class betweenCondition extends condition{
expression expr1, expr2, expr3;
boolean not;
// these vars are for caching the date values when the value
// being considered is a date. It works nicely if the values
// passed in are strings e.g. BETWEEN '22-01-01' AND '2-9-02'
// and are hence the same for every call to evaluate
String lastDateStr1, lastDateStr2;
long lastDateLong1, lastDateLong2;
betweenCondition( expression _e1, expression _e2, expression _e3, boolean _not ){
expr1 = _e1;
expr2 = _e2;
expr3 = _e3;
not = _not;
lastDateStr1 = "";
lastDateStr2 = "";
}// betweenCondition()
boolean evaluate( rowContext _rowContext, List<cfData> _pData ) throws cfmRunTimeException{
// return whether the value of expr1 is between the values of expr2 and expr3.
return compare( expr1.evaluate( _rowContext, _pData ), expr2.evaluate( _rowContext, _pData ), expr3.evaluate( _rowContext, _pData ) );
}// evaluate()
public boolean evaluate( ResultRow _row, List<cfData> data, Map<String, Integer> lookup ) throws cfmRunTimeException {
return compare( expr1.evaluate( _row, data, lookup ), expr2.evaluate( _row, data, lookup ), expr3.evaluate( _row, data, lookup ) );
}
private boolean compare( cfData _val1, cfData _val2, cfData _val3 ) throws cfmRunTimeException{
if ( _val1.getDataType() == cfData.CFNUMBERDATA ){
// do number comparison
return compareNumbers( _val1, _val2, _val3 );
}else if ( _val1.getDataType() == cfData.CFSTRINGDATA ){
// do string comparison
return compareStrings( _val1, _val2, _val3 );
}else if ( _val1.getDataType() == cfData.CFBOOLEANDATA ){
// do boolean comparison
return compareBooleans( _val1, _val2, _val3 );
}else if ( _val1.getDataType() == cfData.CFDATEDATA ){
// do date comparison
return compareDates( _val1, _val2, _val3 );
}else{
throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError",
"queryofqueries.between",
null ) );
}
}
private static boolean compareNumbers( cfData _theNumber, cfData _val1, cfData _val2 ) throws cfmRunTimeException{
double valNo = _theNumber.getDouble();
try{
double lowerNo = _val1.getDouble();
double upperNo = _val2.getDouble();
return valNo >= lowerNo && valNo <= upperNo;
}catch( Exception e ){
throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError",
"queryofqueries.between",
null ) );
}
}// compareNumbers()
private static boolean compareStrings( cfData _theString, cfData _val1, cfData _val2 ) throws cfmRunTimeException{
try{
String val = _theString.getString();
String lower = _val1.getString();
String upper = _val2.getString();
return val.compareTo( lower ) >= 0 && val.compareTo( upper ) <= 0;
}catch( Exception e ){
throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError",
"queryofqueries.between",
null ) );
}
}// compareStrings()
private static boolean compareBooleans( cfData _theBoolean, cfData _val1, cfData _val2 ) throws cfmRunTimeException{
try{
String val = _theBoolean.getBoolean() ? "true" : "false";
String lower = _val1.getString();
String upper = _val2.getString();
return val.compareTo( lower ) >= 0 && val.compareTo( upper ) <= 0;
}catch( Exception e ){
throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError",
"queryofqueries.between",
null ) );
}
}// compareBooleans()
private boolean compareDates( cfData _theDate, cfData _val1, cfData _val2 ) throws cfmRunTimeException{
long valDate = _theDate.getDateData().getLong();
try{
long lowerDate;
if ( _val1.getDataType() == cfData.CFDATEDATA ){
lowerDate = ( (cfDateData) _val1 ).getLong();
}else{
// check the 'one-date cache'
String dateStr1 = _val1.getString();
if ( lastDateStr1.equals( dateStr1 ) ){
lowerDate = lastDateLong1;
}else{
lowerDate = dateTimeTokenizer.getNeutralDate( dateStr1 ).getTime();
lastDateStr1 = dateStr1;
lastDateLong1 = lowerDate;
}
}
long upperDate;
if ( _val2.getDataType() == cfData.CFDATEDATA ){
upperDate = ( (cfDateData) _val2 ).getLong();
}else{
// check the 'one-date cache'
String dateStr2 = _val2.getString();
if ( lastDateStr2.equals( dateStr2 ) ){
upperDate = lastDateLong2;
}else{
upperDate = dateTimeTokenizer.getNeutralDate( dateStr2 ).getTime();
lastDateStr2 = dateStr2;
lastDateLong2 = upperDate;
}
}
return valDate >= lowerDate && valDate <= upperDate;
}catch( Exception e ){
throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError",
"queryofqueries.between",
null ) );
}
}// compareDates()
}// betweenCondition