001: package com.salmonllc.xml;
002:
003: /////////////////////////
004: //$Archive: /SOFIA/SourceCode/com/salmonllc/xml/XMLOptionsParser.java $
005: //$Author: Dan $
006: //$Revision: 12 $
007: //$Modtime: 6/11/03 4:30p $
008: /////////////////////////
009: /**
010: * The XML Options paser is used to parse any XML file specified as options.dtd file.
011: */
012:
013: import java.io.*;
014:
015: import org.w3c.dom.*;
016:
017: public class XMLOptionsParser {
018:
019: /** Default parser name. */
020: private static final String DEFAULT_PARSER_NAME = "com.salmonllc.xml.DOMParser";
021:
022: private static Options _fieldOptions = new Options();
023:
024: /** Default Encoding */
025: private static String PRINTWRITER_ENCODING = "UTF8";
026:
027: private static String MIME2JAVA_ENCODINGS[] = { "Default", "UTF-8",
028: "US-ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3",
029: "ISO-8859-4", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7",
030: "ISO-8859-8", "ISO-8859-9", "ISO-2022-JP", "SHIFT_JIS",
031: "EUC-JP", "GB2312", "BIG5", "EUC-KR", "ISO-2022-KR",
032: "KOI8-R", "EBCDIC-CP-US", "EBCDIC-CP-CA", "EBCDIC-CP-NL",
033: "EBCDIC-CP-DK", "EBCDIC-CP-NO", "EBCDIC-CP-FI",
034: "EBCDIC-CP-SE", "EBCDIC-CP-IT", "EBCDIC-CP-ES",
035: "EBCDIC-CP-GB", "EBCDIC-CP-FR", "EBCDIC-CP-AR1",
036: "EBCDIC-CP-HE", "EBCDIC-CP-CH", "EBCDIC-CP-ROECE",
037: "EBCDIC-CP-YU", "EBCDIC-CP-IS", "EBCDIC-CP-AR2", "UTF-16" };
038:
039: /** Print writer. */
040: protected PrintWriter out;
041:
042: /** Canonical output. */
043: protected boolean canonical;
044:
045: public XMLOptionsParser(String encoding, boolean canonical)
046: throws UnsupportedEncodingException {
047: out = new PrintWriter(new OutputStreamWriter(System.out,
048: encoding));
049: this .canonical = canonical;
050: _fieldOptions = new Options();
051: } // <init>(String,boolean)
052:
053: //
054: // Constructors
055: //
056:
057: /** Default constructor. */
058: public XMLOptionsParser(boolean canonical)
059: throws UnsupportedEncodingException {
060: this (getWriterEncoding(), canonical);
061: }
062:
063: /**
064: * Creation date: (7/20/01 2:03:28 PM)
065: * @return java.lang.String
066: * @param node org.w3c.dom.Node
067: * @param columnName java.lang.String
068: */
069: private String getNodeValue(Node node, String columnName) {
070:
071: Node temp = node.getAttributes().getNamedItem(columnName);
072: if (temp != null)
073: return temp.getNodeValue();
074:
075: return null;
076: }
077:
078: /**
079: * Gets the Options Object for the XML file read
080: * Creation date: (8/1/01 12:22:07 PM)
081: * @return com.salmonllc.xml.Options
082: */
083: public Options getOptions() {
084: return _fieldOptions;
085: }
086:
087: private static String getWriterEncoding() {
088: return (PRINTWRITER_ENCODING);
089: }// getWriterEncoding
090:
091: private static boolean isValidJavaEncoding(String encoding) {
092: for (int i = 0; i < MIME2JAVA_ENCODINGS.length; i++)
093: if (encoding.equals(MIME2JAVA_ENCODINGS[i]))
094: return (true);
095:
096: return (false);
097: }// isValidJavaEncoding
098:
099: //
100: // Main
101: //
102:
103: /** Main program entry point. */
104: public static void main(String argv[]) {
105:
106: // is there anything to do?
107: if (argv.length == 0) {
108: printUsage();
109: System.exit(1);
110: }
111:
112: // vars
113: String parserName = DEFAULT_PARSER_NAME;
114: boolean canonical = false;
115: String encoding = "UTF8"; // default encoding
116:
117: // check parameters
118: for (int i = 0; i < argv.length; i++) {
119: String arg = argv[i];
120:
121: // options
122: if (arg.startsWith("-")) {
123: if (arg.equals("-p")) {
124: if (i == argv.length - 1) {
125: System.err
126: .println("error: missing parser name");
127: System.exit(1);
128: }
129: parserName = argv[++i];
130: continue;
131: }
132:
133: if (arg.equals("-c")) {
134: canonical = true;
135: continue;
136: }
137:
138: if (arg.equals("-h")) {
139: printUsage();
140: System.exit(1);
141: }
142:
143: if (arg.equals("-e")) {
144: if (i == argv.length - 1) {
145: System.err
146: .println("error: missing encoding name");
147: printValidJavaEncoding();
148: System.exit(1);
149: } else {
150: encoding = argv[++i];
151: if (isValidJavaEncoding(encoding))
152: setWriterEncoding(encoding);
153: else {
154: printValidJavaEncoding();
155: System.exit(1);
156: }
157: }
158: continue;
159: }
160:
161: }
162:
163: // print uri
164: System.err.println(arg + ':');
165: parseFile(parserName, arg, canonical, null);
166: System.err.println();
167: }
168:
169: } // main(String[])
170:
171: /** Normalizes the given string. */
172: protected String normalize(String s) {
173: StringBuffer str = new StringBuffer();
174:
175: int len = (s != null) ? s.length() : 0;
176: for (int i = 0; i < len; i++) {
177: char ch = s.charAt(i);
178: switch (ch) {
179: case '<': {
180: str.append("<");
181: break;
182: }
183: case '>': {
184: str.append(">");
185: break;
186: }
187: case '&': {
188: str.append("&");
189: break;
190: }
191: case '"': {
192: str.append(""");
193: break;
194: }
195: case '\r':
196: case '\n': {
197: if (canonical) {
198: str.append("&#");
199: str.append(Integer.toString(ch));
200: str.append(';');
201: break;
202: }
203: // else, default append char
204: }
205: default: {
206: str.append(ch);
207: }
208: }
209: }
210:
211: return (str.toString());
212:
213: } // normalize(String):String
214:
215: /**
216: * This method is used to create the Option object out of the XML file. XML file name
217: * is passed as uri and values object is used to upload options given in XML file.
218: *
219: */
220: public static void parseFile(String uri, Options values) {
221: parseFile(DEFAULT_PARSER_NAME, uri, false, values);
222:
223: } // print(String,String,boolean)
224:
225: /** Prints the resulting document tree. */
226: private static void parseFile(String parserWrapperName, String uri,
227: boolean canonical, Options values) {
228: try {
229:
230: DOMParserWrapper parser = (DOMParserWrapper) Class.forName(
231: parserWrapperName).newInstance();
232: Document document = parser.parse(uri);
233: XMLOptionsParser writer = new XMLOptionsParser(canonical);
234: _fieldOptions = writer.parseNode(document, values);
235: } catch (Exception e) {
236: e.printStackTrace(System.err);
237: }
238:
239: } // print(String,String,boolean)
240:
241: /** Prints the specified node, recursively. */
242: private Options parseNode(Node node, Options values) {
243:
244: // is there anything to do?
245: if (node == null) {
246: return values;
247: }
248:
249: int type = node.getNodeType();
250: switch (type) {
251: // print document
252: case Node.DOCUMENT_NODE:
253: parseNode(((Document) node).getDocumentElement(), values);
254: break;
255: // print element with attributes
256: case Node.ELEMENT_NODE:
257:
258: if (node.getNodeName().equalsIgnoreCase("Options")) {
259: NodeList children = node.getChildNodes();
260: if (children != null) {
261: int len = children.getLength();
262: for (int i = 0; i < len; i++) {
263: Node nodeChild = children.item(i);
264: if (nodeChild.getNodeName().equalsIgnoreCase(
265: "Option")) {
266: values.put(getNodeValue(nodeChild, "key"),
267: getNodeValue(nodeChild, "value"));
268: }
269: }
270: }
271: }
272:
273: // recursive call
274: NodeList children = node.getChildNodes();
275: if (children != null) {
276: int len = children.getLength();
277: for (int i = 0; i < len; i++) {
278: parseNode(children.item(i), values);
279: }
280: }
281:
282: break;
283:
284: }
285:
286: return values;
287: } // parseNode(Node)
288:
289: /** Prints the usage. */
290: private static void printUsage() {
291:
292: System.err
293: .println("usage: java dom.DOMWriter (options) uri ...");
294: System.err.println();
295: System.err.println("options:");
296: System.err
297: .println(" -p name Specify DOM parser wrapper by name.");
298: System.err.println(" Default parser: "
299: + DEFAULT_PARSER_NAME);
300: System.err.println(" -c Canonical XML output.");
301: System.err.println(" -h This help screen.");
302: System.err.println(" -e Output Java Encoding.");
303: System.err.println(" Default encoding: UTF-8");
304:
305: } // printUsage()
306:
307: private static void printValidJavaEncoding() {
308: System.err.println(" ENCODINGS:");
309: System.err.print(" ");
310: for (int i = 0; i < MIME2JAVA_ENCODINGS.length; i++) {
311: System.err.print(MIME2JAVA_ENCODINGS[i] + " ");
312: if ((i % 7) == 0) {
313: System.err.println();
314: System.err.print(" ");
315: }
316: }
317:
318: } // printJavaEncoding()
319:
320: private static void setWriterEncoding(String encoding) {
321: if (encoding.equalsIgnoreCase("DEFAULT"))
322: PRINTWRITER_ENCODING = "UTF8";
323: else if (encoding.equalsIgnoreCase("UTF-16"))
324: PRINTWRITER_ENCODING = "Unicode";
325: //else
326: // PRINTWRITER_ENCODING = MIME2Java.convert( encoding );
327: }// setWriterEncoding
328:
329: /** Returns a sorted list of attributes. */
330: protected Attr[] sortAttributes(NamedNodeMap attrs) {
331:
332: int len = (attrs != null) ? attrs.getLength() : 0;
333: Attr array[] = new Attr[len];
334: for (int i = 0; i < len; i++) {
335: array[i] = (Attr) attrs.item(i);
336: }
337: for (int i = 0; i < len - 1; i++) {
338: String name = array[i].getNodeName();
339: int index = i;
340: for (int j = i + 1; j < len; j++) {
341: String curName = array[j].getNodeName();
342: if (curName.compareTo(name) < 0) {
343: name = curName;
344: index = j;
345: }
346: }
347: if (index != i) {
348: Attr temp = array[i];
349: array[i] = array[index];
350: array[index] = temp;
351: }
352: }
353:
354: return (array);
355:
356: } // sortAttributes(NamedNodeMap):Attr[]
357: }
|