/* * 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.toolkit; import java.io.*; import java.util.Iterator; import java.util.List; import java.sql.SQLException; import edu.isi.pegasus.common.util.Version; import edu.isi.pegasus.common.util.Currently; import org.griphyn.vdl.parser.VDLxParser; import org.griphyn.vdl.classes.*; import org.griphyn.vdl.dbschema.*; import org.griphyn.vdl.util.Logging; import org.griphyn.vdl.util.ChimeraProperties; import org.griphyn.vdl.directive.*; import gnu.getopt.*; /** * This class searches definition's that match the namespace, name, version * triple, then prints the search results in one of the formats: vdlx, vdlt, * or name. * * @author Jens-S. Vöckler * @author Yong Zhao * @version $Revision$ * * @see org.griphyn.vdl.parser.VDLxParser */ public class XSearchVDC extends Toolkit { /** * Constructor */ public XSearchVDC(String appName) { super(appName); } /** * Prints the usage string. */ public void showUsage() { String linefeed = System.getProperty( "line.separator", "\r\n" ); System.out.println( "$Id$" + linefeed + "VDS version " + Version.instance().toString() + linefeed ); System.out.println( "Usage: " + this.m_application + " [general] [-t tr|dv] [-n ns] [-i id] [-v vs]" + linefeed + " or: " + this.m_application + " [general] [-t i|o|io] -f lfn" + linefeed + " or: " + this.m_application + " [general] -q query qargs" ); System.out.println( linefeed + "General options:" + linefeed + " -V|--version print version information and exit." + linefeed + " -d|--dbase dbx associates the dbname with the database, unused." + linefeed + " --verbose increases the verbosity level." + linefeed + " -l|--list x|t|n print x:VDLx, t:VDLt or just a table of n:names." + linefeed + " -e|--error if present, return failure for an empty search." + linefeed + " -o|--output fn put the output into the file fn, default is stdout." + linefeed + linefeed + "Group 1: Searching for definitions" + linefeed + " -t|--type tr|dv Search only for TR or DV, default is both." + linefeed + " -n|--namespace ns Search for matches with namespace ns, default wildcard." + linefeed + " -i|--name id Search for matches with name id, default wildcard." + linefeed + " -v|--ver vs Search for matches with version vs, default wildcard." + linefeed + linefeed + "Group 2: Searching for logical filenames" + linefeed + " -t|--type i|o|io Limit search to (i)n, (o)ut or (io) filenames." + linefeed + " -f|--lfn lfn Limit search to filename lfn, default wildcard." + linefeed + linefeed + "Group 3: Searching by ... what? ... Yong?" + linefeed + " -q|--query query ????" + linefeed ); } /** * Creates a set of options. */ protected LongOpt[] generateValidOptions() { LongOpt[] lo = new LongOpt[17]; lo[0] = new LongOpt( "help", LongOpt.NO_ARGUMENT, null, 'h' ); lo[1] = new LongOpt( "dbase", LongOpt.REQUIRED_ARGUMENT, null, 'd' ); lo[2] = new LongOpt( "version", LongOpt.NO_ARGUMENT, null, 'V' ); lo[3] = new LongOpt( "verbose", LongOpt.NO_ARGUMENT, null, 1 ); lo[4] = new LongOpt( "list", LongOpt.REQUIRED_ARGUMENT, null, 'l' ); lo[5] = new LongOpt( "error", LongOpt.NO_ARGUMENT, null, 'e' ); lo[6] = new LongOpt( "output", LongOpt.REQUIRED_ARGUMENT, null, 'o' ); lo[7] = new LongOpt( "type", LongOpt.REQUIRED_ARGUMENT, null, 't' ); lo[8] = new LongOpt( "namespace", LongOpt.REQUIRED_ARGUMENT, null, 'n' ); lo[9] = new LongOpt( "ns", LongOpt.REQUIRED_ARGUMENT, null, 'n' ); lo[10] = new LongOpt( "name", LongOpt.REQUIRED_ARGUMENT, null, 'i' ); lo[11] = new LongOpt( "id", LongOpt.REQUIRED_ARGUMENT, null, 'i' ); lo[12] = new LongOpt( "ver", LongOpt.REQUIRED_ARGUMENT, null, 'v' ); lo[13] = new LongOpt( "vs", LongOpt.REQUIRED_ARGUMENT, null, 'v' ); lo[14] = new LongOpt( "file", LongOpt.REQUIRED_ARGUMENT, null, 'f' ); lo[15] = new LongOpt( "lfn", LongOpt.REQUIRED_ARGUMENT, null, 'f' ); lo[16] = new LongOpt( "query", LongOpt.REQUIRED_ARGUMENT, null, 'q' ); return lo; } /** * search the database for specific TR's or DV's */ public static void main(String[] args) { int result = 0; boolean emptyFailure = false; boolean seenResults = false; try { XSearchVDC me = new XSearchVDC("xsearchvdc"); // get the commandline options Getopt opts = new Getopt( me.m_application, args, "hd:l:ef:q:o:t:n:i:v:V", me.generateValidOptions() ); opts.setOpterr(false); String dbase = null; String ns = null; String name = null; String ver = null; String lfn = null; String outfn = null; String format = null; String t = null; String query = null; int option = 0; while ( (option = opts.getopt()) != -1 ) { switch ( option ) { case 1: me.increaseVerbosity(); break; case 'V': System.out.println( "$Id$" ); System.out.println( "VDS version " + Version.instance().toString() ); return; case 'd': dbase = opts.getOptarg(); break; case 'e': emptyFailure = true; break; case 'f': lfn = opts.getOptarg(); break; case 'i': name = opts.getOptarg(); break; case 'l': format = opts.getOptarg().toLowerCase(); break; case 'n': ns = opts.getOptarg(); break; case 'o': outfn = opts.getOptarg(); break; case 'q': query = opts.getOptarg(); break; case 't': t = opts.getOptarg().toLowerCase(); break; case 'v': ver = opts.getOptarg(); break; case 'h': default: me.showUsage(); return; } } boolean condition1 = ( lfn != null ); boolean condition2 = ( ns != null || name != null || ver != null ); boolean condition3 = ( query != null); if ( ( condition1 && (condition2 || condition3) ) || (condition2 && condition3) ) { me.showUsage(); throw new RuntimeException( "ERROR: you must either specify the -n -i -v options, the -f option, or the -q option!" ); } int link = -1; int clsType = -1; if (condition1) { // to search for input/output/inout file? if ( t != null ) { if ( t.equals("i") ) link = LFN.INPUT; else if ( t.equals("o") ) link = LFN.OUTPUT; else if ( t.equals("io") ) link = LFN.INOUT; else { System.err.println("Invalid value \"" + t + "\" for option -t"); me.showUsage(); System.exit(1); } } } else if (condition2) { // to search for tr/dv, or both if ( t != null ) { char c = t.charAt(0); if ( c == 'd' ) clsType = Definition.DERIVATION; else if ( c == 't' ) clsType = Definition.TRANSFORMATION; else { System.err.println("Invalid value \"" + t + "\" for option -t"); me.showUsage(); System.exit(1); } } } // get the output format, default is "n" if (format == null) format = "n"; int f = Search.FORMAT_FQDN; switch (format.charAt(0)) { case 'x' : f = Search.FORMAT_VDLX; break; case 't' : f = Search.FORMAT_VDLT; break; case 'n' : f = Search.FORMAT_FQDN; break; default : System.err.println("Invalid value \"" + format + "\" for option -l"); me.showUsage(); System.exit(1); } // Connect the database. String schemaName = ChimeraProperties.instance().getVDCSchemaName(); Connect connect = new Connect(); DatabaseSchema dbschema = connect.connectDatabase(schemaName); // Search the database. me.m_logger.log( "app", 1, "searching the database"); java.util.List defList = null; Search search = new Search(dbschema); if ( condition1 ) { //looking for lfn defList = search.searchDefinition( lfn, link ); } else if (condition3) { StringBuffer xquery = new StringBuffer(256); int start = opts.getOptind(); int arg_len = args.length; if ( dbschema instanceof XDC ) { if (query.equals("tr_dv")) { xquery.append( "for $t in //transformation[@name='" ); xquery.append( args[start] ); xquery.append( "'] return //derivation[@uses=$t/@name]" ); } else if (query.equals("dv_tr")) { xquery.append( "for $t in //derivation[@name='" ); xquery.append( args[start] ); xquery.append( "'] return //transformation[@name=$t/@uses]" ); } else if (query.equals("tr_call")) { xquery.append( "//transformation[call/@uses='" ); xquery.append( args[start] ); xquery.append( "']" ); } else if (query.equals("tr_para")) { xquery.append( "//transformation" ); int i = start; while ( i < arg_len ) { xquery.append("[declare[@name='").append(args[i]).append("']"); i++; if ( i < arg_len && ! args[i].equals("any") ) { xquery.append("[@link='").append(args[i]).append("']"); } i++; xquery.append("]"); } } else if (query.equals("tr_arg")) { xquery.append( "//transformation[contains(argument/*, '" ); xquery.append( args[start] ); xquery.append( "')]" ); } else if (query.equals("dv_pass")) { xquery.append( "//derivation[contains(pass//*, '" ); xquery.append( args[start] ); xquery.append( "')]" ); } else if (query.equals("tr_meta")) { xquery.append( "for $m in //metadata[@subject='tr'][attribute[@name='" ); xquery.append( args[start] ); xquery.append( "']" ); xquery.append("='").append(args[start+1]).append("']"); xquery.append(" let $mn:=$m/@name, $n := substring-before($mn, '::'), $na := substring-after($mn, '::'), $iv := if ($na) then $na else $mn, $v := substring-after($iv, ':'), $ib := substring-before($iv, ':'), $i := if ($ib) then $ib else $iv," ); xquery.append( " $t := if ($n) then if ($v) then //transformation[@namespace=$n][@name=$i][@version=$v] else //transformation[@namespace=$n][@name=$i][empty(@version)] else if ($v) then //transformation[empty(@namespace)][@name=$i][@version=$v] else //transformation[empty(@namespace)][@name=$i][empty(@version)]" ); xquery.append( " return $t[declare[@link='" ); xquery.append( args[start+2] ); xquery.append( "'][@name = $m/@select]]" ); } else if (query.equals("dv_tree")) { xquery.append("declare namespace v='http://www.griphyn.org/chimera';" ); xquery.append("declare function v:dv_tree($lfn as xs:string) as element()* {" ); xquery.append("let $d := //derivation[.//lfn[@file=$lfn][@link='input']]" ); xquery.append("return ( $d," ); xquery.append("for $out in $d//lfn[@link='output']/@file return v:dv_tree($out))" ); xquery.append("};" ); xquery.append("let $d := v:dv_tree('").append(args[start]).append("') return $d"); } else if (query.equals("lfn_tree")) { xquery.append("declare namespace v='http://www.griphyn.org/chimera';" ); xquery.append("declare function v:lfn_tree($lfn as xs:string) as item()* {" ); xquery.append("let $d := //derivation[.//lfn[@file=$lfn][@link='input']]" ); xquery.append("return ( $lfn," ); xquery.append("for $out in $d//lfn[@link='output']/@file return v:lfn_tree($out))" ); xquery.append("};" ); xquery.append("let $f := v:lfn_tree('").append(args[start]); xquery.append("') return distinct-values($f)" ); } else if (query.equals("lfn_meta")) { xquery.append( "for $m in //metadata[@subject='lfn']" ); int i = start; while (i < arg_len) { xquery.append("[attribute[@name='").append(args[i]).append("']"); i++; xquery.append("='").append(args[i]).append("']"); i++; } xquery.append( " return $m/@name" ); } else { xquery.append(query); } if (query.equals("lfn_meta") || query.equals("lfn_tree")) defList = ((XDC)dbschema).searchElements(xquery.toString()); else defList = ((XDC)dbschema).searchDefinition(xquery.toString()); } } else { //looking for definitions if ( dbschema instanceof Advanced ) defList = search.searchDefinitionEx( ns, name, ver, clsType ); else defList = search.searchDefinition( ns, name, ver, clsType ); } if ( defList != null && ! defList.isEmpty() ) { seenResults = true; Writer bw; if ( outfn != null ) { // save to file me.m_logger.log("app", 1, "Saving to the file " + outfn ); bw = new BufferedWriter(new FileWriter(outfn)); } else { bw = new PrintWriter(System.out); } if ( query != null && ( query.equals("lfn_meta") || query.equals("lfn_tree") ) ) for (Iterator i=defList.iterator(); i.hasNext();) bw.write((String)i.next() + "\n"); else search.printDefinitionList(bw, defList, f); bw.close(); } else { me.m_logger.log( "app", 1, "no results" ); } // done dbschema.close(); } catch ( RuntimeException rte ) { System.err.println( "ERROR: " + rte.getMessage() ); result = 1; } catch(Exception e) { e.printStackTrace(); result = 2; } // fail on empty result set, if requested if ( emptyFailure & ! seenResults ) result = 2; if ( result != 0 ) System.exit(result); } }