001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015: package org.griphyn.vdl.annotation;
016:
017: import java.sql.Types;
018: import org.griphyn.vdl.dbschema.Annotation;
019:
020: /**
021: * This class defines basic predicates used for query annotations.
022: * Currently included: AND, OR, NOT, EXISTS, LIKE, BETWEEN_AND,
023: * CONTAINS, EQ, NE, GT, LT, GE, LE.
024: *
025: * @author Jens-S. Vöckler
026: * @author Yong Zhao
027: * @version $Revision: 50 $
028: */
029: public class Predicate {
030: /**
031: * Defines constants for predicates
032: */
033: public static final int AND = 0;
034: public static final int OR = 1;
035: public static final int NOT = 2;
036: public static final int EXISTS = 3;
037: public static final int LIKE = 4;
038: public static final int BETWEEN = 5;
039: public static final int CONTAINS = 6;
040: public static final int EQ = 7;
041: public static final int NE = 8;
042: public static final int GT = 9;
043: public static final int LT = 10;
044: public static final int GE = 11;
045: public static final int LE = 12;
046:
047: /**
048: * Defines corresponding strings for predicates
049: */
050: public static final String[] PREDICATE_STRING = { "AND", "OR",
051: "NOT", "EXISTS", "LIKE", "BETWEEN", "CONTAINS", "=", "<>",
052: ">", "<", ">=", "<=" };
053:
054: /**
055: * Defines constants for value types
056: */
057: public static final int TYPE_STRING = 0;
058: public static final int TYPE_INT = 1;
059: public static final int TYPE_FLOAT = 2;
060: public static final int TYPE_BOOL = 3;
061: public static final int TYPE_DATE = 4;
062:
063: /**
064: * Defines the predicate for the query.
065: */
066: private int m_predicate = EQ;
067:
068: /**
069: * Defines the attribute name
070: */
071: private String m_key;
072:
073: /**
074: * Defines the value type
075: */
076: private int m_type = TYPE_STRING;
077:
078: /**
079: * Defines the value for the attribute
080: */
081: private String m_value1 = null;
082:
083: /**
084: * Defines the second value for the attribute
085: * used only in BETWEEN_AND.
086: */
087: private String m_value2 = null;
088:
089: /**
090: * Constructor
091: */
092: public Predicate(int predicate) {
093: m_predicate = predicate;
094: }
095:
096: /**
097: * Constructor
098: * assume the value type is string
099: */
100: public Predicate(int predicate, String key) {
101: m_predicate = predicate;
102: m_key = key;
103: }
104:
105: /**
106: * Constructs the predicate and key.
107: */
108: public Predicate(int predicate, String key, String value) {
109: m_predicate = predicate;
110: m_key = key;
111: m_value1 = value;
112: }
113:
114: /**
115: * Constructs the predicate and key.
116: */
117: public Predicate(int predicate, String key, int type, String value) {
118: m_predicate = predicate;
119: m_key = key;
120: m_type = type;
121: m_value1 = value;
122: }
123:
124: /**
125: * Constructs the predicate and key.
126: */
127: public Predicate(int predicate, String key, int type,
128: String value1, String value2) {
129: m_predicate = predicate;
130: m_key = key;
131: m_type = type;
132: m_value1 = value1;
133: m_value2 = value2;
134: }
135:
136: /**
137: * Obtains the current value of the predicate
138: */
139: public int getPredicate() {
140: return m_predicate;
141: }
142:
143: /**
144: * Sets the predicate
145: */
146: public void setPredicate(int predicate) {
147: m_predicate = predicate;
148: }
149:
150: /**
151: * Obtains the current value of the key.
152: *
153: * @return the current value of the key.
154: * @see #setKey( String )
155: */
156: public String getKey() {
157: return m_key;
158: }
159:
160: /**
161: * Overwrites the key with a different name.
162: *
163: * @param key is the new key to use from now on.
164: * @see #getKey()
165: */
166: public void setKey(String key) {
167: m_key = key;
168: }
169:
170: /**
171: * Returns the type of the value
172: *
173: * @return a constant from the value types.
174: */
175: public int getType() {
176: return m_type;
177: }
178:
179: /**
180: * Sets the value type
181: */
182: public void setType(int type) {
183: m_type = type;
184: }
185:
186: /**
187: * Returns the value
188: */
189: public String getValue() {
190: return m_value1;
191: }
192:
193: /**
194: * Sets the value
195: */
196: public void setValue(String value) {
197: m_value1 = value;
198: }
199:
200: /**
201: * Returns the value
202: */
203: public String getValue2() {
204: return m_value2;
205: }
206:
207: /**
208: * Sets the value type
209: */
210: public void setValue2(String value) {
211: m_value2 = value;
212: }
213:
214: /**
215: * Strips function part from key
216: */
217: private String getFunctionKey(String key) {
218: int start = key.indexOf('(');
219: int end = key.indexOf(')');
220: if (start != -1 && end != -1 && start < end) {
221: return key.substring(start + 1, end);
222: } else
223: return key;
224: }
225:
226: /**
227: * Adds function part to value
228: */
229: private String getFunctionValue(String key, String default_value) {
230: if (default_value == null)
231: default_value = " value ";
232: if (key == null)
233: return default_value;
234: int start = key.indexOf('(');
235: int end = key.indexOf(')');
236: if (start != -1 && end != -1 && start < end) {
237: return key.substring(0, start) + "(" + default_value + ")";
238: } else
239: return default_value;
240: }
241:
242: /**
243: * Returns a string representation
244: */
245: public String toString() {
246: String str = "";
247: if (m_key != null)
248: str += m_key + " ";
249: str += PREDICATE_STRING[m_predicate];
250: if (m_value1 != null) {
251: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
252: str += " " + m_value1;
253: else
254: str += " '" + m_value1 + "'";
255: }
256: if (m_predicate == BETWEEN && m_value2 != null) {
257: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
258: str += " AND " + m_value2;
259: else
260: str += " AND '" + m_value2 + "'";
261: }
262: return str;
263: }
264:
265: /**
266: * Returns a SQL query statement for annotation search.
267: * @param annoClass is the class to search for
268: * @param arg could be a String for TR arg, or a Integer
269: * for TR call position.
270: *
271: * @see org.griphyn.vdl.dbschema.Annotation
272: */
273: public String toSQL(int annoClass, Object arg) {
274: if (m_predicate == AND)
275: return " INTERSECT ";
276:
277: if (m_predicate == OR)
278: return " UNION ";
279:
280: String select = "SELECT DISTINCT ";
281: String ktable = "";
282: String comma = ", ";
283: String vtable = "";
284: String field = "";
285: String from = " FROM ";
286: String where = " WHERE ";
287: String ext = "";
288: String sql = "";
289:
290: switch (annoClass) {
291: case Annotation.CLASS_FILENAME:
292: ktable = "anno_lfn k";
293: field = "name";
294: break;
295: case Annotation.CLASS_TRANSFORMATION:
296: ktable = "anno_tr k";
297: field = "did";
298: break;
299: case Annotation.CLASS_DERIVATION:
300: ktable = "anno_dv k";
301: field = "did";
302: break;
303: case Annotation.CLASS_DECLARE:
304: ktable = "anno_targ k";
305: field = "did";
306: if (arg != null && arg instanceof String)
307: ext = " AND name='" + (String) arg + "'";
308: break;
309: case Annotation.CLASS_CALL:
310: ktable = "anno_call k";
311: field = "did";
312: if (arg != null && arg instanceof String)
313: ext = " AND pos=" + (Integer) arg;
314: break;
315: default:
316: }
317:
318: if (m_predicate == NOT) {
319: where += field + " NOT IN ";
320: sql = select + field + from + ktable + where;
321: return sql;
322: }
323:
324: if (m_key != null)
325: where += " mkey='" + getFunctionKey(m_key) + "'";
326:
327: if (m_predicate == EXISTS) {
328: //only need to check key
329: sql = select + field + from + ktable + where + ext;
330: return sql;
331: }
332:
333: // need to check value
334: switch (m_type) {
335: case TYPE_STRING:
336: vtable = "anno_text v";
337: break;
338: case TYPE_INT:
339: vtable = "anno_int v";
340: break;
341: case TYPE_FLOAT:
342: vtable = "anno_float v";
343: break;
344: case TYPE_DATE:
345: vtable = "anno_date v";
346: break;
347: case TYPE_BOOL:
348: vtable = "anno_bool v";
349: break;
350: }
351:
352: where += " AND " + getFunctionValue(m_key, null);
353: if (m_predicate == CONTAINS) {
354: where += " LIKE ";
355: if (m_value1 != null)
356: where += "'%" + m_value1 + "%'";
357: } else {
358: where += PREDICATE_STRING[m_predicate];
359: if (m_value1 != null) {
360: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
361: where += " " + m_value1;
362: else
363: where += " '" + m_value1 + "'";
364: }
365: }
366:
367: if (m_predicate == BETWEEN && m_value2 != null) {
368: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
369: where += " AND " + m_value2;
370: else
371: where += " AND '" + m_value2 + "'";
372: }
373:
374: where += " AND k.id=v.id ";
375: sql = select + field + from + ktable + comma + vtable + where
376: + ext;
377: return sql;
378: }
379:
380: public String toXQuery(String var) {
381: String xquery = "";
382:
383: if (m_predicate == AND)
384: return " and ";
385:
386: if (m_predicate == OR)
387: return " or ";
388:
389: if (m_predicate == NOT) {
390: return " not ";
391: }
392:
393: String name = "";
394: if (m_key != null)
395: name = var + "[@name = '" + getFunctionKey(m_key) + "']";
396:
397: if (m_predicate == EXISTS) {
398: //only need to check key
399: xquery += "exists(" + name + ")";
400: return xquery;
401: }
402:
403: //need to check value
404: /*
405: switch (m_type) {
406: case TYPE_STRING:
407: break;
408: case TYPE_INT:
409: xquery += "[@type = 'int']";
410: break;
411: case TYPE_FLOAT:
412: xquery += "[@type = 'float']";
413: break;
414: case TYPE_DATE:
415: break;
416: case TYPE_BOOL:
417: break;
418: }
419: */
420:
421: String value = getFunctionValue(m_key, name);
422: if (m_predicate == CONTAINS) {
423: xquery += "contains(" + value + ",";
424: if (m_value1 != null) {
425: xquery += "'" + m_value1 + "'";
426: }
427: xquery += ")";
428:
429: } else {
430: xquery += value;
431: if (m_predicate == BETWEEN)
432: xquery += " >= ";
433: else
434: xquery += " " + PREDICATE_STRING[m_predicate];
435: if (m_value1 != null) {
436: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
437: xquery += " " + m_value1;
438: else
439: xquery += " '" + m_value1 + "'";
440: }
441: }
442:
443: if (m_predicate == BETWEEN && m_value2 != null) {
444: if (m_type == TYPE_INT || m_type == TYPE_FLOAT)
445: xquery += " and " + value + " <= " + m_value2;
446: else
447: xquery += " and " + value + " <= '" + m_value2 + "'";
448: }
449:
450: return xquery;
451: }
452: }
|