001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.lib.vishnu.client;
028:
029: import java.io.CharArrayReader;
030: import java.io.CharArrayWriter;
031: import java.io.File;
032: import java.io.FileNotFoundException;
033: import java.io.InputStream;
034: import java.io.IOException;
035: import java.io.BufferedOutputStream;
036: import java.io.FileOutputStream;
037: import java.io.OutputStream;
038: import java.io.StringReader;
039: import java.io.StringWriter;
040:
041: import java.util.Date;
042:
043: import org.apache.xerces.dom.DocumentImpl;
044: import org.apache.xerces.parsers.DOMParser;
045: import org.apache.xerces.parsers.SAXParser;
046: import org.apache.xml.serialize.OutputFormat;
047: import org.apache.xml.serialize.XMLSerializer;
048:
049: import org.w3c.dom.Attr;
050: import org.w3c.dom.Document;
051: import org.w3c.dom.Element;
052: import org.w3c.dom.Node;
053: import org.w3c.dom.NodeList;
054: import org.w3c.dom.NamedNodeMap;
055: import org.w3c.dom.Text;
056:
057: import org.xml.sax.InputSource;
058: import org.xml.sax.SAXException;
059:
060: import org.cougaar.util.ConfigFinder;
061: import org.cougaar.util.log.Logger;
062:
063: import org.cougaar.lib.param.ParamMap;
064:
065: /** A collection of helper methods for manipulating DOM documents. */
066: public class VishnuDomUtil {
067: public VishnuDomUtil(ParamMap myParamTable, String name,
068: ConfigFinder configFinder, Logger logger) {
069: this .myParamTable = myParamTable;
070: this .name = name;
071: this .configFinder = configFinder;
072: this .logger = logger;
073: }
074:
075: protected ParamMap getMyParams() {
076: return myParamTable;
077: }
078:
079: /** sets showTiming parameter */
080: protected void localSetup() {
081: try {
082: showTiming = getMyParams().getBooleanParam("showTiming");
083: } catch (Exception e) {
084: showTiming = false;
085: }
086: }
087:
088: /**
089: * Makes a human-readable String representation of a dom document <p>
090: *
091: * Uses XMLSerializer to do its work.
092: *
093: * @see org.apache.xml.serialize.XMLSerializer
094: * @param doc the document to translate into a String
095: * @return String readable document equivalent
096: */
097: protected String getDocAsString(Document doc) {
098: StringWriter sw = new StringWriter();
099:
100: OutputFormat of = new OutputFormat(doc,
101: OutputFormat.Defaults.Encoding, true);
102: of.setLineWidth(150);
103: XMLSerializer serializer = new XMLSerializer(sw, of);
104: try {
105: Date start = new Date();
106: serializer.serialize(doc);
107: if (showTiming)
108: reportTime(" - got doc as string in ", start);
109: } catch (IOException ioe) {
110: logger.error("Exception " + ioe, ioe);
111: }
112:
113: return sw.toString();
114: }
115:
116: /** write document to a CharArrayWriter stream using XMLSerializer */
117: protected CharArrayWriter getDocAsArray(Document doc) {
118: CharArrayWriter sw = new CharArrayWriter();
119:
120: OutputFormat of = new OutputFormat(doc);
121: of.setPreserveSpace(false);
122:
123: XMLSerializer serializer = new XMLSerializer(sw, of);
124: try {
125: serializer.serialize(doc);
126: } catch (IOException ioe) {
127: logger.error("Exception " + ioe, ioe);
128: }
129:
130: return sw;
131: }
132:
133: /**
134: * appends the document at filename onto originalDoc.
135: *
136: * @param originalDoc - doc to append the filename doc to
137: * @param filename - name of the document to append
138: */
139: protected void appendDoc(Document originalDoc, String filename) {
140: Element originalRoot = originalDoc.getDocumentElement();
141: appendDoc(originalDoc, originalRoot, filename);
142: }
143:
144: /**
145: * appends the document at filename onto originalDoc.
146: *
147: * @param originalDoc - doc to append the filename doc to
148: * @param filename - name of the document to append
149: */
150: protected void appendDoc(Document originalDoc,
151: Element originalAppendLoc, String filename) {
152: try {
153: DOMParser parser = new DOMParser();
154: InputStream inputStream = configFinder.open(filename);
155: parser.parse(new InputSource(inputStream));
156: Document appendDoc = parser.getDocument();
157:
158: Element appendDocRoot = appendDoc.getDocumentElement();
159: merge(originalAppendLoc, appendDocRoot);
160:
161: } catch (SAXException sax) {
162: logger.error(name + ".appendDoc - Got sax exception:\n"
163: + sax, sax);
164: } catch (IOException ioe) {
165: logger.error("Could not open file : \n" + ioe, ioe);
166: }
167: }
168:
169: /**
170: * appends the document at filename onto originalDoc.
171: *
172: * @param originalDoc - doc to append the filename doc to
173: * @param filename - name of the document to append
174: */
175: protected void appendChildrenToDoc(Document originalDoc,
176: Element originalAppendLoc, String filename) {
177: try {
178: DOMParser parser = new DOMParser();
179: InputStream inputStream = configFinder.open(filename);
180: parser.parse(new InputSource(inputStream));
181: Document appendDoc = parser.getDocument();
182:
183: Element appendDocRoot = appendDoc.getDocumentElement();
184:
185: if (appendDocRoot.getTagName().equals("GLOBAL_DATA_LIST")) {
186:
187: NodeList nlist = appendDocRoot.getChildNodes();
188:
189: for (int i = 0; i < nlist.getLength(); i++) {
190: Node rootChild = nlist.item(i);
191: merge(originalAppendLoc, rootChild);
192: }
193: } else
194: merge(originalAppendLoc, appendDoc.getDocumentElement());
195:
196: } catch (SAXException sax) {
197: logger.error(name + ".appendDoc - Got sax exception:\n"
198: + sax, sax);
199: } catch (IOException ioe) {
200: logger.error("Could not open file : \n" + ioe, ioe);
201: }
202: }
203:
204: /**
205: * Takes two nodes of xml documents and makes the rootToAdd
206: * node as a child of the placeToAdd node.
207: *
208: * On the first call, these two nodes are the roots of two
209: * separate xml documents.
210: *
211: * It recurses down the tree to be added.
212: *
213: * Note that naively taking the root to be added and
214: * adding it directly by doing appendChild doesn't work,
215: * since all DOM Nodes have an "owner document," and all
216: * nodes in a tree must have the same owner. Since the
217: * rootToAdd node comes from a different document, you'll get
218: * a "Wrong Document Err" when you try to do this.
219: *
220: * So you have to create copies with the target document's
221: * createElement method and add those.
222: *
223: * BOZO : probably better way to do this!
224: * @param placeToAdd - the root of the destination document
225: * @param rootToAdd - the root of the document to merge into the first
226: * doc
227: *
228: */
229: protected void merge(Node placeToAdd, Node rootToAdd) {
230: Document targetDoc = placeToAdd.getOwnerDocument();
231:
232: // clone the node to be added
233:
234: if (rootToAdd.getNodeType() == Node.ELEMENT_NODE) {
235: Node clonedNode = createClone(rootToAdd, targetDoc);
236:
237: placeToAdd.appendChild(clonedNode);
238:
239: NodeList nlist = rootToAdd.getChildNodes();
240: int nlength = nlist.getLength();
241:
242: for (int i = 0; i < nlength; i++) {
243: Node child = nlist.item(i);
244: merge(clonedNode, child);
245: }
246: } else if (rootToAdd.getNodeType() == Node.TEXT_NODE) {
247: String data = rootToAdd.getNodeValue().trim();
248: if (data.length() > 0) {
249: Text textNode = targetDoc.createTextNode(data);
250: placeToAdd.appendChild(textNode);
251: }
252: }
253: }
254:
255: /**
256: * Clone a node (only its attributes)
257: *
258: * @param toClone - the node to copy
259: * @param doc - is the factory for new nodes
260: * @return the clone
261: */
262: protected Node createClone(Node toClone, Document doc) {
263: Element clonedNode = doc.createElement(toClone.getNodeName());
264:
265: // clone the attributes
266: NamedNodeMap attrs = toClone.getAttributes();
267: for (int i = 0; i < attrs.getLength(); i++) {
268: Attr attrNode = (Attr) attrs.item(i);
269: clonedNode.setAttribute(attrNode.getName(), attrNode
270: .getValue());
271: }
272:
273: return clonedNode;
274: }
275:
276: /** write document to an output stream using XMLSerializer */
277: protected void writeDocToStream(Document doc, OutputStream os) {
278: OutputFormat of = new OutputFormat(doc, "UTF-8", true);
279: of.setLineWidth(150);
280:
281: XMLSerializer serializer = new XMLSerializer(os, of);
282:
283: try {
284: serializer.serialize(doc);
285: } catch (IOException ioe) {
286: logger.error("Exception " + ioe, ioe);
287: }
288: }
289:
290: /**
291: * Prints out time since <code>start</code> with prefix <code>prefix</code>
292: * @param start since when
293: * @param prefix meaning of time difference
294: */
295: public void reportTime(String prefix, Date start) {
296: Runtime rt = Runtime.getRuntime();
297: Date end = new Date();
298: long diff = end.getTime() - start.getTime();
299: long min = diff / 60000l;
300: long sec = (diff - (min * 60000l)) / 1000l;
301: long millis = diff - (min * 60000l) - (sec * 1000l);
302: // if (min < 1l && sec < 1l && millis < 10l) return;
303: String msg = name + prefix + min + ":"
304: + ((sec < 10) ? "0" : "") + sec + ":"
305: + ((millis < 10) ? "00" : ((millis < 100) ? "0" : ""))
306: + millis + " (Wall clock)" + " free "
307: + (rt.freeMemory() / (1024 * 1024)) + "M" + " total "
308: + (rt.totalMemory() / (1024 * 1024)) + "M";
309:
310: logger.info(msg);
311:
312: System.out.println(msg);
313: }
314:
315: protected ParamMap myParamTable;
316:
317: boolean showTiming;
318: String name;
319: ConfigFinder configFinder;
320: protected Logger logger;
321: }
|