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: package org.griphyn.vdl.toolkit;
016:
017: import java.io.*;
018: import java.sql.SQLException;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.ArrayList;
022: import java.util.Set;
023: import java.util.TreeSet;
024: import org.griphyn.common.util.Version;
025: import org.griphyn.common.util.Currently;
026: import org.griphyn.vdl.parser.*;
027: import org.griphyn.vdl.dbdriver.*;
028: import org.griphyn.vdl.dbschema.*;
029: import org.griphyn.vdl.classes.Definitions;
030: import org.griphyn.vdl.classes.Definition;
031: import org.griphyn.vdl.util.Logging;
032: import org.griphyn.vdl.util.ChimeraProperties;
033: import org.griphyn.vdl.directive.*;
034: import org.xml.sax.InputSource;
035: import gnu.getopt.*;
036:
037: /**
038: * This class uses the <code>VDLxParser</code> to parse VDLx specifications
039: * and add them to the database backend. If a definition already exists
040: * in the database, it is updated in overwrite mode, or rejected in
041: * insert mode.
042: *
043: * @author Jens-S. Vöckler
044: * @author Yong Zhao
045: * @version $Revision: 50 $
046: *
047: * @see org.griphyn.vdl.parser.VDLxParser
048: */
049: public class UpdateVDC extends VDLHelper {
050: /**
051: * writer to output rejected definitions
052: */
053: private Writer m_reject = null;
054:
055: /**
056: * This initializies the class to handle inserts and updates, and
057: * optionally store the rejects for later availability.
058: *
059: * @param appName is the true name of the application
060: * @param reject is a writer to output rejected inserts.
061: * @param level is the verbosity level for the "app" logging queue.
062: */
063: public UpdateVDC(String appName, Writer reject, int level)
064: throws IOException {
065: super (appName, level);
066: m_reject = reject;
067: }
068:
069: /**
070: * Closes the rejects file, if still open.
071: */
072: protected void finalize() throws Throwable {
073: if (m_reject != null)
074: m_reject.close();
075: super .finalize();
076: }
077:
078: /**
079: * Prints the usage string.
080: *
081: * @param ow is the overwrite mode to distinguish between insert and update.
082: */
083: static public void showUsage(boolean ow) {
084: String linefeed = System.getProperty("line.separator", "\r\n");
085:
086: System.out
087: .println("$Id: UpdateVDC.java 50 2007-05-19 00:48:32Z gmehta $"
088: + linefeed
089: + "VDS version "
090: + Version.instance().toString() + linefeed);
091:
092: System.out.println("Usage: " + (ow ? "update" : "insert")
093: + "vdc [general] [-r fn] vdlx|vdlt [vdlt|vdlx [..]]");
094:
095: System.out
096: .println(linefeed
097: + " -V|--version print version information and exit."
098: + linefeed
099: + " -d|--dbase dbx associates the dbname with the database, unused."
100: + linefeed
101: + " --verbose increases the verbosity level."
102: + linefeed
103: + " -r|--rejects fn gathers the rejected definitions into file fn."
104: + linefeed);
105: }
106:
107: public void showUsage() {
108: showUsage(m_application != null
109: && m_application.charAt(0) == 'i');
110: }
111:
112: /**
113: * Creates a set of options.
114: */
115: protected static LongOpt[] generateValidOptions() {
116: LongOpt[] lo = new LongOpt[6];
117:
118: lo[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
119: lo[1] = new LongOpt("dbase", LongOpt.REQUIRED_ARGUMENT, null,
120: 'd');
121: lo[2] = new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V');
122: lo[3] = new LongOpt("verbose", LongOpt.NO_ARGUMENT, null, 1);
123:
124: lo[4] = new LongOpt("rejects", LongOpt.REQUIRED_ARGUMENT, null,
125: 'r');
126: lo[5] = new LongOpt("force", LongOpt.NO_ARGUMENT, null, 'f');
127: return lo;
128: }
129:
130: /**
131: * Add or update definition's from VDLx documents into the database.
132: */
133: public static void main(String[] args) {
134: int result = 0;
135:
136: try {
137: Getopt opts = new Getopt("(undef)", args, "Vhd:fr:",
138: generateValidOptions());
139: opts.setOpterr(false);
140:
141: Writer reject = null;
142: String dbase = null; // unused option
143: boolean overwrite = false; // --force
144: String filename = null; // reject file
145:
146: int verbose = 0;
147: int option = 0;
148: while ((option = opts.getopt()) != -1) {
149: switch (option) {
150: case 1:
151: ++verbose;
152: break;
153:
154: case 'V':
155: System.out
156: .println("$Id: UpdateVDC.java 50 2007-05-19 00:48:32Z gmehta $");
157: System.out.println("VDS version "
158: + Version.instance().toString());
159: return;
160:
161: case 'd':
162: dbase = opts.getOptarg();
163: break;
164:
165: case 'f':
166: // if force is not true, the program acts in insert mode,
167: // i.e. definition's already exist will not be overwritten.
168: overwrite = true;
169: break;
170:
171: case 'r':
172: filename = opts.getOptarg();
173: break;
174:
175: case 'h':
176: default:
177: showUsage(overwrite);
178: return;
179: }
180: }
181:
182: if (filename != null && filename.length() > 0)
183: reject = new BufferedWriter(new FileWriter(filename));
184: UpdateVDC me = new UpdateVDC(overwrite ? "updatevdc"
185: : "insertvdc", reject, verbose);
186:
187: if (opts.getOptind() >= args.length) {
188: // nothing to process -- what is this?
189: showUsage(overwrite);
190: throw new RuntimeException(
191: "You must specify at least one input file");
192: }
193:
194: // Connect the database.
195: String schemaName = ChimeraProperties.instance()
196: .getVDCSchemaName();
197: Connect connect = new Connect();
198: DatabaseSchema dbschema = connect
199: .connectDatabase(schemaName);
200: Define define = new Define(dbschema);
201: // if ( derivations.isEmpty() ) define.setDerivationMemory( true );
202:
203: // Add definitions to the database backend while parsing
204: Set badfile = me.addFilesToVDC(args, opts.getOptind(),
205: define, reject, overwrite);
206: int errcount = badfile.size();
207: if (errcount > 0) {
208: // previous section saw one or more errors, better give up.
209: for (Iterator i = badfile.iterator(); i.hasNext();) {
210: System.err.println("errors in "
211: + ((String) i.next()));
212: }
213: throw new RuntimeException("Detected " + errcount
214: + " error" + (errcount == 1 ? " " : "s ")
215: + "while parsing VDL");
216: }
217:
218: if (reject != null)
219: reject.close();
220: int count = define.getNumberSaved();
221: int rejected = define.getNumberRejected();
222:
223: me.m_logger.log("app", 1, "modified " + count
224: + " definition" + (count == 1 ? "" : "s"));
225: me.m_logger.log("app", 1, "rejected " + rejected
226: + " definition" + (rejected == 1 ? "" : "s"));
227: define.close();
228: } catch (RuntimeException rte) {
229: System.err.println("ERROR: " + rte.getMessage());
230: result = 1;
231: } catch (Exception e) {
232: System.err.println("FATAL: " + e.getMessage());
233: e.printStackTrace();
234: result = 2;
235: }
236:
237: // Java will return with 0 unless exit is used. Unfortunately, using
238: // System.exit sometimes has some unwanted side-effects on d'tors,
239: // thus avoid using it unless strictly necessary.
240: if (result != 0)
241: System.exit(result);
242: }
243: }
|