Skip to content

Commit

Permalink
fixup! JSON output no longer quotes all values
Browse files Browse the repository at this point in the history
  • Loading branch information
stevedlawrence committed Jan 10, 2025
1 parent 6861528 commit a08d1fe
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

import org.apache.daffodil.japi.infoset.JDOMInfosetInputter;
import org.apache.daffodil.japi.infoset.JDOMInfosetOutputter;
import org.apache.daffodil.japi.infoset.JsonInfosetOutputter;
import org.apache.daffodil.japi.infoset.JsonInfosetInputter;
import org.apache.daffodil.japi.io.InputSourceDataInputStream;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
Expand Down Expand Up @@ -1449,5 +1451,51 @@ public void testJavaAPICompileResource() throws IOException, ClassNotFoundExcept
}
}

@Test
public void testJavaAPIJson1() 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("/");

java.io.File file = getResource("/test/japi/myData.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
InputSourceDataInputStream dis = new InputSourceDataInputStream(fis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JsonInfosetOutputter outputter = new JsonInfosetOutputter(bos, false);
ParseResult res = dp.parse(dis, outputter);
assertFalse(res.isError());

java.io.ByteArrayInputStream input = new java.io.ByteArrayInputStream(bos.toByteArray());
JsonInfosetInputter inputter = new JsonInfosetInputter(input);
java.io.ByteArrayOutputStream bos2 = new java.io.ByteArrayOutputStream();
java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos2);
UnparseResult res2 = dp.unparse(inputter, wbc);
assertFalse(res2.isError());
assertEquals("42", bos2.toString());
}

@Test
public void testJavaAPIJson2() 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("/");

// e2 should be a simple type
String badJsonInfoset = "{\"e1\": {\"e2\": {\"unexpected\": \"object\"}}}";

java.io.ByteArrayInputStream input = new java.io.ByteArrayInputStream(badJsonInfoset.getBytes("UTF-8"));
JsonInfosetInputter inputter = new JsonInfosetInputter(input);
java.io.ByteArrayOutputStream bos2 = new java.io.ByteArrayOutputStream();
java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos2);
UnparseResult res = dp.unparse(inputter, wbc);
assertTrue(res.isError());
java.util.List<Diagnostic> diags = res.getDiagnostics();
assertEquals(1, diags.size());
assertTrue(diags.get(0).toString().contains("Illegal content for simple element"));
assertTrue(diags.get(0).toString().contains("Unexpected array or object"));
assertTrue(diags.get(0).toString().contains("e2"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,9 @@ class JsonInfosetInputter(input: java.io.InputStream) extends InfosetInputter {
jsp.getCurrentToken() match {
case JsonToken.START_OBJECT => if (objectDepth == 1) StartDocument else StartElement
case JsonToken.END_OBJECT => EndElement
case JsonToken.VALUE_STRING |
JsonToken.VALUE_NUMBER_INT |
JsonToken.VALUE_NUMBER_FLOAT |
JsonToken.VALUE_TRUE |
JsonToken.VALUE_FALSE |
JsonToken.VALUE_NULL => {
case JsonToken.VALUE_STRING | JsonToken.VALUE_NUMBER_INT |
JsonToken.VALUE_NUMBER_FLOAT | JsonToken.VALUE_TRUE | JsonToken.VALUE_FALSE |
JsonToken.VALUE_NULL => {
// we don't want to start faking element end yet, but signify that
// after a call to next(), we will want to fake it
nextEventShouldBeFakeEnd = true
Expand Down Expand Up @@ -124,8 +121,12 @@ class JsonInfosetInputter(input: java.io.InputStream) extends InfosetInputter {
runtimeProperties: java.util.Map[String, String]
): String = {
if (!jsp.getCurrentToken().isScalarValue()) {
throw new NonTextFoundInSimpleContentException("Unexpected array or object '" + getLocalName + "' on line " + jsp.getTokenLocation().getLineNr())
} else if (jsp.getCurrentToken() == JsonToken.VALUE_NULL) {
throw new NonTextFoundInSimpleContentException(
"Unexpected array or object '" + getLocalName + "' on line " + jsp
.getTokenLocation()
.getLineNr()
)
} else if (jsp.getCurrentToken() == JsonToken.VALUE_NULL) {
null
} else {
// this handles unescaping any escaped characters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class JsonInfosetOutputter private (writer: java.io.BufferedWriter, pretty: Bool
d.isInfinite || d.isNaN
}
case DFDLPrimType.Float => {
val f = simple.getFloat.toDouble
val f = simple.getFloat
f.isInfinite || f.isNaN
}
case _ => false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import org.apache.daffodil.sapi.InvalidUsageException
import org.apache.daffodil.sapi.ParseResult
import org.apache.daffodil.sapi.SAXErrorHandlerForSAPITest
import org.apache.daffodil.sapi.ValidationMode
import org.apache.daffodil.sapi.infoset.JsonInfosetInputter
import org.apache.daffodil.sapi.infoset.JsonInfosetOutputter
import org.apache.daffodil.sapi.infoset.ScalaXMLInfosetInputter
import org.apache.daffodil.sapi.infoset.ScalaXMLInfosetOutputter
import org.apache.daffodil.sapi.infoset.XMLTextEscapeStyle
Expand Down Expand Up @@ -1411,4 +1413,54 @@ class TestScalaAPI {
}
}

@Test
def testScalaAPIJson1(): Unit = {
val c = Daffodil.compiler()
val name = "/test/sapi/mySchema1.dfdl.xsd"
val pf = c.compileResource(name)
val dp = pf.onPath("/")

val file = getResource("/test/sapi/myData.dat")
val fis = new java.io.FileInputStream(file)
val bos = new ByteArrayOutputStream()
using(new InputSourceDataInputStream(fis)) { input =>
val outputter = new JsonInfosetOutputter(bos, pretty = false)
val res = dp.parse(input, outputter)
assertFalse(res.isError())
}

using(new ByteArrayInputStream(bos.toByteArray())) { input =>
val bos = new java.io.ByteArrayOutputStream()
val wbc = java.nio.channels.Channels.newChannel(bos)
val inputter = new JsonInfosetInputter(input)
val res = dp.unparse(inputter, wbc)
assertFalse(res.isError())
assertEquals("42", bos.toString())
}
}

@Test
def testScalaAPIJson2(): Unit = {
val c = Daffodil.compiler()
val name = "/test/sapi/mySchema1.dfdl.xsd"
val pf = c.compileResource(name)
val dp = pf.onPath("/")

// e2 should be a simple type
val badJsonInfoset = """{"e1": {"e2": {"unexpected": "object"}}}"""

using(new ByteArrayInputStream(badJsonInfoset.getBytes("UTF-8"))) { input =>
val bos = new java.io.ByteArrayOutputStream()
val wbc = java.nio.channels.Channels.newChannel(bos)
val inputter = new JsonInfosetInputter(input)
val res = dp.unparse(inputter, wbc)
assertTrue(res.isError())
val diags = res.getDiagnostics
assertEquals(1, diags.length)
assertTrue(diags(0).toString.contains("Illegal content for simple element"))
assertTrue(diags(0).toString.contains("Unexpected array or object"))
assertTrue(diags(0).toString.contains("e2"))
}
}

}

0 comments on commit a08d1fe

Please sign in to comment.