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.euryale;
016:
017: import org.griphyn.vdl.dax.*;
018: import org.griphyn.vdl.classes.LFN;
019: import org.griphyn.vdl.toolkit.Toolkit;
020: import org.griphyn.vdl.util.Logging;
021: import org.griphyn.vdl.util.VDLType;
022:
023: import org.xml.sax.*;
024: import org.xml.sax.helpers.DefaultHandler;
025: import javax.xml.parsers.*;
026: import java.io.*;
027: import java.util.Iterator;
028: import java.util.ArrayList;
029: import java.util.List;
030: import java.util.HashMap;
031: import java.util.Map;
032: import java.util.Stack;
033:
034: /**
035: * This class uses the xerces SAX2 parser to validate and parse an DAX
036: * document. This class extends the xerces DefaultHandler so that we
037: * only need to override callbacks of interest.
038: *
039: * @author Kavitha Ranganathan
040: * @author Jens-S. Vöckler
041: * @author Yong Zhao
042: * @version $Revision: 460 $
043: */
044:
045: public class DAXParser extends DefaultHandler {
046: /**
047: * class name of the SAX parser.
048: */
049: private static String vendorParserClass = "org.apache.xerces.parsers.SAXParser";
050:
051: /**
052: * our own instance of the SAX parser.
053: */
054: private XMLReader m_parser;
055:
056: /**
057: * maintain the hierarchy for some debug printing
058: */
059: private int m_depth;
060:
061: /**
062: * collects the information for a section 2 job element.
063: */
064: private Job m_job;
065:
066: /**
067: * collects the leaves for a profile that is part of a job.
068: */
069: private Profile m_profile;
070:
071: /**
072: * maintains the currently viewed section 3 child element.
073: */
074: private String m_child;
075:
076: /**
077: * collects the parents associated with a particular child.
078: */
079: private java.util.List m_parent;
080:
081: /**
082: * maintains the indications which parent element to be used whenever
083: * a filename tag is being encountered.
084: */
085: private int m_tag;
086:
087: // possible values for m_tag
088: static final int TAG_ADAG = 0;
089: static final int TAG_ARGUMENT = 1;
090: static final int TAG_PROFILE = 2;
091: static final int TAG_OTHER = 3;
092:
093: /**
094: * Keep the location within the document
095: */
096: private Locator m_location;
097:
098: /**
099: * A Hashmap to forward resolve namespaces that were encountered
100: * during parsing.
101: */
102: private Map m_forward;
103:
104: /**
105: * A Hashmap to reverse resolve namespaces that were encountered
106: * during parsing.
107: */
108: private Map m_reverse;
109:
110: /**
111: * Obtain our logger once for multiple uses.
112: */
113: private Logging m_log;
114:
115: /**
116: * Maintains the callback class to provide the information to.
117: */
118: private Callback m_callback;
119:
120: /**
121: * Sets a feature while capturing failed features right here.
122: *
123: * @param uri is the feature's URI to modify
124: * @param flag is the new value to set.
125: * @return true, if the feature could be set, false for an exception
126: */
127: private boolean set(String uri, boolean flag) {
128: boolean result = false;
129: try {
130: this .m_parser.setFeature(uri, flag);
131: result = true;
132: } catch (SAXException se) {
133: Logging.instance().log("default", 0,
134: "Could not set parser feature " + se.getMessage());
135: }
136: return result;
137: }
138:
139: /**
140: * The class constructor initializes the Xerces parser, sets the
141: * classes that hold the callback functions, and the features that
142: * enable schema validation.
143: *
144: * @param schemaLocation is any URI pointing to the XML schema definition.
145: */
146: public DAXParser(String schemaLocation) {
147: // member variables
148: this .m_callback = null;
149: this .m_child = null;
150: this .m_parent = null;
151:
152: // parser related members
153: this .m_forward = new HashMap();
154: this .m_reverse = new HashMap();
155: this .m_log = Logging.instance();
156:
157: try {
158: m_parser = (XMLReader) Class.forName(vendorParserClass)
159: .newInstance();
160: m_parser.setContentHandler(this );
161: // m_parser.setErrorHandler(this);
162: m_parser
163: .setErrorHandler(new org.griphyn.cPlanner.parser.XMLErrorHandler());
164:
165: set("http://xml.org/sax/features/validation", true);
166: set("http://apache.org/xml/features/validation/dynamic",
167: true);
168: set("http://apache.org/xml/features/validation/schema",
169: true);
170: // time+memory consuming, see http://xml.apache.org/xerces2-j/features.html
171: // set( "http://apache.org/xml/features/validation/schema-full-checking", true );
172:
173: // Send XML Schema element default values via characters().
174: set(
175: "http://apache.org/xml/features/validation/schema/element-default",
176: true);
177: set(
178: "http://apache.org/xml/features/validation/warn-on-duplicate-attdef",
179: true);
180: // mysteriously, this one fails with recent Xerces
181: // set( "http://apache.org/xml/features/validation/warn-on-undeclared-elemdef", true );
182: set(
183: "http://apache.org/xml/features/warn-on-duplicate-entitydef",
184: true);
185:
186: // set the schema default location.
187: if (schemaLocation != null) {
188: setSchemaLocations(ADAG.SCHEMA_NAMESPACE + ' '
189: + schemaLocation);
190: m_log.log("app", 2, "will use " + schemaLocation);
191: } else {
192: m_log.log("app", 2, "will use document schema hint");
193: }
194: } catch (ClassNotFoundException e) {
195: m_log.log("default", 0,
196: "The SAXParser class was not found: " + e);
197: } catch (InstantiationException e) {
198: m_log.log("default", 0,
199: "The SAXParser class could not be instantiated: "
200: + e);
201: } catch (IllegalAccessException e) {
202: m_log.log("default", 0,
203: "The SAXParser class could not be accessed: " + e);
204: }
205: }
206:
207: /**
208: * Obtains the current instance to be used for callbacks.
209: *
210: * @return the current callback instance object, or null.
211: * @see #setCallback( Callback )
212: */
213: public Callback getCallback() {
214: return this .m_callback;
215: }
216:
217: /**
218: * Sets a new callback object to use for future callbacks.
219: *
220: * @param callback is the new callback object.
221: * @see #getCallback()
222: */
223: public void setCallback(Callback callback) {
224: this .m_callback = callback;
225: }
226:
227: /**
228: * Set the list of external real locations where the XML schema may be found.
229: * Since this list can be determined at run-time through properties etc., we
230: * expect this function to be called between instantiating the parser, and
231: * using the parser.
232: *
233: * @param list is a list of strings representing schema locations. The content
234: * exists in pairs, one of the namespace URI, one of the location URL.
235: */
236: public void setSchemaLocations(String list) {
237: // schema location handling
238: try {
239: m_parser
240: .setProperty(
241: "http://apache.org/xml/properties/schema/external-schemaLocation",
242: list);
243: } catch (SAXException se) {
244: m_log.log("default", 0, "The SAXParser reported an error: "
245: + se);
246: }
247: }
248:
249: /**
250: * This function parses a DAX source (could be a document, a stream,
251: * etc.), and creates java class instances that correspond to the DAX.
252: * These will provided to the callback functions instead of being
253: * collected here in memory.
254: *
255: * @param daxURI is the URI for the DAX source.
256: * @return true for valid parsing, false if an error occurred.
257: */
258: public boolean parse(String daxURI) {
259: boolean result = false;
260:
261: if (m_callback == null) {
262: m_log.log("default", 0,
263: "Error: Programmer forgot to provide a callback");
264: return result;
265: }
266:
267: try {
268: InputSource inputSource = new InputSource(daxURI);
269: m_parser.parse(inputSource);
270: result = true;
271: } catch (SAXException e) {
272: m_log.log("default", 0, "SAX Error: " + e);
273: } catch (IOException e) {
274: m_log.log("default", 0, "IO Error: " + e);
275: }
276:
277: return result;
278: }
279:
280: /**
281: * This function parses a DAX source (could be a document, a stream,
282: * etc.), and creates java class instances that correspond to the DAX.
283: * These will provided to the callback functions instead of being
284: * collected here in memory.
285: *
286: * @param stream is an input stream for the DAX source.
287: * @return true for valid parsing, false if an error occurred.
288: */
289: public boolean parse(InputStream stream) {
290: boolean result = false;
291:
292: if (m_callback == null) {
293: m_log.log("default", 0,
294: "Error: Programmer forgot to provide a callback");
295: return result;
296: }
297:
298: try {
299: InputSource inputSource = new InputSource(stream);
300: m_parser.parse(inputSource);
301: result = true;
302: } catch (SAXException e) {
303: m_log.log("default", 0, "SAX Error: " + e);
304: } catch (IOException e) {
305: m_log.log("default", 0, "IO Error: " + e);
306: }
307:
308: return result;
309: }
310:
311: //
312: // here starts the implementation to the Interface
313: //
314:
315: /**
316: * Obtains the document locator from the parser. The document location
317: * can be used to print debug information, i.e the current location
318: * (line, column) in the document.
319: *
320: * @param locator is the externally set current position
321: */
322: public void setDocumentLocator(Locator locator) {
323: this .m_location = locator;
324: }
325:
326: /**
327: * This method specifies what to do when the parser is at the beginning
328: * of the document. In this case, we simply print a message for debugging.
329: */
330: public void startDocument() {
331: m_depth = 0;
332: m_log.log("parser", 1, "*** start of document ***");
333: }
334:
335: /**
336: * The parser comes to the end of the document.
337: */
338: public void endDocument() {
339: m_log.log("parser", 1, "*** end of document ***");
340: }
341:
342: /**
343: * There is a prefix or namespace defined, put the prefix and its URI
344: * in the HashMap. We can get the URI when the prefix is used here after.
345: *
346: * @param prefix the Namespace prefix being declared.
347: * @param uri the Namespace URI the prefix is mapped to.
348: */
349: public void startPrefixMapping(java.lang.String prefix,
350: java.lang.String uri) throws SAXException {
351: String p = prefix == null ? null : new String(prefix);
352: String u = uri == null ? null : new String(uri);
353: m_log.log("parser", 2, "adding \"" + p + "\" <=> " + u);
354:
355: if (!this .m_forward.containsKey(p))
356: this .m_forward.put(p, new Stack());
357: ((Stack) this .m_forward.get(p)).push(u);
358:
359: if (!this .m_reverse.containsKey(u))
360: this .m_reverse.put(u, new Stack());
361: ((Stack) this .m_reverse.get(u)).push(p);
362: }
363:
364: /**
365: * Out of the reach of the prefix, remove it from the HashMap.
366: *
367: * @param prefix is the prefix that was being mapped previously.
368: */
369: public void endPrefixMapping(java.lang.String prefix)
370: throws SAXException {
371: String u = (String) ((Stack) this .m_forward.get(prefix)).pop();
372: String p = (String) ((Stack) this .m_reverse.get(u)).pop();
373: m_log.log("parser", 2, "removed \"" + p + "\" <=> " + u);
374: }
375:
376: /**
377: * Helper function to map prefixes correctly onto the elements.
378: *
379: * @param uri is the parser-returned URI that needs translation.
380: * @return the correct prefix for the URI
381: */
382: private String map(String uri) {
383: if (uri == null || uri.length() == 0)
384: return "";
385: Stack stack = (Stack) this .m_reverse.get(uri);
386: String result = stack == null ? null : (String) stack.peek();
387: if (result == null || result.length() == 0)
388: return "";
389: else
390: return result + ':';
391: }
392:
393: /**
394: * This method defines the action to take when the parser begins to parse
395: * an element.
396: *
397: * @param namespaceURI is the URI of the namespace for the element
398: * @param localName is the element name without namespace
399: * @param qName is the element name as it appears in the docment
400: * @param atts has the names and values of all the attributes
401: */
402: public void startElement(java.lang.String namespaceURI,
403: java.lang.String localName, java.lang.String qName,
404: Attributes atts) throws SAXException {
405:
406: m_log.log("parser", 3, "<" + map(namespaceURI) + localName
407: + "> at " + m_location.getLineNumber() + ":"
408: + m_location.getColumnNumber());
409:
410: // yup, one more element level
411: m_depth++;
412:
413: java.util.List names = new java.util.ArrayList();
414: java.util.List values = new java.util.ArrayList();
415: for (int i = 0; i < atts.getLength(); ++i) {
416: String name = new String(atts.getLocalName(i));
417: String value = new String(atts.getValue(i));
418:
419: m_log.log("parser", 2, "attribute " + map(atts.getURI(i))
420: + name + "=\"" + value + "\"");
421: names.add(name);
422: values.add(value);
423: }
424:
425: createElementObject(localName, names, values);
426: }
427:
428: /**
429: * The parser is at the end of an element. Each successfully and
430: * completely parsed Definition will trigger a callback to the
431: * registered DefinitionHandler.
432: *
433: * @param namespaceURI is the URI of the namespace for the element
434: * @param localName is the element name without namespace
435: * @param qName is the element name as it appears in the docment
436: */
437: public void endElement(java.lang.String namespaceURI,
438: java.lang.String localName, java.lang.String qName)
439: throws SAXException {
440: // that's it for this level
441: m_depth--;
442: m_log.log("parser", 3, "</" + map(namespaceURI) + localName
443: + "> at " + m_location.getLineNumber() + ":"
444: + m_location.getColumnNumber());
445:
446: setElementRelation(localName);
447: }
448:
449: /**
450: * This method is the callback function for characters in an element.
451: * The element should be mixed-content.
452: *
453: * @param ch are the characters from the XML document
454: * @param start is the start position into the array
455: * @param length is the amount of valid data in the array
456: */
457: public void characters(char[] ch, int start, int length)
458: throws SAXException {
459: String message = new String(ch, start, length);
460: if (message.length() > 0) {
461: if (message.trim().length() == 0)
462: m_log.log("parser", 3, "Characters: whitespace x "
463: + length);
464: else
465: m_log.log("parser", 3, "Characters: \"" + message
466: + "\"");
467: elementCharacters(message);
468: }
469: }
470:
471: /**
472: * Currently, ignorable whitespace will be ignored.
473: *
474: * @param ch are the characters from the XML document
475: * @param start is the start position into the array
476: * @param length is the amount of valid data in the array
477: */
478: public void ignorableWhitespace(char[] ch, int start, int length)
479: throws SAXException {
480: m_log.log("parser", 3, "Ignoring " + length + " whitespaces");
481: }
482:
483: /**
484: * Receive a processing instruction. Currently, we are just printing
485: * a debug message that we received a PI.
486: *
487: * @param target the processing instruction target
488: * @param data the processing instruction data, or null if none was supplied.
489: * The data does not include any whitespace separating it from the target.
490: */
491: public void processingInstruction(java.lang.String target,
492: java.lang.String data) throws SAXException {
493: m_log.log("parser", 2, "processing instruction " + target
494: + "=\"" + data + "\" was skipped!");
495: }
496:
497: /**
498: * Receive a notification that an entity was skipped. Currently, we
499: * are just printing a debug message to this fact.
500: *
501: * @param name The name of the skipped entity. If it is a parameter
502: * entity, the name will begin with '%', and if it is the external DTD
503: * subset, it will be the string "[dtd]".
504: */
505: public void skippedEntity(java.lang.String name)
506: throws SAXException {
507: m_log.log("parser", 2, "entity " + name + " was skipped!");
508: }
509:
510: //
511: // =================================================== our own stuff ===
512: //
513:
514: /**
515: * Small helper method to bundle repetitive parameters in a template
516: * for reporting progress.
517: *
518: * @param subject is the name of the XML element that is being scrutinized.
519: * @param name is then name of the element we are working with.
520: * @param value is the attribute value.
521: */
522: private void log(String subject, String name, String value) {
523: if (value == null)
524: value = new String();
525: m_log.log("parser", 3, subject + "." + name + "=\"" + value
526: + "\"");
527: }
528:
529: /**
530: * Small helper method to bundle repetitive complaints in a template
531: * for reporting progress.
532: *
533: * @param subject is the name of the XML element that is being scrutinized.
534: * @param name is then name of the element we are working with.
535: * @param value is the attribute value.
536: */
537: private void complain(String subject, String name, String value) {
538: if (value == null)
539: value = new String();
540: m_log.log("default", 0, "ignoring " + subject + '@' + name
541: + "=\"" + value + '"', true);
542: }
543:
544: /**
545: * This method finds out what is the current element, creates the
546: * java object that corresponds to the element, and sets the member
547: * variables with the values of the attributes of the element.
548: *
549: * @param e is the name of the element
550: * @param names is a list of attribute names, as strings.
551: * @param values is a list of attribute values, to match the key list.
552: */
553: public void createElementObject(String e, java.util.List names,
554: java.util.List values) throws IllegalArgumentException {
555: // invalid length
556: if (e == null || e.length() < 1)
557: throw new IllegalArgumentException("illegal element length");
558:
559: if (e.equals("adag")) {
560: HashMap cbdata = new HashMap();
561: m_tag = TAG_ADAG;
562:
563: for (int i = 0; i < names.size(); ++i) {
564: String name = (String) names.get(i);
565: String value = (String) values.get(i);
566:
567: if (name.equals("name")) {
568: this .log(e, name, value);
569: cbdata.put(name, value);
570: } else if (name.equals("index")) {
571: this .log(e, name, value);
572: cbdata.put(name, value);
573: } else if (name.equals("count")) {
574: this .log(e, name, value);
575: cbdata.put(name, value);
576: } else if (name.equals("version")) {
577: this .log(e, name, value);
578: cbdata.put(name, value);
579: } else if (name.equals("jobCount")) {
580: this .log(e, name, value);
581: cbdata.put(name, value);
582: } else if (name.equals("fileCount")) {
583: this .log(e, name, value);
584: cbdata.put(name, value);
585: } else if (name.equals("childCount")) {
586: this .log(e, name, value);
587: cbdata.put(name, value);
588: } else if (name.equals("schemaLocation")) {
589: cbdata.put(name, value);
590: } else {
591: this .complain(e, name, value);
592: }
593: }
594: m_callback.cb_document(cbdata);
595: return;
596: }
597:
598: if (e.equals("filename") || e.equals("stdin")
599: || e.equals("stdout") || e.equals("stderr")
600: || e.equals("uses")) {
601: Filename fn = new Filename();
602: for (int i = 0; i < names.size(); ++i) {
603: String name = (String) names.get(i);
604: String value = (String) values.get(i);
605:
606: if (name.equals("file")) {
607: this .log(e, name, value);
608: fn.setFilename(value);
609: } else if (name.equals("link")) {
610: this .log(e, name, value);
611: fn.setLink(VDLType.getLinkType(value));
612: } else if (name.equals("optional")) {
613: this .log(e, name, value);
614: fn.setOptional(new Boolean(value).booleanValue());
615: } else if (name.equals("dontRegister")) {
616: this .log(e, name, value);
617: fn.setDontRegister(new Boolean(value)
618: .booleanValue());
619: } else if (name.equals("dontTransfer")) {
620: // parse tri-state
621: if (value.equals("false")) {
622: this .log(e, name, value);
623: fn.setDontTransfer(LFN.XFER_MANDATORY);
624: } else if (value.equals("true")) {
625: this .log(e, name, value);
626: fn.setDontTransfer(LFN.XFER_NOT);
627: } else if (value.equals("optional")) {
628: this .log(e, name, value);
629: fn.setDontTransfer(LFN.XFER_OPTIONAL);
630: } else {
631: this .complain(e, name, value);
632: }
633: } else if (name.equals("isTemporary")) {
634: this .log(e, name, value);
635: boolean temp = (new Boolean(value)).booleanValue();
636: fn.setDontRegister(temp);
637: fn.setDontTransfer(temp ? LFN.XFER_NOT
638: : LFN.XFER_MANDATORY);
639: } else if (name.equals("temporaryHint")) {
640: this .log(e, name, value);
641: fn.setTemporary(value);
642: } else if (name.equals("varname")) {
643: this .log(e, name, value);
644: fn.setVariable(value);
645: } else if (name.equals("type")) {
646: this .log(e, name, value);
647: fn.setType(LFN.typeInt(value));
648: } else {
649: this .complain(e, name, value);
650: }
651: } // for
652:
653: if (e.equals("filename")) {
654: switch (m_tag) {
655: case TAG_ADAG:
656: m_callback.cb_filename(fn);
657: break;
658: case TAG_PROFILE:
659: m_profile.addLeaf(fn);
660: break;
661: case TAG_ARGUMENT:
662: m_job.addArgument(fn);
663: }
664: } else {
665: m_tag = TAG_OTHER;
666:
667: if (e.equals("stdin"))
668: m_job.setStdin(fn);
669: else if (e.equals("stdout"))
670: m_job.setStdout(fn);
671: else if (e.equals("stderr"))
672: m_job.setStderr(fn);
673: else if (e.equals("uses"))
674: m_job.addUses(fn);
675: }
676: return;
677: }
678:
679: if (e.equals("job")) {
680: m_job = new Job();
681: for (int i = 0; i < names.size(); ++i) {
682: String name = (String) names.get(i);
683: String value = (String) values.get(i);
684:
685: if (name.equals("name")) {
686: this .log(e, name, value);
687: m_job.setName(value);
688: } else if (name.equals("level")) {
689: this .log(e, name, value);
690: m_job.setLevel(Integer.parseInt(value));
691: } else if (name.equals("namespace")) {
692: this .log(e, name, value);
693: m_job.setNamespace(value);
694: } else if (name.equals("version")) {
695: this .log(e, name, value);
696: m_job.setVersion(value);
697: } else if (name.equals("compound")) {
698: this .log(e, name, value);
699: m_job.setChain(value);
700: } else if (name.equals("id")) {
701: this .log(e, name, value);
702: m_job.setID(value);
703: } else if (name.equals("dv-namespace")) {
704: this .log(e, name, value);
705: m_job.setDVNamespace(value);
706: } else if (name.equals("dv-name")) {
707: this .log(e, name, value);
708: m_job.setDVName(value);
709: } else if (name.equals("dv-version")) {
710: this .log(e, name, value);
711: m_job.setDVVersion(value);
712: } else {
713: this .complain(e, name, value);
714: }
715: }
716: return;
717: }
718:
719: if (e.equals("child")) {
720: this .m_parent = new ArrayList();
721: for (int i = 0; i < names.size(); ++i) {
722: String name = (String) names.get(i);
723: String value = (String) values.get(i);
724:
725: if (name.equals("ref")) {
726: this .log(e, name, value);
727: m_child = value;
728: } else {
729: this .complain(e, name, value);
730: }
731: }
732: return;
733: }
734:
735: if (e.equals("parent")) {
736: String parent = null;
737: for (int i = 0; i < names.size(); ++i) {
738: String name = (String) names.get(i);
739: String value = (String) values.get(i);
740:
741: if (name.equals("ref")) {
742: this .log(e, name, value);
743: parent = value;
744: } else {
745: this .complain(e, name, value);
746: }
747: }
748: if (parent != null)
749: m_parent.add(parent);
750: return;
751: }
752:
753: if (e.equals("argument")) {
754: m_tag = TAG_ARGUMENT;
755: return;
756: }
757:
758: if (e.equals("profile")) {
759: m_profile = new Profile();
760: m_tag = TAG_PROFILE;
761: for (int i = 0; i < names.size(); ++i) {
762: String name = (String) names.get(i);
763: String value = (String) values.get(i);
764:
765: if (name.equals("namespace")) {
766: this .log(e, name, value);
767: m_profile.setNamespace(value);
768: } else if (name.equals("key")) {
769: this .log(e, name, value);
770: m_profile.setKey(value);
771: } else if (name.equals("origin")) {
772: this .log(e, name, value);
773: m_profile.setOrigin(value);
774: } else {
775: this .complain(e, name, value);
776: }
777: }
778: return;
779: }
780:
781: // FIXME: shouldn't this be an exception?
782: m_log.log("filler", 0, "Error: No rules defined for element "
783: + e);
784: }
785:
786: /**
787: * This method sets the relations between the current java object
788: * and its parent object according to the element hierarchy.
789: * Usually it involves adding the object to the parent's child object
790: * list.
791: */
792: public void setElementRelation(String elementName) {
793: switch (elementName.charAt(0)) {
794: case 'a':
795: if (elementName.equals("argument")) {
796: m_tag = TAG_OTHER;
797: } else if (elementName.equals("adag")) {
798: m_callback.cb_done();
799: }
800: break;
801:
802: case 'c':
803: if (elementName.equals("child")) {
804: m_callback.cb_parents(m_child, m_parent);
805: }
806: break;
807:
808: case 'j':
809: if (elementName.equals("job")) {
810: m_tag = TAG_ADAG;
811: m_callback.cb_job(m_job);
812: m_log.log("filler", 3, "Adding job " + m_job.getID());
813: }
814: break;
815:
816: case 'p':
817: if (elementName.equals("profile")) {
818: m_job.addProfile(m_profile);
819: m_tag = TAG_OTHER;
820: }
821: break;
822:
823: default:
824: // m_log.log( "filler", 0, "Cannot guess parent for " + elementName );
825: break;
826: }
827: }
828:
829: /**
830: * This method sets the content of the java object corresponding to
831: * the element "text", which has mixed content.
832: * @see org.griphyn.vdl.classes.Text
833: */
834: public void elementCharacters(String elementChars) {
835: PseudoText text = new PseudoText(elementChars);
836:
837: switch (m_tag) {
838: case TAG_PROFILE:
839: m_profile.addLeaf(text);
840: this .log("profile", "text", elementChars);
841: break;
842: case TAG_ARGUMENT:
843: m_job.addArgument(text);
844: this .log("argument", "text", elementChars);
845: }
846: }
847: }
|