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.invocation;
016:
017: import java.util.*;
018: import java.io.Writer;
019: import java.io.IOException;
020:
021: /**
022: * This class maintains the application that was run, and the
023: * arguments to the commandline that were actually passed on to
024: * the application.
025: *
026: * @author Jens-S. Vöckler
027: * @author Yong Zhao
028: * @version $Revision: 50 $
029: * @see Job
030: */
031: public class ArgVector extends Arguments {
032: /**
033: * This is the (new) alternative explicit argument vector. The reason
034: * for using a map is that I cannot random access an ArrayList.
035: */
036: private Map m_argv;
037:
038: /**
039: * Default c'tor: Construct a hollow shell and allow further
040: * information to be added later.
041: */
042: public ArgVector() {
043: super ();
044: m_argv = new TreeMap();
045: }
046:
047: /**
048: * Constructs an applications without arguments.
049: * @param executable is the name of the application.
050: */
051: public ArgVector(String executable) {
052: super (executable);
053: m_argv = new TreeMap();
054: }
055:
056: /**
057: * Returns the full argument vector as one single string.
058: *
059: * @return a single string joining all arguments with a single space.
060: * @see #setValue(int,String)
061: */
062: public String getValue() {
063: StringBuffer result = new StringBuffer(128);
064:
065: if (m_argv.size() > 0) {
066: boolean flag = false;
067: for (Iterator i = m_argv.keySet().iterator(); i.hasNext();) {
068: Integer key = (Integer) i.next();
069: String value = (String) m_argv.get(key);
070:
071: if (value != null) {
072: if (flag)
073: result.append(' ');
074: else
075: flag = true;
076: // FIXME: Use single quotes around value, if it contains ws.
077: // FIXME: escape contained apostrophes and esc characters.
078: result.append(value);
079: }
080: }
081: }
082:
083: return result.toString();
084: }
085:
086: /**
087: * Sets the argument vector at the specified location.
088: * @param position is the position at which to set the entry.
089: * @param entry is the argument vector position
090: * Setting <code>null</code> is a noop.
091: */
092: public void setValue(int position, String entry) {
093: if (position >= 0) {
094: if (entry == null) {
095: m_argv.put(new Integer(position), new String());
096: } else {
097: m_argv.put(new Integer(position), entry);
098: }
099: }
100: }
101:
102: /**
103: * Dumps the state of the current element as XML output. This function
104: * can return the necessary data more efficiently, thus overwriting
105: * the inherited method.
106: *
107: * @param indent is a <code>String</code> of spaces used for pretty
108: * printing. The initial amount of spaces should be an empty string.
109: * The parameter is used internally for the recursive traversal.
110: *
111: * @return a String which contains the state of the current class and
112: * its siblings using XML. Note that these strings might become large.
113: */
114: public String toXML(String indent) {
115: StringBuffer result = new StringBuffer(64);
116: String newline = System.getProperty("line.separator", "\r\n");
117:
118: result.append("<argument-vector");
119: if (m_executable != null) {
120: result.append(" executable=\"");
121: result.append(quote(m_executable, true));
122: result.append('"');
123: }
124:
125: if (m_argv.size() == 0) {
126: // no content
127: result.append("/>");
128: } else {
129: // yes, content
130: String newindent = indent == null ? null : indent + " ";
131:
132: result.append('>');
133: if (indent != null)
134: result.append(newline);
135:
136: for (Iterator i = m_argv.keySet().iterator(); i.hasNext();) {
137: Integer key = (Integer) i.next();
138: String entry = (String) m_argv.get(key);
139: if (entry != null) {
140: if (newindent != null)
141: result.append(newindent);
142: result.append("<arg nr=\"").append(key).append(
143: "\">");
144: result.append(quote(entry, false));
145: result.append("</arg>");
146: if (newindent != null)
147: result.append(newline);
148: }
149: }
150: result.append("</argument-vector>");
151: }
152:
153: return result.toString();
154: }
155:
156: /**
157: * Dump the state of the current element as XML output. This function
158: * traverses all sibling classes as necessary, and converts the data
159: * into pretty-printed XML output. The stream interface should be able
160: * to handle large output efficiently.
161: *
162: * @param stream is a stream opened and ready for writing. This can also
163: * be a string stream for efficient output.
164: * @param indent is a <code>String</code> of spaces used for pretty
165: * printing. The initial amount of spaces should be an empty string.
166: * The parameter is used internally for the recursive traversal.
167: * If a <code>null</code> value is specified, no indentation nor
168: * linefeeds will be generated.
169: * @param namespace is the XML schema namespace prefix. If neither
170: * empty nor null, each element will be prefixed with this prefix,
171: * and the root element will map the XML namespace.
172: * @exception IOException if something fishy happens to the stream.
173: */
174: public void toXML(Writer stream, String indent, String namespace)
175: throws IOException {
176: String newline = System.getProperty("line.separator", "\r\n");
177: String tag = (namespace != null && namespace.length() > 0) ? namespace
178: + ":argument-vector"
179: : "argument-vector";
180:
181: // open tag
182: if (indent != null && indent.length() > 0)
183: stream.write(indent);
184: stream.write('<');
185: stream.write(tag);
186: if (m_executable != null)
187: writeAttribute(stream, " executable=\"", m_executable);
188:
189: if (m_argv.size() > 0) {
190: // yes, new content
191: String newindent = indent == null ? null : indent + " ";
192: String newtag = (namespace != null && namespace.length() > 0) ? namespace
193: + ":arg"
194: : "arg";
195:
196: stream.write('>');
197: if (indent != null)
198: stream.write(newline);
199: for (Iterator i = m_argv.keySet().iterator(); i.hasNext();) {
200: String key = (String) i.next();
201: String entry = (String) m_argv.get(key);
202: if (entry != null) {
203: if (newindent != null && newindent.length() > 0)
204: stream.write(newindent);
205: stream.write('<');
206: stream.write(newtag);
207: writeAttribute(stream, " nr=\"", key);
208: stream.write('>');
209: stream.write(quote(entry, false));
210: stream.write("</");
211: stream.write(newtag);
212: stream.write('>');
213: if (indent != null)
214: stream.write(newline);
215: }
216: }
217:
218: if (indent != null && indent.length() > 0)
219: stream.write(indent);
220: stream.write("</");
221: stream.write(tag);
222: stream.write('>');
223:
224: } else {
225: // no content
226: stream.write("/>");
227: }
228:
229: if (indent != null)
230: stream.write(newline);
231: }
232: }
|