| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.daffodil.example; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| import java.nio.channels.Channels; |
| import java.nio.channels.ReadableByteChannel; |
| import java.nio.channels.WritableByteChannel; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.daffodil.japi.*; |
| import org.apache.daffodil.japi.infoset.XMLTextInfosetOutputter; |
| import org.jdom2.output.Format; |
| import org.junit.Test; |
| |
| import org.apache.daffodil.japi.infoset.JDOMInfosetInputter; |
| import org.apache.daffodil.japi.infoset.JDOMInfosetOutputter; |
| import org.apache.daffodil.japi.io.InputSourceDataInputStream; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| import org.xml.sax.XMLReader; |
| |
| import javax.xml.XMLConstants; |
| |
| public class TestJavaAPI { |
| |
| /** |
| * Best practices for XML loading are to turn off anything that could lead to |
| * insecurity. |
| * |
| * This is probably unnecessary in the case of these tests, but as these tests |
| * are also used to illustrate API usage, this exemplifies best practice. |
| */ |
| public static void setSecureDefaults(XMLReader xmlReader) |
| throws SAXNotSupportedException, SAXNotRecognizedException { |
| xmlReader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); |
| // since we're not really sure what they mean by secure processing |
| // we make doubly sure by setting these ourselves also. |
| xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); |
| xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); |
| xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); |
| } |
| |
| String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces"; |
| String SAX_NAMESPACE_PREFIXES_FEATURE = "http://xml.org/sax/features/namespace-prefixes"; |
| |
| private java.io.File getResource(String resPath) { |
| try { |
| return new java.io.File(this.getClass().getResource(resPath).toURI()); |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| /** |
| * This is a test-only helper function used to serialize and deserialize a |
| * DataProcessor to ensure all JAPI classes that need to extend |
| * Serializable do so appropriately. |
| * |
| * All of the JAPI tests create a DataProcessor. To test that we correctly |
| * made all the necessary changes to make the JAPI DataProcessor |
| * serializable, it is important to serialize and deserialize that |
| * DataProcessor before use in the tests. This function acts as a helper |
| * function to accomplish that task. |
| * |
| * So this functions accepts a JAPI DataProcessor, serializes and deserializes |
| * that DataProcessor in memory, and then returns the result. |
| */ |
| private DataProcessor reserializeDataProcessor(DataProcessor dp) throws IOException, ClassNotFoundException { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| dp.save(Channels.newChannel(baos)); |
| baos.close(); |
| |
| DataProcessor result = null; |
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
| try { |
| result = Daffodil.compiler().reload(Channels.newChannel(bais)); |
| } catch (InvalidParserException e) { |
| fail("Unable to reload data processor"); |
| } |
| return result; |
| } |
| |
| @Test |
| public void testJavaAPI1() throws IOException, ClassNotFoundException { |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertTrue(debugger.lines.size() > 0); |
| assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n")); |
| assertTrue(debugger.getCommand().equals("trace")); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("42", bos.toString()); |
| } |
| |
| // This is a duplicate of test testJavaAPI1 that serializes the parser |
| // before executing the test. |
| @Test |
| public void testJavaAPI1_A() throws Exception { |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| |
| // Serialize the parser to memory, then deserialize for parsing. |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| WritableByteChannel output = Channels.newChannel(os); |
| dp.save(output); |
| |
| ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); |
| ReadableByteChannel input = Channels.newChannel(is); |
| org.apache.daffodil.japi.Compiler compiler = Daffodil.compiler(); |
| DataProcessor parser = compiler.reload(input); |
| parser = parser.withDebuggerRunner(debugger); |
| parser = parser.withDebugging(true); |
| |
| File data = getResource("/test/japi/myData.dat"); |
| // This test uses a byte array here, just so as to be sure to exercise |
| // the constructor for creating an InputSourceDataInputStream from a byte array |
| // and byte buffer. |
| byte[] ba = FileUtils.readFileToByteArray(data); |
| ByteBuffer bb = ByteBuffer.wrap(ba); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(bb); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = parser.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertTrue(debugger.lines.size() > 0); |
| assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n")); |
| assertTrue(debugger.getCommand().equals("trace")); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("42", bos.toString()); |
| } |
| |
| // This is a duplicate of test testJavaAPI1 that serializes the parser |
| // before executing the test. |
| @Test |
| public void testJavaAPI1_A_FullFails() throws Exception { |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| |
| // Serialize the parser to memory, then deserialize for parsing. |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| WritableByteChannel output = Channels.newChannel(os); |
| dp.save(output); |
| |
| ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); |
| ReadableByteChannel input = Channels.newChannel(is); |
| org.apache.daffodil.japi.Compiler compiler = Daffodil.compiler(); |
| DataProcessor parser = compiler.reload(input); |
| |
| try { |
| parser = parser.withValidationMode(ValidationMode.Full); |
| fail(); |
| } catch (InvalidUsageException e) { |
| assertEquals("'Full' validation not allowed when using a restored parser.", e.getMessage()); |
| } |
| } |
| |
| @Test |
| public void testJavaAPI2() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myDataBroken.dat"); |
| // This test uses a byte array here, just so as to be sure to exercise |
| // the constructor for creating an InputSourceDataInputStream from a byte array |
| // and byte buffer. |
| byte[] ba = FileUtils.readFileToByteArray(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(ba); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| |
| // TODO: NEED a java friendly way to get the status of the outputter. |
| // Scala enums don't work well |
| // assertTrue(outputter.getStatus() != Status.DONE); // This is a hack |
| // so that Java doesn't have to know about Nope/Maybe, need to figure |
| // out better api that is Java compatible |
| assertTrue(res.isError()); |
| java.util.List<Diagnostic> diags = res.getDiagnostics(); |
| assertEquals(1, diags.size()); |
| Diagnostic d = diags.get(0); |
| // System.err.println(d.getMessage()); |
| assertTrue(d.getMessage().contains("int")); |
| assertTrue(d.getMessage().contains("Not an int")); |
| assertTrue(d.getDataLocations().toString().contains("10")); |
| java.util.List<LocationInSchemaFile> locs = d.getLocationsInSchemaFiles(); |
| assertEquals(1, locs.size()); |
| LocationInSchemaFile loc = locs.get(0); |
| assertTrue(loc.toString().contains("mySchema1.dfdl.xsd")); |
| // above is mySchema1 as it reports the element ref location, |
| // not element decl. |
| } |
| |
| /** |
| * Verify that we can detect when the parse did not consume all the data. |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void testJavaAPI3() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| pf = pf.withDistinguishedRootNode("e3", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData16.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertEquals(2, res.location().bytePos1b()); |
| assertEquals(9, res.location().bitPos1b()); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("9", bos.toString()); |
| } |
| |
| // This is a duplicate of test testJavaAPI3 that serializes the parser |
| // before executing the test. |
| @Test |
| public void testJavaAPI3_A() throws Exception { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| pf = pf.withDistinguishedRootNode("e3", null); |
| DataProcessor dp = pf.onPath("/"); |
| |
| // Serialize the parser to memory, then deserialize for parsing. |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| WritableByteChannel output = Channels.newChannel(os); |
| dp.save(output); |
| |
| ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); |
| ReadableByteChannel input = Channels.newChannel(is); |
| org.apache.daffodil.japi.Compiler compiler = Daffodil.compiler(); |
| DataProcessor parser = compiler.reload(input); |
| |
| java.io.File file = getResource("/test/japi/myData16.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = parser.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertEquals(2, res.location().bytePos1b()); |
| assertEquals(9, res.location().bitPos1b()); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("9", bos.toString()); |
| } |
| |
| @Test |
| public void testJavaAPI4b() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFileName, "e4", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData2.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertEquals(5, res.location().bytePos1b()); |
| assertEquals(33, res.location().bitPos1b()); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("data", bos.toString()); |
| } |
| |
| @Test |
| public void testJavaAPI5() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFileName, "e4", null); // e4 is a 4-byte long string |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData3.dat"); // contains 5 |
| // bytes |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| assertEquals(5, res.location().bytePos1b()); |
| assertEquals(33, res.location().bitPos1b()); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertEquals("data", bos.toString()); |
| } |
| |
| /*** |
| * Verify that the compiler throws a FileNotFound exception when fed a list |
| * of schema files that do not exist. |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void testJavaAPI6() throws IOException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = new java.io.File("/test/japi/notHere1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| assertTrue(pf.isError()); |
| List<Diagnostic> diags = pf.getDiagnostics(); |
| boolean found1 = false; |
| for (Diagnostic d : diags) { |
| if (d.getMessage().contains("notHere1")) { |
| found1 = true; |
| } |
| } |
| assertTrue(found1); |
| } |
| |
| /** |
| * Tests a user submitted case where the XML appears to be serializing odd |
| * xml entities into the output. |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void testJavaAPI7() throws IOException, ClassNotFoundException { |
| // TODO: This is due to the fact that we are doing several conversions |
| // back and forth between Scala.xml.Node and JDOM. And the conversions |
| // both use XMLOutputter to format the result (which escapes the |
| // entities). |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/TopLevel.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile, "TopLevel", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/01very_simple.txt"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertTrue(bos.toString().contains("Return-Path: <bob@smith.com>")); |
| } |
| |
| /** |
| * This test is nearly identical to testJavaAPI7. The only difference is |
| * that this test uses double newline as a terminator for the first element |
| * in the sequence rather than double newline as a separator for the |
| * sequence |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void testJavaAPI8() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/TopLevel.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile, "TopLevel2", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/01very_simple.txt"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult()); |
| UnparseResult res2 = dp.unparse(inputter, wbc); |
| err = res2.isError(); |
| assertFalse(err); |
| assertTrue(bos.toString().contains("Return-Path: <bob@smith.com>")); |
| } |
| |
| /** |
| * Verify that calling result() on the ParseResult multiple times does not |
| * error. |
| */ |
| @Test |
| public void testJavaAPI9() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/TopLevel.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile, "TopLevel2", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/01very_simple.txt"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| |
| org.jdom2.Document doc1 = outputter.getResult(); |
| |
| java.io.ByteArrayOutputStream bos1 = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc1 = java.nio.channels.Channels.newChannel(bos1); |
| JDOMInfosetInputter inputter1 = new JDOMInfosetInputter(doc1); |
| UnparseResult res2 = dp.unparse(inputter1, wbc1); |
| err = res2.isError(); |
| assertFalse(err); |
| assertTrue(bos1.toString().contains("Return-Path: <bob@smith.com>")); |
| |
| org.jdom2.Document doc2 = outputter.getResult(); |
| |
| java.io.ByteArrayOutputStream bos2 = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc2 = java.nio.channels.Channels.newChannel(bos2); |
| JDOMInfosetInputter inputter2 = new JDOMInfosetInputter(doc2); |
| UnparseResult res3 = dp.unparse(inputter2, wbc2); |
| err = res3.isError(); |
| assertFalse(err); |
| assertTrue(bos2.toString().contains("Return-Path: <bob@smith.com>")); |
| } |
| |
| /** |
| * Verify that hidden elements do not appear in the resulting infoset |
| */ |
| @Test |
| public void testJavaAPI10() throws IOException, ClassNotFoundException { |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema4.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData4.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| org.jdom2.Element rootNode = doc.getRootElement(); |
| org.jdom2.Element hidden = rootNode.getChild("hiddenElement", rootNode.getNamespace()); |
| assertTrue(null == hidden); |
| } |
| |
| /** |
| * Verify that nested elements do not appear as duplicates |
| */ |
| @Test |
| public void testJavaAPI11() throws IOException, ClassNotFoundException { |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema5.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData5.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| // xo.output(doc, System.out); |
| org.jdom2.Element rootNode = doc.getRootElement(); |
| org.jdom2.Element elementGroup = rootNode.getChild("elementGroup", null); // local |
| // element |
| // names |
| // are |
| // unqualified |
| assertTrue(null != elementGroup); |
| org.jdom2.Element groupE2 = elementGroup.getChild("e2", null); |
| assertTrue(null != groupE2); |
| org.jdom2.Element groupE3 = elementGroup.getChild("e3", null); |
| assertTrue(null != groupE3); |
| org.jdom2.Element rootE2 = rootNode.getChild("e2", null); |
| assertTrue(null == rootE2); |
| org.jdom2.Element rootE3 = rootNode.getChild("e3", null); |
| assertTrue(null == rootE3); |
| } |
| |
| @Test |
| public void testJavaAPI12() throws IOException, ClassNotFoundException { |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| |
| assertTrue(debugger.lines.size() > 0); |
| assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n")); |
| } |
| |
| @Test |
| public void testJavaAPI13() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates here that we can set external variables |
| // after compilation but before parsing via Compiler. |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File extVarsFile = getResource("/test/japi/external_vars_1.xml"); |
| java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| dp = dp.withExternalVariables(extVarsFile); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| String docString = xo.outputString(doc); |
| boolean containsVar1 = docString.contains("var1Value"); |
| boolean containsVar1Value = docString.contains("externallySet"); |
| assertTrue(containsVar1); |
| assertTrue(containsVar1Value); |
| } |
| |
| @Test |
| public void testJavaAPI14() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates here that we can set external variables |
| // after compilation but before parsing via DataProcessor. |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File extVarFile = getResource("/test/japi/external_vars_1.xml"); |
| java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| dp = dp.withExternalVariables(extVarFile); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| String docString = xo.outputString(doc); |
| boolean containsVar1 = docString.contains("var1Value"); |
| boolean containsVar1Value = docString.contains("externallySet"); |
| assertTrue(containsVar1); |
| assertTrue(containsVar1Value); |
| |
| assertTrue(debugger.lines.size() > 0); |
| assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n")); |
| } |
| |
| @Test |
| public void testJavaAPI15() throws IOException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myInfosetBroken.xml"); |
| org.jdom2.input.SAXBuilder builder = new org.jdom2.input.SAXBuilder(); |
| |
| org.jdom2.Document doc = null; |
| try { |
| doc = builder.build(file); |
| } catch (Exception e) { |
| fail(); |
| } |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| JDOMInfosetInputter inputter = new JDOMInfosetInputter(doc); |
| UnparseResult res = dp.unparse(inputter, wbc); |
| boolean err = res.isError(); |
| assertTrue(err); |
| |
| java.util.List<Diagnostic> diags = res.getDiagnostics(); |
| assertEquals(1, diags.size()); |
| Diagnostic d = diags.get(0); |
| assertTrue(d.getMessage().contains("wrong")); |
| assertTrue(d.getMessage().contains("e2")); |
| } |
| |
| @Test |
| public void testJavaAPI16() throws IOException, InvalidUsageException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withValidationMode(ValidationMode.Limited); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| assertTrue(res.isError()); |
| assertFalse(res.isProcessingError()); |
| assertTrue(res.isValidationError()); |
| |
| java.util.List<Diagnostic> diags = res.getDiagnostics(); |
| assertEquals(1, diags.size()); |
| Diagnostic d = diags.get(0); |
| assertTrue(d.getMessage().contains("maxInclusive")); |
| assertTrue(d.getMessage().contains("e2")); |
| assertTrue(d.getMessage().contains("20")); |
| } |
| |
| @Test |
| public void testJavaAPI17() throws IOException, InvalidUsageException, ClassNotFoundException { |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = dp.withValidationMode(ValidationMode.Full); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| assertTrue(res.isError()); |
| assertFalse(res.isProcessingError()); |
| assertTrue(res.isValidationError()); |
| long actualLength = res.location().bytePos1b() - 1; |
| assertEquals(file.length(), actualLength); |
| |
| java.util.List<Diagnostic> diags = res.getDiagnostics(); |
| assertEquals(3, diags.size()); |
| Diagnostic d0 = diags.get(0); |
| Diagnostic d1 = diags.get(1); |
| Diagnostic d2 = diags.get(2); |
| |
| assertTrue(d0.getMessage().contains("42")); |
| assertTrue(d0.getMessage().contains("e2")); |
| assertTrue(d0.getMessage().contains("not valid")); |
| |
| assertTrue(d1.getMessage().contains("42")); |
| assertTrue(d1.getMessage().contains("maxInclusive")); |
| assertTrue(d1.getMessage().contains("20")); |
| |
| assertTrue(d2.getMessage().contains("maxInclusive")); |
| assertTrue(d2.getMessage().contains("e2")); |
| assertTrue(d2.getMessage().contains("20")); |
| } |
| |
| @Test |
| public void testJavaAPI18() throws IOException, ClassNotFoundException { |
| // Demonstrate that we can use the API to continue a parse where we left off |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile,"e4", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData2.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream input = new InputSourceDataInputStream(fis); |
| |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = null; |
| boolean err = false; |
| |
| res = dp.parse(input, outputter); |
| err = res.isError(); |
| assertFalse(err); |
| assertEquals(5, res.location().bytePos1b()); |
| assertEquals("data", outputter.getResult().getRootElement().getText()); |
| |
| outputter.reset(); |
| res = dp.parse(input, outputter); |
| err = res.isError(); |
| assertFalse(err); |
| assertEquals(9, res.location().bytePos1b()); |
| assertEquals("left", outputter.getResult().getRootElement().getText()); |
| |
| outputter.reset(); |
| res = dp.parse(input, outputter); |
| err = res.isError(); |
| assertFalse(err); |
| assertFalse(input.hasData()); |
| assertEquals(13, res.location().bytePos1b()); |
| assertEquals("over", outputter.getResult().getRootElement().getText()); |
| } |
| |
| @Test |
| public void testJavaAPI19() throws IOException, ClassNotFoundException { |
| // Demonstrate that we cannot use the API to continue a parse with an invalid InputSource |
| // ie. after a runtime SDE. This test needs to be run with an input file larger than 256MB |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/ambig_elt.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile, "root", null); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myData19.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream input = new InputSourceDataInputStream(fis); |
| |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = null; |
| boolean err = false; |
| |
| res = dp.parse(input, outputter); |
| err = res.isError(); |
| assertTrue(err); |
| |
| outputter.reset(); |
| try { |
| res = dp.parse(input, outputter); |
| } catch (Exception e) { |
| assertTrue(e.getMessage().contains("Usage error")); |
| assertTrue(e.getMessage().contains("invalid input source")); |
| } |
| } |
| |
| @Test |
| public void testJavaAPI20() throws IOException, ClassNotFoundException { |
| // Test SAX parsing/unparsing |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| DaffodilParseXMLReader parseXMLReader = dp.newXMLReaderInstance(); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fisDP = new java.io.FileInputStream(file); |
| java.io.FileInputStream fisSAX = new java.io.FileInputStream(file); |
| InputSourceDataInputStream disDP = new InputSourceDataInputStream(fisDP); |
| InputSourceDataInputStream disSAX = new InputSourceDataInputStream(fisSAX); |
| ByteArrayOutputStream xmlBos = new ByteArrayOutputStream(); |
| XMLTextInfosetOutputter outputter = new XMLTextInfosetOutputter(xmlBos, true); |
| ParseResult res = dp.parse(disDP, outputter); |
| String infosetDPString = xmlBos.toString(); |
| |
| org.jdom2.input.sax.SAXHandler contentHandler = new org.jdom2.input.sax.SAXHandler(); |
| SAXErrorHandlerForJAPITest errorHandler = new SAXErrorHandlerForJAPITest(); |
| // since SAXHandler uses a blank prefix when the below isn't set to true, it introduces |
| // an undesired no-prefixed xmlns mapping |
| parseXMLReader.setFeature(SAX_NAMESPACE_PREFIXES_FEATURE, true); |
| parseXMLReader.setContentHandler(contentHandler); |
| parseXMLReader.setErrorHandler(errorHandler); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBDIRECTORY(), |
| Paths.get(System.getProperty("java.io.tmpdir"))); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBPREFIX(), |
| "daffodil-sapi-"); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBSUFFIX(), |
| ".sax.blob"); |
| parseXMLReader.parse(disSAX); |
| ParseResult resSAX = (ParseResult) parseXMLReader.getProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_PARSERESULT()); |
| boolean err = errorHandler.isError(); |
| ArrayList<Diagnostic> diags = errorHandler.getDiagnostics(); |
| Format pretty = Format.getPrettyFormat().setLineSeparator(System.getProperty("line.separator")); |
| String infosetSAXString = new org.jdom2.output.XMLOutputter(pretty).outputString(contentHandler.getDocument()); |
| |
| assertFalse(err); |
| assertTrue(diags.isEmpty()); |
| assertEquals(infosetDPString, infosetSAXString); |
| |
| // test unparse |
| ByteArrayOutputStream unparseBos = new java.io.ByteArrayOutputStream(); |
| WritableByteChannel wbc = java.nio.channels.Channels.newChannel(unparseBos); |
| |
| // prep for SAX unparse |
| DaffodilUnparseContentHandler unparseContentHandler = dp.newContentHandlerInstance(wbc); |
| try { |
| org.xml.sax.XMLReader unparseXMLReader = javax.xml.parsers.SAXParserFactory.newInstance() |
| .newSAXParser().getXMLReader(); |
| setSecureDefaults(unparseXMLReader); |
| unparseXMLReader.setContentHandler(unparseContentHandler); |
| unparseXMLReader.setErrorHandler(errorHandler); |
| unparseXMLReader.setFeature(SAX_NAMESPACES_FEATURE, true); |
| unparseXMLReader.setFeature(SAX_NAMESPACE_PREFIXES_FEATURE, true); |
| ByteArrayInputStream is = new ByteArrayInputStream(infosetSAXString.getBytes()); |
| // kickstart unparse |
| unparseXMLReader.parse(new org.xml.sax.InputSource(is)); |
| } catch (javax.xml.parsers.ParserConfigurationException | org.xml.sax.SAXException e) { |
| fail("Error: " + e); |
| } |
| |
| UnparseResult saxUr = unparseContentHandler.getUnparseResult(); |
| wbc.close(); |
| |
| boolean saxErr = saxUr.isError(); |
| assertFalse(saxErr); |
| assertTrue(saxUr.getDiagnostics().isEmpty()); |
| assertEquals("42", unparseBos.toString()); |
| } |
| |
| |
| @Test |
| public void testJavaAPI21() throws IOException, ClassNotFoundException { |
| // Test SAX parsing with errors |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| DaffodilParseXMLReader parseXMLReader = dp.newXMLReaderInstance(); |
| |
| java.io.File file = getResource("/test/japi/myDataBroken.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| |
| org.jdom2.input.sax.SAXHandler contentHandler = new org.jdom2.input.sax.SAXHandler(); |
| SAXErrorHandlerForJAPITest errorHandler = new SAXErrorHandlerForJAPITest(); |
| parseXMLReader.setContentHandler(contentHandler); |
| parseXMLReader.setErrorHandler(errorHandler); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBDIRECTORY(), |
| Paths.get(System.getProperty("java.io.tmpdir"))); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBPREFIX(), "daffodil-sapi-"); |
| parseXMLReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBSUFFIX(), ".sax.blob"); |
| parseXMLReader.parse(dis); |
| boolean err = errorHandler.isError(); |
| ArrayList<Diagnostic> diags = errorHandler.getDiagnostics(); |
| |
| assertTrue(err); |
| assertEquals(1, diags.size()); |
| Diagnostic d = diags.get(0); |
| assertTrue(d.getMessage().contains("int")); |
| assertTrue(d.getMessage().contains("Not an int")); |
| assertTrue(d.getDataLocations().toString().contains("10")); |
| java.util.List<LocationInSchemaFile> locs = d.getLocationsInSchemaFiles(); |
| assertEquals(1, locs.size()); |
| LocationInSchemaFile loc = locs.get(0); |
| assertTrue(loc.toString().contains("mySchema1.dfdl.xsd")); |
| } |
| |
| @Test |
| public void testJavaAPI22_setExternalVariablesUsingAbstractMap() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates here that we can set external variables using a |
| // Java AbstractMap after compilation but before parsing via DataProcessor. |
| DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest(); |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File extVarFile = getResource("/test/japi/external_vars_1.xml"); |
| java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| dp = dp.withDebuggerRunner(debugger); |
| dp = dp.withDebugging(true); |
| |
| java.util.AbstractMap<String, String> extVarsMap = new java.util.HashMap<String, String>(); |
| extVarsMap.put("var1", "var1ValueFromMap"); |
| |
| dp = dp.withExternalVariables(extVarsMap); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| boolean err = res.isError(); |
| assertFalse(err); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| String docString = xo.outputString(doc); |
| boolean containsVar1 = docString.contains("var1Value"); |
| boolean containsVar1Value = docString.contains("var1ValueFromMap"); |
| assertTrue(containsVar1); |
| assertTrue(containsVar1Value); |
| |
| assertTrue(debugger.lines.size() > 0); |
| assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n")); |
| } |
| |
| @Test |
| public void testJavaAPI23() throws IOException, ClassNotFoundException { |
| // test SAX unparsing with errors |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.io.File file = getResource("/test/japi/myInfosetBroken.xml"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| // prep for SAX |
| DaffodilUnparseContentHandler unparseContentHandler = dp.newContentHandlerInstance(wbc); |
| try { |
| org.xml.sax.XMLReader unparseXMLReader = javax.xml.parsers.SAXParserFactory.newInstance() |
| .newSAXParser().getXMLReader(); |
| setSecureDefaults(unparseXMLReader); |
| unparseXMLReader.setContentHandler(unparseContentHandler); |
| unparseXMLReader.setFeature(SAX_NAMESPACES_FEATURE, true); |
| unparseXMLReader.setFeature(SAX_NAMESPACE_PREFIXES_FEATURE, true); |
| // kickstart unparse |
| unparseXMLReader.parse(new org.xml.sax.InputSource(fis)); |
| } catch (DaffodilUnparseErrorSAXException | DaffodilUnhandledSAXException ignored) { |
| // do nothing; UnparseError is handled below while we don't expect Unhandled in this test |
| } catch (javax.xml.parsers.ParserConfigurationException | org.xml.sax.SAXException e) { |
| fail("Error: " + e); |
| } |
| |
| UnparseResult res = unparseContentHandler.getUnparseResult(); |
| boolean err = res.isError(); |
| assertTrue(err); |
| |
| java.util.List<Diagnostic> diags = res.getDiagnostics(); |
| assertEquals(1, diags.size()); |
| Diagnostic d = diags.get(0); |
| assertTrue(d.getMessage().contains("wrong")); |
| assertTrue(d.getMessage().contains("e2")); |
| } |
| |
| @Test |
| public void testJavaAPI24() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates error cases of setting external variables |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| |
| java.io.File schemaFile = getResource("/test/japi/mySchemaWithComplexVars1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| dp = reserializeDataProcessor(dp); |
| |
| java.util.AbstractMap<String, String> extVarsMap = new java.util.HashMap<String, String>(); |
| |
| // set var without a namespace, ambiguity error because schema contains |
| // two variables with same name but different namespace |
| extVarsMap.clear(); |
| extVarsMap.put("var", "10"); |
| try { |
| dp = dp.withExternalVariables(extVarsMap); |
| } catch (ExternalVariableException e) { |
| String msg = e.getMessage(); |
| assertTrue(msg.contains("var")); |
| assertTrue(msg.contains("ambiguity")); |
| assertTrue(msg.contains("ex1:var")); |
| assertTrue(msg.contains("ex2:var")); |
| } |
| |
| // variable without namespace does not exist error |
| extVarsMap.clear(); |
| extVarsMap.put("dne", "10"); |
| try { |
| dp = dp.withExternalVariables(extVarsMap); |
| } catch (ExternalVariableException e) { |
| String msg = e.getMessage(); |
| assertTrue(msg.contains("definition not found")); |
| assertTrue(msg.contains("dne")); |
| } |
| |
| // variable with namespace does not exist error |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/1}dne", "10"); |
| try { |
| dp = dp.withExternalVariables(extVarsMap); |
| } catch (ExternalVariableException e) { |
| String msg = e.getMessage(); |
| assertTrue(msg.contains("definition not found")); |
| assertTrue(msg.contains("{http://example.com/1}dne")); |
| } |
| |
| // variable cannot be set externally |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/2}var", "10"); |
| try { |
| dp = dp.withExternalVariables(extVarsMap); |
| } catch (ExternalVariableException e) { |
| String msg = e.getMessage(); |
| assertTrue(msg.contains("ex2:var")); |
| assertTrue(msg.contains("cannot be set externally")); |
| } |
| |
| // variable not valid with regards to type |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/1}var", "notAnInt"); |
| try { |
| dp = dp.withExternalVariables(extVarsMap); |
| } catch (ExternalVariableException e) { |
| String msg = e.getMessage(); |
| assertTrue(msg.contains("ex1:var")); |
| assertTrue(msg.contains("is not a valid xs:int")); |
| assertTrue(msg.contains("notAnInt")); |
| } |
| |
| // can change the value of the same variable multiple times |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/1}var", "100"); |
| dp = dp.withExternalVariables(extVarsMap); |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/1}var", "200"); |
| dp = dp.withExternalVariables(extVarsMap); |
| |
| // can parse with the variable values |
| { |
| byte[] ba = {}; |
| ByteBuffer bb = ByteBuffer.wrap(ba); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(bb); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| assertFalse(res.isError()); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| String docString = xo.outputString(doc); |
| assertTrue(docString.contains("<ex1var>200</ex1var>")); |
| } |
| |
| // can set an external variable after a parse |
| extVarsMap.clear(); |
| extVarsMap.put("{http://example.com/1}var", "300"); |
| dp = dp.withExternalVariables(extVarsMap); |
| |
| // can parse with the updated variable value |
| { |
| byte[] ba = {}; |
| ByteBuffer bb = ByteBuffer.wrap(ba); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(bb); |
| JDOMInfosetOutputter outputter = new JDOMInfosetOutputter(); |
| ParseResult res = dp.parse(dis, outputter); |
| assertFalse(res.isError()); |
| org.jdom2.Document doc = outputter.getResult(); |
| org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter(); |
| xo.setFormat(Format.getPrettyFormat()); |
| String docString = xo.outputString(doc); |
| assertTrue(docString.contains("<ex1var>300</ex1var>")); |
| } |
| } |
| |
| @Test |
| public void testJavaAPI25() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates the use of a custom InfosetInputter/Outputter |
| |
| String expectedData = "42"; |
| TestInfosetEvent expectedEvents[] = { |
| TestInfosetEvent.startDocument(), |
| TestInfosetEvent.startComplex("e1", "http://example.com"), |
| TestInfosetEvent.startSimple("e2", "http://example.com", expectedData), |
| TestInfosetEvent.endSimple("e2", "http://example.com"), |
| TestInfosetEvent.endComplex("e1", "http://example.com"), |
| TestInfosetEvent.endDocument() |
| }; |
| |
| org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); |
| java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); |
| ProcessorFactory pf = c.compileFile(schemaFile); |
| DataProcessor dp = pf.onPath("/"); |
| |
| java.io.File file = getResource("/test/japi/myData.dat"); |
| java.io.FileInputStream fis = new java.io.FileInputStream(file); |
| InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); |
| TestInfosetOutputter outputter = new TestInfosetOutputter(); |
| ParseResult pr = dp.parse(dis, outputter); |
| |
| assertFalse(pr.isError()); |
| assertArrayEquals(expectedEvents, outputter.events.toArray()); |
| |
| java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); |
| java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos); |
| TestInfosetInputter inputter = new TestInfosetInputter(expectedEvents); |
| UnparseResult ur = dp.unparse(inputter, wbc); |
| |
| assertFalse(ur.isError()); |
| assertEquals(expectedData, bos.toString()); |
| } |
| |
| @Test |
| public void testJavaAPI26() throws IOException, ClassNotFoundException, ExternalVariableException { |
| // Demonstrates the use of the various EntityResolver methods from Java |
| |
| assertTrue(DaffodilXMLEntityResolver.getEntityResolver() != null); |
| assertTrue(DaffodilXMLEntityResolver.getXMLEntityResolver() != null); |
| assertTrue(DaffodilXMLEntityResolver.getLSResourceResolver() != null); |
| } |
| } |