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:
016: package org.griphyn.vdl.directive;
017:
018: import java.io.*;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.sql.SQLException;
022: import org.griphyn.common.util.Currently;
023: import org.griphyn.vdl.parser.VDLxParser;
024: import org.griphyn.vdl.classes.*;
025: import org.griphyn.vdl.dbschema.*;
026: import org.griphyn.vdl.annotation.*;
027: import org.griphyn.vdl.util.Logging;
028: import java.util.MissingResourceException;
029:
030: /**
031: * This class searches for definitions that either match certain
032: * namespace, name, version combination, or contain a certain
033: * LFN.
034: *
035: * @author Jens-S. Vöckler
036: * @author Yong Zhao
037: * @version $Revision: 50 $
038: *
039: * @see org.griphyn.vdl.parser.VDLxParser
040: * @see org.griphyn.vdl.dbschema.VDC
041: */
042: public class Search extends Directive {
043: /**
044: * Defines the output format constants
045: */
046: public static final int FORMAT_FQDN = 0;
047: public static final int FORMAT_VDLT = 1;
048: public static final int FORMAT_VDLX = 2;
049:
050: private DatabaseSchema m_dbschema = null;
051:
052: /**
053: * Constructor
054: */
055: public Search() throws IOException, MissingResourceException {
056: super ();
057: }
058:
059: /**
060: * Constructor
061: * @param dbs is the database schema instance
062: */
063: public Search(DatabaseSchema dbs) throws IOException,
064: MissingResourceException {
065: m_dbschema = dbs;
066: }
067:
068: /**
069: * set database schema
070: * @param dbs is the database schema instance
071: */
072: public void setDatabaseSchema(DatabaseSchema dbs) {
073: m_dbschema = dbs;
074: }
075:
076: /**
077: * Search for definitions that contain LFN of specific name
078: * and link type. This method does not allow jokers.
079: *
080: * @param filename the LFN name
081: * @param link the linkage type of the LFN
082: * @return a list of Definition items that match the criterion.
083: *
084: * @see org.griphyn.vdl.classes.LFN#NONE
085: * @see org.griphyn.vdl.classes.LFN#INPUT
086: * @see org.griphyn.vdl.classes.LFN#OUTPUT
087: * @see org.griphyn.vdl.classes.LFN#INOUT
088: */
089: public java.util.List searchDefinition(String filename, int link)
090: throws java.sql.SQLException {
091: return ((VDC) m_dbschema).searchFilename(filename, link);
092: }
093:
094: /**
095: * Search the database for definitions by ns::name:version triple
096: * and by type (either Transformation or Derivation). This version
097: * of the search allows for jokers expressed as null value
098: *
099: * @param namespace namespace, null to match any namespace
100: * @param name name, null to match any name
101: * @param version version, null to match any version
102: * @param clsType type of definition, see below, or -1 as wildcard
103: * @return a list of Definition items, which may be empty
104: *
105: * @see org.griphyn.vdl.classes.Definition#TRANSFORMATION
106: * @see org.griphyn.vdl.classes.Definition#DERIVATION
107: */
108: public java.util.List searchDefinition(String namespace,
109: String name, String version, int clsType)
110: throws java.sql.SQLException {
111: return ((VDC) m_dbschema).searchDefinition(namespace, name,
112: version, clsType);
113: }
114:
115: /**
116: * Checks a string for the presence of joker characters.
117: *
118: * @param s is the input string
119: * @return true, if a joker character was detected, false otherwise
120: * and null strings.
121: */
122: private boolean hasJoker(String s) {
123: return (s == null ? false
124: : (s.indexOf('*') + s.indexOf('?') != -2));
125: }
126:
127: /**
128: * Translates the regular shell-style jokers into SQL jokers.
129: * Simultaneously protects (with backslash for now) any SQL jokers to
130: * make them literal.
131: *
132: * @param hasJoker is flagged, if the string contains shell jokers
133: * @param s input string to translate
134: * @return translated string -- may be the original reference
135: */
136: private String mask(boolean hasJoker, String s) {
137: String result = s;
138: if (s == null)
139: return result;
140:
141: if (result.indexOf('%') + result.indexOf('_') != -2) {
142: // has SQL jokers, protect them (backslash for now)
143: result = result.replaceAll("([%_])", "\\\\$1");
144: }
145:
146: if (hasJoker) {
147: // turn jokers into SQL jokers
148: result = result.replace('*', '%').replace('?', '_');
149: }
150:
151: return result;
152: }
153:
154: /**
155: * Search the database for definitions by ns::name:version triple
156: * and by type (either Transformation or Derivation). This version
157: * of the search allows for jokers expressed as null value, or special
158: * characters '%' and '_'.
159: *
160: * @param namespace namespace, null to match any namespace
161: * @param name name, null to match any name
162: * @param version version, null to match any version
163: * @param clsType type of definition, see below, or -1 as wildcard
164: * @return a list of Definition items, which may be empty
165: *
166: * @see org.griphyn.vdl.classes.Definition#TRANSFORMATION
167: * @see org.griphyn.vdl.classes.Definition#DERIVATION
168: */
169: public java.util.List searchDefinitionEx(String namespace,
170: String name, String version, int clsType)
171: throws java.sql.SQLException {
172: boolean b1 = hasJoker(namespace);
173: boolean b2 = hasJoker(name);
174: boolean b3 = hasJoker(version);
175: if (b1 || b2 || b3) {
176: // protect and translate jokers
177: return ((Advanced) m_dbschema).searchDefinitionEx(mask(b1,
178: namespace), mask(b2, name), mask(b3, version),
179: clsType);
180: } else {
181: // no jokers, use potentially more efficient query
182: return ((VDC) m_dbschema).searchDefinition(namespace, name,
183: version, clsType);
184: }
185: }
186:
187: /**
188: * Search for LFNs or Definitions that has certain annotations
189: *
190: * @param kind defines the kind/class of object annotated.
191: * @param arg is used only for TR ARG and TR CALL. For the former
192: * it is the name of the argument (String), for the latter the position of
193: * the call (Integer).
194: * @param tree stores the query tree to query the annotation
195: * @return a list of LFNs if search for filenames, otherwise a list of
196: * definitions.
197: * @exception SQLException if something goes wrong with the database.
198: * @see org.griphyn.vdl.annotation.QueryTree
199: */
200: public java.util.List searchAnnotation(int kind, Object arg,
201: QueryTree tree) throws java.sql.SQLException {
202: return ((Annotation) m_dbschema).searchAnnotation(kind, arg,
203: tree);
204: }
205:
206: /**
207: * Print a list of definitions in different format: fqdn, vdlt, and vdlx
208: *
209: * @param writer the target to output the list
210: * @param defList a list of definitions
211: * @param format the output format
212: *
213: * @see #FORMAT_FQDN
214: * @see #FORMAT_VDLT
215: * @see #FORMAT_VDLX
216: * NOTE: might be better to move into another module?
217: */
218: public void printDefinitionList(Writer writer,
219: java.util.List defList, int format) throws IOException {
220: if (defList == null || defList.isEmpty())
221: return;
222: Definitions defs = new Definitions();
223: if (format != FORMAT_FQDN) {
224: defs.setDefinition(defList);
225: if (format == FORMAT_VDLX)
226: defs.toXML(writer, "");
227: else if (format == FORMAT_VDLT)
228: defs.toString(writer);
229: } else {
230: for (Iterator i = defList.iterator(); i.hasNext();) {
231: Definition def = (Definition) i.next();
232:
233: writer.write(def.identify());
234: writer.write("\n");
235: }
236: writer.flush();
237: }
238: }
239: }
|