/*
* 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.sql.SQLException;
import java.util.Set;
import java.util.TreeSet;
import org.griphyn.vdl.directive.*;
import org.griphyn.vdl.parser.*;
import org.griphyn.vdl.util.Logging;
import java.util.regex.*;
/**
* This class encapsulates common helper functions for VDL parsing.
*
* @author Jens-S. Vöckler
* @author Yong Zhao
* @version $Revision$
*
* @see UpdateVDC
* @see VDLc
* @see org.griphyn.vdl.parser.VDLtParser
* @see org.griphyn.vdl.parser.VDLxParser
*/
public abstract class VDLHelper extends Toolkit
{
/**
* Pattern to match against when recognizing VDLx from VDLt.
* recognizes: "<?xml " "<definition " "<ns1:definition "
*/
private static final String c_pattern =
"^\\s*<(?:(?:\\w+:)?definitions|\\?\\s*xml)\\s+";
/**
* Converter for VDLt to VDLx, is a singleton.
*/
private static VDLtConvert c_t2x = null;
/**
* ctor: Constructs a new instance object with the given application name.
*
* @param appName is the name of the shell wrapper with which to report.
*/
public VDLHelper( String appName )
{
super(appName);
}
/**
* Default ctor: Constructs a new instance object with the given
* application name.
*
* @param appName is the name of the shell wrapper with which to report.
* @param verbosity sets the verbosity level of the "app" logging queue.
*/
public VDLHelper( String appName, int verbosity )
{
super(appName,verbosity);
}
/**
* Determines if a file is VDLx or VDLt. It does so by
* expecting the ubiquitous XML preamble in the VDLx.
*
* @param filename is the name of the file
* @return true if the file is XML, false otherwise.
*/
public boolean isXML( String filename )
throws IOException
{
LineNumberReader lnr = new LineNumberReader(new FileReader(filename));
String line = null;
boolean result = false;
java.util.regex.Pattern p = java.util.regex.Pattern.compile( VDLHelper.c_pattern );
while ( (line = lnr.readLine()) != null &&
! result && lnr.getLineNumber() < 64 ) {
result = p.matcher(line).lookingAt();
}
lnr.close();
return result;
}
/**
* Determines, if input file is VDLt or VDLx. Parses VDLt into a
* temporary VDLx file. Adds VDLx into the VDC.
*
* @param filename is the file to add, either VDLt or VDLx content.
* @param define is a VDC connector to add to the VDC
* @param reject is a writer to gather definitions that were reject from
* the VDC, depending on the overwrite mode. If <code>null</code>, no rejects
* will be gathered.
* @param overwrite determines insert or update mode.
* @return the result from adding the XML into the VDC
* @see org.griphyn.vdl.directive.Define#updateVDC( Reader, Writer, boolean )
*/
public boolean addFileToVDC( String filename,
Define define,
Writer reject, boolean overwrite )
throws VDLtParserException, VDLtScannerException, IOException
{
// instantiate singleton, if necessary
if ( c_t2x == null ) c_t2x = new VDLtConvert();
File tempfn = null;
if ( isXML(filename) ) {
// VDLx file, no conversions necessary
tempfn = new File(filename);
} else {
// VDLt file, convert to XML
Reader r = new BufferedReader( new FileReader(filename) );
tempfn = File.createTempFile( "vdlc-", ".xml", null );
tempfn.deleteOnExit();
Writer w = new BufferedWriter( new FileWriter(tempfn) );
c_t2x.VDLt2VDLx( r, w );
r.close();
w.flush();
w.close();
}
return define.updateVDC( new BufferedReader( new FileReader(tempfn) ),
reject, overwrite );
}
/**
* Determines, if input file is VDLt or VDLx. Parses VDLt into a
* temporary VDLx file. Adds VDLx into the VDC. Skips to next file on
* error.
*
* @param args is the argument vector of main
* @param start is the start of filenames in the argument vector.
* @param define is a VDC connector to add to the VDC
* @param reject is a writer to gather definitions that were reject from
* the VDC, depending on the overwrite mode. If <code>null</code>, no rejects
* will be gathered.
* @param overwrite determines insert or update mode.
* @return a set of filenames which reported errors.
* @see #addFileToVDC( String, Define, Writer, boolean )
*/
public Set addFilesToVDC( String[] args, int start,
Define define,
Writer reject, boolean overwrite )
{
Set result = new TreeSet();
for ( int i = start; i < args.length; ++i ) {
m_logger.log( "app", 1, "parsing \"" + args[i] + "\"" );
try {
if ( ! addFileToVDC(args[i],define,reject,overwrite) ) {
// unsuccessful parsing
m_logger.log( "default", 0, "XML parsing error, skipping to next file" );
result.add( args[i] );
}
} catch ( VDLtParserException e ) {
m_logger.log( "default", 0, "syntactical error, skipping to next file" );
System.err.println( e.getMessage() );
result.add( args[i] );
} catch ( VDLtScannerException e ) {
m_logger.log( "default", 0, "lexical error, skipping to next file" );
System.err.println( e.getMessage() );
result.add( args[i] );
} catch ( IOException e ) {
m_logger.log( "default", 0, "I/O error, skipping to next file" );
System.err.println( e.getMessage() );
result.add( args[i] );
}
}
return result;
}
}