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.sql.SQLException;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.ArrayList;
023: import java.util.Set;
024: import java.util.HashSet;
025: import java.util.MissingResourceException;
026: import org.griphyn.common.util.Currently;
027: import org.griphyn.vdl.parser.*;
028: import org.griphyn.vdl.dbdriver.*;
029: import org.griphyn.vdl.dbschema.*;
030: import org.griphyn.vdl.classes.Definitions;
031: import org.griphyn.vdl.classes.Definition;
032: import org.griphyn.vdl.classes.Derivation;
033: import org.griphyn.vdl.util.Logging;
034: import org.xml.sax.InputSource;
035:
036: /**
037: * This class parses VDL XML specifications and stores
038: * them to database backend.
039: *
040: * @author Jens-S. Vöckler
041: * @author Yong Zhao
042: * @version $Revision: 50 $
043: *
044: * @see org.griphyn.vdl.parser.VDLxParser
045: * @see org.griphyn.vdl.parser.DefinitionHandler
046: */
047: public class Define extends Directive implements DefinitionHandler {
048: /**
049: * This determines the behavior: insert mode (false) or update mode (true)
050: */
051: private boolean m_overwrite;
052:
053: /**
054: * This variable keeps the stream to print rejects onto, may be null.
055: */
056: private Writer m_rejects = null;
057:
058: /**
059: * Counts the number of successful database manipulations.
060: */
061: private int m_count = 0;
062:
063: /**
064: * Counts the rejected manipulations.
065: */
066: private int m_rejected = 0;
067:
068: /**
069: * database manipulator.
070: */
071: private DatabaseSchema m_dbschema = null;
072:
073: /**
074: * If enabled, collapses the names of DVs that were processed.
075: */
076: private java.util.Set m_derivations = null;
077:
078: /**
079: * Constructor
080: */
081: public Define() throws IOException, MissingResourceException {
082: super ();
083: }
084:
085: /**
086: * Constructor, set database schema instance
087: * @param dbs the database schema instance
088: */
089: public Define(DatabaseSchema dbs) throws IOException,
090: MissingResourceException {
091: m_dbschema = dbs;
092: }
093:
094: /**
095: * set database schema
096: * @param dbs the database schema instance
097: */
098: public void setDatabaseSchema(DatabaseSchema dbs) {
099: m_dbschema = dbs;
100: }
101:
102: /**
103: * Closes the associated database backend and invalidates the schema.
104: */
105: public void close() throws SQLException {
106: if (m_dbschema != null)
107: m_dbschema.close();
108: m_dbschema = null;
109: }
110:
111: /**
112: * Returns the remembered derivations.
113: *
114: * @return all remembered derivations, an empty set if none
115: * were found, or <code>null</code> if remembering was off.
116: * @see #setDerivationMemory( boolean )
117: */
118: public Set getDerivationMemory() {
119: return m_derivations;
120: }
121:
122: /**
123: * Toggles the remembering of derivations that were processed.
124: *
125: * @param on is true to enable derivation memory
126: * @see #getDerivationMemory()
127: */
128: public void setDerivationMemory(boolean on) {
129: if (on) {
130: // enable remembering derivations
131: if (m_derivations == null)
132: m_derivations = new java.util.HashSet();
133: } else {
134: // disable remembering derivations
135: m_derivations = null;
136: }
137: }
138:
139: /**
140: * Insert definitions into database, if a definition already
141: * exists in the database, then it is rejected. This method
142: * does not keep track of rejected ones.
143: *
144: * @param reader the reader to vdlx source
145: * @return true if insersion is successful
146: */
147: public boolean insertVDC(Reader reader) {
148: return updateVDC(reader, null, false);
149: }
150:
151: /**
152: * Insert definitions into database, if a definition already
153: * exists in the database, then it is rejected. This method
154: * keeps track of rejected ones.
155: *
156: * @param reader the reader to vdlx source
157: * @param writer writer to output the rejected definitions
158: * @return true if insersion is successful
159: */
160: public boolean insertVDC(Reader reader, Writer writer) {
161: return updateVDC(reader, writer, false);
162: }
163:
164: /**
165: * Insert definitions into database, if a definition already
166: * exists in the database, then overwrite it. This method
167: * does not keep track of overwritten ones.
168: *
169: * @param reader the reader to vdlx source
170: * @return true if update is successful
171: */
172: public boolean updateVDC(Reader reader) {
173: return updateVDC(reader, null, true);
174: }
175:
176: /**
177: * Insert definitions into database, if a definition already
178: * exists in the database, then overwrite it. This method
179: * keeps track of overwritten ones.
180: *
181: * @param reader the reader to vdlx source
182: * @param writer writer to output the overwritten definitions
183: * @return true if update is successful
184: */
185: public boolean updateVDC(Reader reader, Writer writer) {
186: return updateVDC(reader, writer, true);
187: }
188:
189: /**
190: * Insert definitions into database, if a definition already
191: * exists in the database, then either update the definition or
192: * reject the definition.
193: *
194: * @param reader the reader to vdlx source
195: * @param writer writer to output the overwritten/rejected definitions
196: * @return true if update is successful
197: */
198: public boolean updateVDC(Reader reader, Writer writer,
199: boolean overwrite) {
200: m_rejects = writer;
201: m_overwrite = overwrite;
202: m_count = m_rejected = 0;
203:
204: org.griphyn.vdl.parser.VDLxParser parser = new org.griphyn.vdl.parser.VDLxParser(
205: m_props.getVDLSchemaLocation());
206:
207: return parser.parse(new InputSource(reader), this );
208: }
209:
210: /**
211: * This method implements the interface defined in DefinitionHandler
212: * to save definition to database backend.
213: *
214: * @param d is the Definition that is ready to be stored.
215: * @return true, if new version was stored and database modified,
216: * false, if the definition was rejected for any reason.
217: */
218: public boolean store(Definition d) {
219: boolean result = false;
220: VDC vdc = (VDC) m_dbschema;
221:
222: // NEW: remember all DVs we came across
223: if (m_derivations != null && d instanceof Derivation)
224: m_derivations.add(d.shortID());
225:
226: try {
227: if (m_rejects == null) {
228: // rely on saveDefinition to do "the right thing"
229: result = vdc.saveDefinition(d, m_overwrite);
230: } else {
231: // Is the Definition already in the database?
232: if (vdc.containsDefinition(d)) {
233: if (m_overwrite) {
234: // this is time-consuming and ineffective
235: Definition old = vdc.loadDefinition(d
236: .getNamespace(), d.getName(), d
237: .getVersion(), d.getType());
238: old.toXML(m_rejects, " ");
239: result = vdc.saveDefinition(d, true);
240: } else {
241: // skip, if not forced to overwrite, but save rejects
242: d.toXML(m_rejects, " ");
243: }
244: } else {
245: // not found, insert unconditionally
246: result = vdc.saveDefinition(d, true);
247: }
248: }
249: } catch (SQLException sql) {
250: // database problems
251: for (int i = 0; sql != null; ++i) {
252: m_logger.log("database", 0, "SQL error " + i + ": "
253: + sql.getErrorCode() + ": " + sql.getMessage());
254: sql = sql.getNextException();
255: }
256: m_logger.log("database", 0, "ignoring SQL exception(s)");
257: } catch (Exception e) {
258: m_logger.log("database", 0, "caught " + e + ", ignoring");
259: result = false;
260: }
261:
262: if (result)
263: m_count++;
264: else
265: m_rejected++;
266: return result;
267: }
268:
269: /**
270: * return the number of successfully saved definitions
271: */
272: public int getNumberSaved() {
273: return m_count;
274: }
275:
276: /**
277: * return the number of rejected definitions
278: */
279: public int getNumberRejected() {
280: return m_rejected;
281: }
282: }
|