001: /*
002: Copyright (c) 2003, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.extras;
030:
031: import java.io.ByteArrayInputStream;
032: import java.io.ByteArrayOutputStream;
033: import java.io.File;
034: import java.io.FileInputStream;
035: import java.io.FileOutputStream;
036: import java.io.FileReader;
037: import java.io.IOException;
038: import java.io.InputStreamReader;
039: import java.net.URL;
040: import java.net.URLClassLoader;
041:
042: import org.jibx.runtime.*;
043: import org.xmlpull.v1.XmlPullParserException;
044:
045: /**
046: * Test program for the JiBX framework. Works with two or three command line
047: * arguments: mapped-class, in-file, and out-file (optional, only needed if
048: * different from in-file). You can also supply a multiple of three input
049: * arguments, in which case each set of three is processed in turn (in this case
050: * the out-file is required). Unmarshals documents from files using the binding
051: * defined for the mapped class, then marshals them back out using the same
052: * bindings and compares the results. In case of a comparison error the output
053: * file is left as <i>temp.xml</i>.
054: *
055: * @author Dennis M. Sosnoski
056: * @version 1.0
057: */
058: public class TestRoundtrip {
059:
060: protected static boolean runTest(String mname, String bname,
061: String fin, String fout) throws IOException, JiBXException,
062: XmlPullParserException {
063:
064: // look up the mapped class and associated binding factory
065: Class mclas;
066: try {
067: URL[] urls = new URL[] { new File(".").toURL() };
068: ClassLoader parent = Thread.currentThread()
069: .getContextClassLoader();
070: if (parent == null) {
071: parent = TestMultRoundtrip.class.getClassLoader();
072: }
073: ClassLoader loader = new URLClassLoader(urls, parent);
074: Thread.currentThread().setContextClassLoader(loader);
075: mclas = loader.loadClass(mname);
076: } catch (ClassNotFoundException ex) {
077: System.err.println("Class " + mname + " not found");
078: return false;
079: }
080: IBindingFactory bfact;
081: if (bname == null) {
082: bfact = BindingDirectory.getFactory(mclas);
083: } else {
084: bfact = BindingDirectory.getFactory(bname, mclas);
085: }
086:
087: // unmarshal document to construct objects
088: IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
089: Object obj = uctx.unmarshalDocument(new FileInputStream(fin),
090: null);
091: if (!mclas.isInstance(obj)) {
092: System.err.println("Unmarshalled result not expected type");
093: return false;
094: }
095:
096: // marshal root object back out to document in memory
097: IMarshallingContext mctx = bfact.createMarshallingContext();
098: mctx.setIndent(2);
099: ByteArrayOutputStream bos = new ByteArrayOutputStream();
100: mctx.marshalDocument(obj, "UTF-8", null, bos);
101:
102: // compare with output document to be matched
103: InputStreamReader brdr = new InputStreamReader(
104: new ByteArrayInputStream(bos.toByteArray()), "UTF-8");
105: FileReader frdr = new FileReader(fout);
106: DocumentComparator comp = new DocumentComparator(System.err);
107: if (comp.compare(frdr, brdr)) {
108: return true;
109: } else {
110:
111: // save file before returning failure
112: try {
113: FileOutputStream fos = new FileOutputStream("temp.xml");
114: fos.write(bos.toByteArray());
115: fos.close();
116: } catch (IOException ex) {
117: System.err.println("Error writing to temp.xml: "
118: + ex.getMessage());
119: }
120: return false;
121: }
122: }
123:
124: public static void main(String[] args) {
125: if (args.length == 2
126: || (args.length > 0 && args.length % 3 == 0)) {
127:
128: // delete generated output file if present
129: File temp = new File("temp.xml");
130: if (temp.exists()) {
131: temp.delete();
132: }
133:
134: // process input arguments
135: int base = 0;
136: boolean err = false;
137: String fin = null;
138: String fout = null;
139: while (base < args.length) {
140:
141: // run test with one argument set
142: fin = args[base + 1];
143: fout = (args.length < base + 3) ? fin : args[base + 2];
144: try {
145: if (!runTest(args[base], null, fin, fout)) {
146: err = true;
147: }
148: } catch (Exception ex) {
149: ex.printStackTrace();
150: // System.err.println(ex.getMessage());
151: err = true;
152: }
153:
154: // take error exit if difference found
155: if (err) {
156: System.err.println("Error round-tripping class: "
157: + args[base] + "\n with input file " + fin
158: + " and output compared to " + fout);
159: System.err
160: .println("Saved output document file path "
161: + temp.getAbsolutePath());
162: System.exit(1);
163: }
164:
165: // advance to next argument set
166: base += 3;
167: }
168:
169: } else {
170: System.err
171: .println("Usage: java TestRoundtrip mapped-class"
172: + " in-file [out-file]\n where out-file is only required if the"
173: + " output document is different from\nthe input document. "
174: + "Leaves output as temp.xml in case of error");
175: System.exit(1);
176: }
177: }
178: }
|