/* * This file or a portion of this file is licensed under the terms of * the Globus Toolkit Public License, found in file GTPL, or at * http://www.globus.org/toolkit/download/license.html. This notice must * appear in redistributions of this file, with or without modification. * * Redistributions of this Software, with or without modification, must * reproduce the GTPL in: (1) the Software, or (2) the Documentation or * some other similar material which is provided with the Software (if * any). * * Copyright 1999-2004 University of Chicago and The University of * Southern California. All rights reserved. */ package org.griphyn.vdl.annotation; import java.sql.Types; import org.griphyn.vdl.dbschema.Annotation; /** * This class defines basic predicates used for query annotations. * Currently included: AND, OR, NOT, EXISTS, LIKE, BETWEEN_AND, * CONTAINS, EQ, NE, GT, LT, GE, LE. * * @author Jens-S. Vöckler * @author Yong Zhao * @version $Revision$ */ public class Predicate { /** * Defines constants for predicates */ public static final int AND=0; public static final int OR=1; public static final int NOT=2; public static final int EXISTS=3; public static final int LIKE=4; public static final int BETWEEN=5; public static final int CONTAINS=6; public static final int EQ=7; public static final int NE=8; public static final int GT=9; public static final int LT=10; public static final int GE=11; public static final int LE=12; /** * Defines corresponding strings for predicates */ public static final String[] PREDICATE_STRING = { "AND", "OR", "NOT", "EXISTS", "LIKE", "BETWEEN", "CONTAINS", "=", "<>", ">", "<", ">=", "<=" }; /** * Defines constants for value types */ public static final int TYPE_STRING=0; public static final int TYPE_INT=1; public static final int TYPE_FLOAT=2; public static final int TYPE_BOOL=3; public static final int TYPE_DATE=4; /** * Defines the predicate for the query. */ private int m_predicate = EQ; /** * Defines the attribute name */ private String m_key; /** * Defines the value type */ private int m_type = TYPE_STRING; /** * Defines the value for the attribute */ private String m_value1 = null; /** * Defines the second value for the attribute * used only in BETWEEN_AND. */ private String m_value2 = null; /** * Constructor */ public Predicate(int predicate) { m_predicate = predicate; } /** * Constructor * assume the value type is string */ public Predicate( int predicate, String key) { m_predicate = predicate; m_key = key; } /** * Constructs the predicate and key. */ public Predicate( int predicate, String key, String value) { m_predicate = predicate; m_key = key; m_value1 = value; } /** * Constructs the predicate and key. */ public Predicate( int predicate, String key, int type, String value) { m_predicate = predicate; m_key = key; m_type = type; m_value1 = value; } /** * Constructs the predicate and key. */ public Predicate( int predicate, String key, int type, String value1, String value2) { m_predicate = predicate; m_key = key; m_type = type; m_value1 = value1; m_value2 = value2; } /** * Obtains the current value of the predicate */ public int getPredicate() { return m_predicate; } /** * Sets the predicate */ public void setPredicate(int predicate) { m_predicate = predicate; } /** * Obtains the current value of the key. * * @return the current value of the key. * @see #setKey( String ) */ public String getKey() { return m_key; } /** * Overwrites the key with a different name. * * @param key is the new key to use from now on. * @see #getKey() */ public void setKey( String key ) { m_key = key; } /** * Returns the type of the value * * @return a constant from the value types. */ public int getType() { return m_type; } /** * Sets the value type */ public void setType(int type) { m_type = type; } /** * Returns the value */ public String getValue() { return m_value1; } /** * Sets the value */ public void setValue( String value ) { m_value1 = value; } /** * Returns the value */ public String getValue2() { return m_value2; } /** * Sets the value type */ public void setValue2(String value) { m_value2 = value; } /** * Strips function part from key */ private String getFunctionKey(String key) { int start = key.indexOf('('); int end = key.indexOf(')'); if (start != -1 && end != -1 && start < end) { return key.substring(start+1, end); } else return key; } /** * Adds function part to value */ private String getFunctionValue(String key, String default_value) { if (default_value == null) default_value = " value "; if (key == null) return default_value; int start = key.indexOf('('); int end = key.indexOf(')'); if (start != -1 && end != -1 && start < end) { return key.substring(0, start) + "(" + default_value + ")"; } else return default_value; } /** * Returns a string representation */ public String toString() { String str = ""; if (m_key != null) str += m_key + " "; str += PREDICATE_STRING[m_predicate]; if (m_value1 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) str += " " + m_value1; else str += " '" + m_value1 + "'"; } if (m_predicate == BETWEEN && m_value2 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) str += " AND " + m_value2; else str += " AND '" + m_value2 + "'"; } return str; } /** * Returns a SQL query statement for annotation search. * @param annoClass is the class to search for * @param arg could be a String for TR arg, or a Integer * for TR call position. * * @see org.griphyn.vdl.dbschema.Annotation */ public String toSQL(int annoClass, Object arg) { if (m_predicate == AND) return " INTERSECT "; if (m_predicate == OR) return " UNION "; String select = "SELECT DISTINCT "; String ktable = ""; String comma = ", "; String vtable = ""; String field = ""; String from = " FROM "; String where = " WHERE "; String ext = ""; String sql = ""; switch (annoClass) { case Annotation.CLASS_FILENAME: ktable = "anno_lfn k"; field = "name"; break; case Annotation.CLASS_TRANSFORMATION: ktable = "anno_tr k"; field = "did"; break; case Annotation.CLASS_DERIVATION: ktable = "anno_dv k"; field = "did"; break; case Annotation.CLASS_DECLARE: ktable = "anno_targ k"; field = "did"; if (arg != null && arg instanceof String) ext = " AND name='" + (String)arg + "'"; break; case Annotation.CLASS_CALL: ktable = "anno_call k"; field = "did"; if (arg != null && arg instanceof String) ext = " AND pos=" + (Integer)arg; break; default: } if (m_predicate == NOT) { where += field + " NOT IN "; sql = select + field + from + ktable + where; return sql; } if (m_key != null) where += " mkey='" + getFunctionKey(m_key) + "'"; if (m_predicate == EXISTS) { //only need to check key sql = select + field + from + ktable + where + ext; return sql; } // need to check value switch (m_type) { case TYPE_STRING: vtable = "anno_text v"; break; case TYPE_INT: vtable = "anno_int v"; break; case TYPE_FLOAT: vtable = "anno_float v"; break; case TYPE_DATE: vtable = "anno_date v"; break; case TYPE_BOOL: vtable = "anno_bool v"; break; } where += " AND " + getFunctionValue(m_key, null); if (m_predicate == CONTAINS) { where += " LIKE "; if (m_value1 != null) where += "'%" + m_value1 + "%'"; } else { where += PREDICATE_STRING[m_predicate]; if (m_value1 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) where += " " + m_value1; else where += " '" + m_value1 + "'"; } } if (m_predicate == BETWEEN && m_value2 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) where += " AND " + m_value2; else where += " AND '" + m_value2 + "'"; } where += " AND k.id=v.id "; sql = select + field + from + ktable + comma + vtable + where + ext; return sql; } public String toXQuery(String var) { String xquery = ""; if (m_predicate == AND) return " and "; if (m_predicate == OR) return " or "; if (m_predicate == NOT) { return " not "; } String name = ""; if (m_key != null) name = var + "[@name = '" + getFunctionKey(m_key) + "']"; if (m_predicate == EXISTS) { //only need to check key xquery += "exists(" + name + ")"; return xquery; } //need to check value /* switch (m_type) { case TYPE_STRING: break; case TYPE_INT: xquery += "[@type = 'int']"; break; case TYPE_FLOAT: xquery += "[@type = 'float']"; break; case TYPE_DATE: break; case TYPE_BOOL: break; } */ String value = getFunctionValue(m_key, name); if (m_predicate == CONTAINS) { xquery += "contains(" + value + ","; if (m_value1 != null) { xquery += "'" + m_value1 + "'"; } xquery += ")"; } else { xquery += value; if (m_predicate == BETWEEN) xquery += " >= "; else xquery += " " + PREDICATE_STRING[m_predicate]; if (m_value1 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) xquery += " " + m_value1; else xquery += " '" + m_value1 + "'"; } } if (m_predicate == BETWEEN && m_value2 != null) { if (m_type == TYPE_INT || m_type == TYPE_FLOAT) xquery += " and " + value + " <= " + m_value2; else xquery += " and " + value + " <= '" + m_value2 + "'"; } return xquery; } }