/* * 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.sql.SQLException; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.MissingResourceException; import edu.isi.pegasus.common.util.Currently; import org.griphyn.vdl.parser.*; import org.griphyn.vdl.dbdriver.*; import org.griphyn.vdl.dbschema.*; import org.griphyn.vdl.classes.Definitions; import org.griphyn.vdl.classes.Definition; import org.griphyn.vdl.classes.Derivation; import org.griphyn.vdl.util.Logging; import org.xml.sax.InputSource; /** * This class parses VDL XML specifications and stores * them to database backend. * * @author Jens-S. Vöckler * @author Yong Zhao * @version $Revision$ * * @see org.griphyn.vdl.parser.VDLxParser * @see org.griphyn.vdl.parser.DefinitionHandler */ public class Define extends Directive implements DefinitionHandler { /** * This determines the behavior: insert mode (false) or update mode (true) */ private boolean m_overwrite; /** * This variable keeps the stream to print rejects onto, may be null. */ private Writer m_rejects = null; /** * Counts the number of successful database manipulations. */ private int m_count = 0; /** * Counts the rejected manipulations. */ private int m_rejected = 0; /** * database manipulator. */ private DatabaseSchema m_dbschema = null; /** * If enabled, collapses the names of DVs that were processed. */ private java.util.Set m_derivations = null; /** * Constructor */ public Define() throws IOException, MissingResourceException { super(); } /** * Constructor, set database schema instance * @param dbs the database schema instance */ public Define(DatabaseSchema dbs) throws IOException, MissingResourceException { m_dbschema = dbs; } /** * set database schema * @param dbs the database schema instance */ public void setDatabaseSchema(DatabaseSchema dbs) { m_dbschema = dbs; } /** * Closes the associated database backend and invalidates the schema. */ public void close() throws SQLException { if ( m_dbschema != null ) m_dbschema.close(); m_dbschema = null; } /** * Returns the remembered derivations. * * @return all remembered derivations, an empty set if none * were found, or <code>null</code> if remembering was off. * @see #setDerivationMemory( boolean ) */ public Set getDerivationMemory() { return m_derivations; } /** * Toggles the remembering of derivations that were processed. * * @param on is true to enable derivation memory * @see #getDerivationMemory() */ public void setDerivationMemory( boolean on ) { if ( on ) { // enable remembering derivations if ( m_derivations == null ) m_derivations = new java.util.HashSet(); } else { // disable remembering derivations m_derivations = null; } } /** * Insert definitions into database, if a definition already * exists in the database, then it is rejected. This method * does not keep track of rejected ones. * * @param reader the reader to vdlx source * @return true if insersion is successful */ public boolean insertVDC(Reader reader) { return updateVDC(reader, null, false); } /** * Insert definitions into database, if a definition already * exists in the database, then it is rejected. This method * keeps track of rejected ones. * * @param reader the reader to vdlx source * @param writer writer to output the rejected definitions * @return true if insersion is successful */ public boolean insertVDC(Reader reader, Writer writer) { return updateVDC(reader, writer, false); } /** * Insert definitions into database, if a definition already * exists in the database, then overwrite it. This method * does not keep track of overwritten ones. * * @param reader the reader to vdlx source * @return true if update is successful */ public boolean updateVDC(Reader reader) { return updateVDC(reader, null, true); } /** * Insert definitions into database, if a definition already * exists in the database, then overwrite it. This method * keeps track of overwritten ones. * * @param reader the reader to vdlx source * @param writer writer to output the overwritten definitions * @return true if update is successful */ public boolean updateVDC(Reader reader, Writer writer) { return updateVDC(reader, writer, true); } /** * Insert definitions into database, if a definition already * exists in the database, then either update the definition or * reject the definition. * * @param reader the reader to vdlx source * @param writer writer to output the overwritten/rejected definitions * @return true if update is successful */ public boolean updateVDC(Reader reader, Writer writer, boolean overwrite) { m_rejects = writer; m_overwrite = overwrite; m_count = m_rejected = 0; org.griphyn.vdl.parser.VDLxParser parser = new org.griphyn.vdl.parser.VDLxParser(m_props.getVDLSchemaLocation()); return parser.parse( new InputSource(reader), this ); } /** * This method implements the interface defined in DefinitionHandler * to save definition to database backend. * * @param d is the Definition that is ready to be stored. * @return true, if new version was stored and database modified, * false, if the definition was rejected for any reason. */ public boolean store( Definition d ) { boolean result = false; VDC vdc = (VDC)m_dbschema; // NEW: remember all DVs we came across if ( m_derivations != null && d instanceof Derivation ) m_derivations.add( d.shortID() ); try { if ( m_rejects == null ) { // rely on saveDefinition to do "the right thing" result = vdc.saveDefinition( d, m_overwrite ); } else { // Is the Definition already in the database? if ( vdc.containsDefinition(d) ) { if ( m_overwrite ) { // this is time-consuming and ineffective Definition old = vdc.loadDefinition( d.getNamespace(), d.getName(), d.getVersion(), d.getType() ); old.toXML( m_rejects, " " ); result = vdc.saveDefinition( d, true ); } else { // skip, if not forced to overwrite, but save rejects d.toXML( m_rejects, " " ); } } else { // not found, insert unconditionally result = vdc.saveDefinition( d, true ); } } } catch ( SQLException sql ) { // database problems for ( int i=0; sql != null; ++i ) { m_logger.log( "database", 0, "SQL error " + i + ": " + sql.getErrorCode() + ": " + sql.getMessage() ); sql = sql.getNextException(); } m_logger.log( "database", 0, "ignoring SQL exception(s)" ); } catch ( Exception e ) { m_logger.log( "database", 0, "caught " + e + ", ignoring" ); result = false; } if ( result ) m_count++; else m_rejected++; return result; } /** * return the number of successfully saved definitions */ public int getNumberSaved() { return m_count; } /** * return the number of rejected definitions */ public int getNumberRejected() { return m_rejected; } }