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.toolkit;
017:
018: import java.io.*;
019: import java.util.*;
020: import gnu.getopt.*;
021:
022: import org.griphyn.vdl.util.Logging;
023: import org.griphyn.vdl.util.ChimeraProperties;
024: import org.griphyn.vdl.dbschema.*;
025: import org.griphyn.vdl.directive.*;
026: import org.griphyn.vdl.annotation.*;
027: import org.griphyn.common.util.Separator;
028: import org.griphyn.common.util.Version;
029:
030: /**
031: * This class inserts annotations into the backend database.
032: *
033: * @author Jens-S. Vöckler
034: * @author Yong Zhao
035: * @version $Revision: 50 $
036: *
037: */
038:
039: public class InsertMeta extends Toolkit {
040: /**
041: * Constructor
042: */
043: public InsertMeta(String appName) {
044: super (appName);
045: }
046:
047: /**
048: * Prints the usage string.
049: */
050: public void showUsage() {
051: String linefeed = System.getProperty("line.separator", "\r\n");
052:
053: System.out
054: .println("$Id: InsertMeta.java 50 2007-05-19 00:48:32Z gmehta $"
055: + linefeed
056: + "VDS version "
057: + Version.instance().toString() + linefeed);
058:
059: System.out.println("Usage: " + this .m_application
060: + " [general] [-n ns] [-i id] [-v vs] [-a arg] [mdf]"
061: + linefeed + "Or : " + this .m_application
062: + " [general] [-f lfn] [metadata_file]");
063:
064: System.out
065: .println(linefeed
066: + "General options: "
067: + linefeed
068: + " -V|--version print version information and exit."
069: + linefeed
070: + " -d|--dbase db associates the dbname with the database, unused."
071: + linefeed
072: + " --verbose increases the verbosity level."
073: + linefeed
074: + " -t|--type tr|dv limits candidates to either TR or DV, default is both."
075: + linefeed
076: + linefeed
077: + "Option group 1: Arguments dealing with VDL definitions "
078: + linefeed
079: + " -n|--vdlns ns limits candidates to definition namespace matches."
080: + linefeed
081: + " -i|--vdlid id limits candidates to definition name matches."
082: + linefeed
083: + " -v|--vdlvs vs limits candidates to definition version matches."
084: + linefeed
085: + " -a|--arg arg limits to formal arguments, requires -t tr."
086: + linefeed
087: + linefeed
088: + "Option group 2: Arguments dealing with VDL logical filenames"
089: + linefeed
090: + " -f|--file lfn limits candidates to logical filename matches."
091: + linefeed
092: + linefeed
093: + "Option groups 1 and 2 are mutually exclusive. The metadata file is a texual"
094: + linefeed
095: + "file with at least three columns, the key, the type and the value(s)."
096: + linefeed);
097: }
098:
099: /**
100: * Creates a set of options.
101: * @return the assembled long option list
102: */
103: protected LongOpt[] generateValidOptions() {
104: LongOpt[] lo = new LongOpt[17];
105:
106: lo[0] = new LongOpt("dbase", LongOpt.REQUIRED_ARGUMENT, null,
107: 'd');
108: lo[1] = new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V');
109: lo[2] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
110: lo[3] = new LongOpt("verbose", LongOpt.NO_ARGUMENT, null, 1);
111:
112: lo[4] = new LongOpt("vdlns", LongOpt.REQUIRED_ARGUMENT, null,
113: 'n');
114: lo[5] = new LongOpt("namespace", LongOpt.REQUIRED_ARGUMENT,
115: null, 'n');
116: lo[6] = new LongOpt("ns", LongOpt.REQUIRED_ARGUMENT, null, 'n');
117:
118: lo[7] = new LongOpt("vdlid", LongOpt.REQUIRED_ARGUMENT, null,
119: 'i');
120: lo[8] = new LongOpt("name", LongOpt.REQUIRED_ARGUMENT, null,
121: 'i');
122: lo[9] = new LongOpt("identifier", LongOpt.REQUIRED_ARGUMENT,
123: null, 'i');
124: lo[10] = new LongOpt("id", LongOpt.REQUIRED_ARGUMENT, null, 'i');
125:
126: lo[11] = new LongOpt("vdlvs", LongOpt.REQUIRED_ARGUMENT, null,
127: 'v');
128: lo[12] = new LongOpt("vs", LongOpt.REQUIRED_ARGUMENT, null, 'v');
129:
130: lo[13] = new LongOpt("arg", LongOpt.REQUIRED_ARGUMENT, null,
131: 'a');
132: lo[14] = new LongOpt("args", LongOpt.REQUIRED_ARGUMENT, null,
133: 'a');
134: lo[15] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null,
135: 't');
136:
137: lo[16] = new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null,
138: 'f');
139:
140: return lo;
141: }
142:
143: /**
144: * Inserts metadata for TR, DV, LFN.
145: */
146: public static void main(String[] args) {
147: int result = 0;
148:
149: try {
150: InsertMeta me = new InsertMeta("insertmeta");
151:
152: // no arguments -- yikes
153: if (args.length == 0) {
154: me.showUsage();
155: return;
156: }
157:
158: // obtain commandline options first -- we may need the database stuff
159: Getopt opts = new Getopt(me.m_application, args,
160: "hd:t:n:i:v:a:f:V", me.generateValidOptions());
161:
162: opts.setOpterr(false);
163: String secondary = null;
164: String primary = new String();
165: String type = null;
166: String vdlns = null;
167: String vdlid = null;
168: String vdlvs = null;
169: String lfn = null;
170: String arg = null;
171:
172: int option = 0;
173: while ((option = opts.getopt()) != -1) {
174: switch (option) {
175: case 1:
176: me.increaseVerbosity();
177: break;
178:
179: case 'V':
180: System.out
181: .println("$Id: InsertMeta.java 50 2007-05-19 00:48:32Z gmehta $");
182: System.out.println("VDS version "
183: + Version.instance().toString());
184: return;
185:
186: case 'a':
187: arg = opts.getOptarg();
188: break;
189:
190: case 'd':
191: // currently inactive option
192: opts.getOptarg();
193: break;
194:
195: case 'f':
196: lfn = opts.getOptarg();
197: break;
198:
199: case 'i':
200: vdlid = opts.getOptarg();
201: break;
202:
203: case 'n':
204: vdlns = opts.getOptarg();
205: break;
206:
207: case 't':
208: type = opts.getOptarg();
209: break;
210:
211: case 'v':
212: vdlvs = opts.getOptarg();
213: break;
214:
215: case 'h':
216: default:
217: me.showUsage();
218: return;
219: }
220: }
221:
222: boolean condition1 = (lfn != null);
223: boolean condition2 = (vdlns != null || vdlid != null || vdlvs != null);
224: // (a XOR b) <=> (a AND !b) OR (!a AND b)
225: // !(a XOR b) <=> (a OR !b) AND (!a OR b)
226: if ((condition1 || !condition2)
227: && (!condition1 || condition2)) {
228: me.showUsage();
229: throw new RuntimeException(
230: "You must either specify the -n -i -v options, or\n"
231: + "\tuse the -f option!");
232: }
233:
234: int classType = -1;
235: if (condition2) {
236: // metadata for TR or DV?
237: switch (Character.toUpperCase(type.charAt(0))) {
238: case 'D': // DV
239: classType = Annotation.CLASS_DERIVATION;
240: break;
241:
242: case 'T': // TR
243: classType = Annotation.CLASS_TRANSFORMATION;
244: if (arg != null) {
245: classType = Annotation.CLASS_DECLARE;
246: secondary = arg;
247: }
248: break;
249:
250: default:
251: me.showUsage();
252: throw new RuntimeException("invalid argument \""
253: + type + "\" for option t");
254: }
255:
256: // will be used for 'D' and 'T' only
257: primary = Separator.combine(vdlns, vdlid, vdlvs);
258: } else {
259: // must be condition1
260: classType = Annotation.CLASS_FILENAME;
261: primary = lfn;
262: }
263: // postcondition: variable "type" can be recycled now
264:
265: // Connect the database.
266: String schemaName = ChimeraProperties.instance()
267: .getVDCSchemaName();
268: Connect connect = new Connect();
269: DatabaseSchema dbschema = connect
270: .connectDatabase(schemaName);
271:
272: if (!(dbschema instanceof Annotation)) {
273: dbschema.close();
274: throw new RuntimeException(
275: "The database does not support metadata!");
276: } else {
277: Annotation annotation = (Annotation) dbschema;
278:
279: // open metadata file -- or read from stdin
280: String mdfile = (opts.getOptind() < args.length ? args[opts
281: .getOptind()]
282: : null);
283: LineNumberReader lnr = null;
284: if (mdfile == null || mdfile.equals("-")) {
285: System.err
286: .println("# reminder: reading from stdin");
287: lnr = new LineNumberReader(new InputStreamReader(
288: System.in));
289: } else {
290: lnr = new LineNumberReader(new FileReader(mdfile));
291: }
292:
293: // parsing name-value pairs from the file
294: Logging.instance().log("app", 1,
295: "parsing name type value tuple");
296:
297: StringTokenizer st = null;
298: String token, key, line = null;
299: while ((line = lnr.readLine()) != null) {
300: Logging.instance().log("app", 3,
301: lnr.getLineNumber() + ": " + line);
302:
303: st = new StringTokenizer(line, " ", false);
304: int column = -1;
305: key = type = null;
306: StringBuffer value = new StringBuffer(80);
307:
308: while (st.hasMoreTokens()) {
309: token = st.nextToken();
310: column++;
311: switch (column) {
312: case 0: // key
313: key = token;
314: break;
315: case 1: // type
316: type = token;
317: break;
318: case 2: // value
319: value.append(token);
320: break;
321: default: // addon
322: value.append(' ').append(token);
323: break;
324: }
325: }
326:
327: // invalid line
328: if (column < 2) {
329: // FIXME: Warn the user here?
330: continue;
331: }
332:
333: // System.out.println("column=" + column );
334: // System.out.println("key=" + key );
335: // System.out.println("type=" + type );
336: // System.out.println("value=" + value );
337:
338: Tuple tuple = null;
339:
340: if (type.equalsIgnoreCase("int")
341: || type.equalsIgnoreCase("i"))
342: tuple = new TupleInteger(key, Long
343: .parseLong(value.toString()));
344: else if (type.equalsIgnoreCase("float")
345: || type.equalsIgnoreCase("f"))
346: tuple = new TupleFloat(key, Float
347: .parseFloat(value.toString()));
348: else if (type.equalsIgnoreCase("bool")
349: || type.equalsIgnoreCase("boolean")
350: || type.equalsIgnoreCase("b"))
351: tuple = new TupleBoolean(key, Boolean
352: .getBoolean(value.toString()));
353: else if (type.equalsIgnoreCase("string")
354: || type.equalsIgnoreCase("s"))
355: tuple = (Tuple) new TupleString(key, value
356: .toString());
357: else if (type.equalsIgnoreCase("date")
358: || type.equalsIgnoreCase("d"))
359: tuple = (Tuple) new TupleDate(key, 0); // FIXME
360: else {
361: // FIXME: What about this case?
362: System.out
363: .println("ERROR: InsertMeta: invalid type: "
364: + type);
365: }
366:
367: if (tuple != null) {
368: System.out.println("Processing ("
369: + tuple.toString() + ")");
370: annotation.saveAnnotation(primary, secondary,
371: classType, tuple, false);
372: } else {
373: // FIXME: What about this case?
374: System.out
375: .println("ERROR: InsertMeta: Tuple creation failed.");
376: }
377: } // while
378: System.out.println("Metadata loaded successfully!");
379: }
380:
381: // done
382: if (dbschema != null)
383: dbschema.close();
384: } catch (RuntimeException rte) {
385: Logging.instance().log("default", 0,
386: "runtime error: " + rte.getMessage());
387: System.err.println("ERROR: " + rte.getMessage());
388: result = 1;
389:
390: } catch (Exception e) {
391: Logging.instance().log("default", 0,
392: "FATAL: " + e.getMessage());
393: e.printStackTrace();
394: System.err.println("FATAL: " + e.getMessage());
395: result = 2;
396: }
397:
398: if (result != 0)
399: System.exit(result);
400: }
401: }
|