/*
* 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.directive;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.sql.SQLException;
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.annotation.*;
import org.griphyn.vdl.util.Logging;
import java.util.MissingResourceException;
/**
* This class searches for definitions that either match certain
* namespace, name, version combination, or contain a certain
* LFN.
*
* @author Jens-S. Vöckler
* @author Yong Zhao
* @version $Revision$
*
* @see org.griphyn.vdl.parser.VDLxParser
* @see org.griphyn.vdl.dbschema.VDC
*/
public class Search extends Directive
{
/**
* Defines the output format constants
*/
public static final int FORMAT_FQDN = 0;
public static final int FORMAT_VDLT = 1;
public static final int FORMAT_VDLX = 2;
private DatabaseSchema m_dbschema = null;
/**
* Constructor
*/
public Search()
throws IOException, MissingResourceException
{
super();
}
/**
* Constructor
* @param dbs is the database schema instance
*/
public Search(DatabaseSchema dbs)
throws IOException, MissingResourceException
{
m_dbschema = dbs;
}
/**
* set database schema
* @param dbs is the database schema instance
*/
public void setDatabaseSchema(DatabaseSchema dbs)
{
m_dbschema = dbs;
}
/**
* Search for definitions that contain LFN of specific name
* and link type. This method does not allow jokers.
*
* @param filename the LFN name
* @param link the linkage type of the LFN
* @return a list of Definition items that match the criterion.
*
* @see org.griphyn.vdl.classes.LFN#NONE
* @see org.griphyn.vdl.classes.LFN#INPUT
* @see org.griphyn.vdl.classes.LFN#OUTPUT
* @see org.griphyn.vdl.classes.LFN#INOUT
*/
public java.util.List searchDefinition(String filename, int link)
throws java.sql.SQLException
{
return ((VDC)m_dbschema).searchFilename(filename, link);
}
/**
* Search the database for definitions by ns::name:version triple
* and by type (either Transformation or Derivation). This version
* of the search allows for jokers expressed as null value
*
* @param namespace namespace, null to match any namespace
* @param name name, null to match any name
* @param version version, null to match any version
* @param clsType type of definition, see below, or -1 as wildcard
* @return a list of Definition items, which may be empty
*
* @see org.griphyn.vdl.classes.Definition#TRANSFORMATION
* @see org.griphyn.vdl.classes.Definition#DERIVATION
*/
public java.util.List searchDefinition( String namespace,
String name,
String version,
int clsType )
throws java.sql.SQLException
{
return ((VDC)m_dbschema).searchDefinition(namespace, name, version, clsType );
}
/**
* Checks a string for the presence of joker characters.
*
* @param s is the input string
* @return true, if a joker character was detected, false otherwise
* and null strings.
*/
private boolean hasJoker( String s )
{
return ( s == null ? false : ( s.indexOf('*')+s.indexOf('?') != -2 ) );
}
/**
* Translates the regular shell-style jokers into SQL jokers.
* Simultaneously protects (with backslash for now) any SQL jokers to
* make them literal.
*
* @param hasJoker is flagged, if the string contains shell jokers
* @param s input string to translate
* @return translated string -- may be the original reference
*/
private String mask( boolean hasJoker, String s )
{
String result = s;
if ( s == null ) return result;
if ( result.indexOf('%')+result.indexOf('_') != -2 ) {
// has SQL jokers, protect them (backslash for now)
result = result.replaceAll( "([%_])", "\\\\$1" );
}
if ( hasJoker ) {
// turn jokers into SQL jokers
result = result.replace('*','%').replace('?','_');
}
return result;
}
/**
* Search the database for definitions by ns::name:version triple
* and by type (either Transformation or Derivation). This version
* of the search allows for jokers expressed as null value, or special
* characters '%' and '_'.
*
* @param namespace namespace, null to match any namespace
* @param name name, null to match any name
* @param version version, null to match any version
* @param clsType type of definition, see below, or -1 as wildcard
* @return a list of Definition items, which may be empty
*
* @see org.griphyn.vdl.classes.Definition#TRANSFORMATION
* @see org.griphyn.vdl.classes.Definition#DERIVATION
*/
public java.util.List searchDefinitionEx( String namespace,
String name,
String version,
int clsType )
throws java.sql.SQLException
{
boolean b1 = hasJoker(namespace);
boolean b2 = hasJoker(name);
boolean b3 = hasJoker(version);
if ( b1 || b2 || b3 ) {
// protect and translate jokers
return ((Advanced)m_dbschema).searchDefinitionEx( mask(b1,namespace),
mask(b2,name),
mask(b3,version),
clsType );
} else {
// no jokers, use potentially more efficient query
return ((VDC)m_dbschema).searchDefinition(namespace,name,version,clsType);
}
}
/**
* Search for LFNs or Definitions that has certain annotations
*
* @param kind defines the kind/class of object annotated.
* @param arg is used only for TR ARG and TR CALL. For the former
* it is the name of the argument (String), for the latter the position of
* the call (Integer).
* @param tree stores the query tree to query the annotation
* @return a list of LFNs if search for filenames, otherwise a list of
* definitions.
* @exception SQLException if something goes wrong with the database.
* @see org.griphyn.vdl.annotation.QueryTree
*/
public java.util.List searchAnnotation( int kind,
Object arg,
QueryTree tree)
throws java.sql.SQLException
{
return ((Annotation)m_dbschema).searchAnnotation(kind, arg, tree);
}
/**
* Print a list of definitions in different format: fqdn, vdlt, and vdlx
*
* @param writer the target to output the list
* @param defList a list of definitions
* @param format the output format
*
* @see #FORMAT_FQDN
* @see #FORMAT_VDLT
* @see #FORMAT_VDLX
* NOTE: might be better to move into another module?
*/
public void printDefinitionList(Writer writer, java.util.List defList, int format)
throws IOException
{
if (defList == null || defList.isEmpty())
return;
Definitions defs = new Definitions();
if ( format != FORMAT_FQDN ) {
defs.setDefinition(defList);
if ( format == FORMAT_VDLX )
defs.toXML(writer, "");
else if ( format == FORMAT_VDLT)
defs.toString(writer);
} else {
for ( Iterator i=defList.iterator(); i.hasNext(); ) {
Definition def = (Definition) i.next();
writer.write(def.identify());
writer.write("\n");
}
writer.flush();
}
}
}