This is an automated email from the ASF dual-hosted git repository. jw3 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/master by this push: new 7faeb04 Allow custom debuggers through SAPI and JAPI 7faeb04 is described below commit 7faeb04aa17337487848f5f61141a74d7d82484b Author: John Wass <wa...@ctc.com> AuthorDate: Wed Mar 31 10:45:51 2021 -0400 Allow custom debuggers through SAPI and JAPI DAFFODIL-2491 --- .../scala/org/apache/daffodil/japi/Daffodil.scala | 20 ++++-- .../daffodil/example/TestCustomDebuggerAPI.java | 79 ++++++++++++++++++++++ .../org/apache/daffodil/example/TestJavaAPI.java | 14 ++-- .../scala/org/apache/daffodil/sapi/Daffodil.scala | 20 ++++-- .../daffodil/example/TestCustomDebuggerAPI.scala | 62 +++++++++++++++++ .../org/apache/daffodil/example/TestScalaAPI.scala | 16 ++--- 6 files changed, 188 insertions(+), 23 deletions(-) diff --git a/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala b/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala index 83918dc..ba48c30 100644 --- a/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala +++ b/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala @@ -58,6 +58,7 @@ import java.net.URI import org.apache.daffodil.api.URISchemaSource import org.apache.daffodil.api.Validator +import org.apache.daffodil.debugger.Debugger import org.apache.daffodil.util.Maybe import org.apache.daffodil.util.Maybe._ import org.apache.daffodil.util.MaybeULong @@ -532,7 +533,8 @@ class DataProcessor private[japi] (private var dp: SDataProcessor) /** * Enable/disable debugging. * - * Before enabling, [[DataProcessor#setDebugger(DebuggerRunner)]] must be called with a non-null debugger. + * Before enabling, [[DataProcessor#withDebugger]] or [[DataProcessor#withDebuggerRunner(DebuggerRunner)]] must be + * called with a non-null debugger. * * @param flag true to enable debugging, false to disabled */ @@ -544,7 +546,8 @@ class DataProcessor private[japi] (private var dp: SDataProcessor) /** * Obtain a new [[DataProcessor]] instance with debugging enabled or disabled. * - * Before enabling, [[DataProcessor#withDebugger(DebuggerRunner)]] must be called to obtain a [[DataProcessor]] with a non-null debugger. + * Before enabling, [[DataProcessor#withDebugger(Debugger)]] or [[DataProcessor#withDebuggerRunner(DebuggerRunner)]] + * must be called to obtain a [[DataProcessor]] with a non-null debugger. * * @param flag true to enable debugging, false to disabled */ @@ -557,7 +560,7 @@ class DataProcessor private[japi] (private var dp: SDataProcessor) * * @param dr debugger runner */ - @deprecated("Use withDebugger.", "2.6.0") + @deprecated("Use withDebuggerRunner.", "2.6.0") def setDebugger(dr: DebuggerRunner): Unit = { val debugger = newDebugger(dr) dp = dp.withDebugger(debugger) @@ -568,11 +571,20 @@ class DataProcessor private[japi] (private var dp: SDataProcessor) * * @param dr debugger runner */ - def withDebugger(dr: DebuggerRunner): DataProcessor = { + def withDebuggerRunner(dr: DebuggerRunner): DataProcessor = { val debugger = newDebugger(dr) copy(dp = dp.withDebugger(debugger)) } + /** + * Obtain a new [[DataProcessor]] with a specified debugger. + * + * @param dbg debugger + */ + def withDebugger(dbg: Debugger): DataProcessor = { + copy(dp = dp.withDebugger(dbg)) + } + private def newDebugger(dr: DebuggerRunner) = { val runner = dr match { case tdr: TraceDebuggerRunner => new STraceDebuggerRunner() diff --git a/daffodil-japi/src/test/java/org/apache/daffodil/example/TestCustomDebuggerAPI.java b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestCustomDebuggerAPI.java new file mode 100644 index 0000000..91af3f1 --- /dev/null +++ b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestCustomDebuggerAPI.java @@ -0,0 +1,79 @@ +/* + * 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 org.apache.daffodil.debugger.Debugger; +import org.apache.daffodil.japi.Daffodil; +import org.apache.daffodil.japi.DataProcessor; +import org.apache.daffodil.japi.ParseResult; +import org.apache.daffodil.japi.ProcessorFactory; +import org.apache.daffodil.japi.infoset.NullInfosetOutputter; +import org.apache.daffodil.japi.io.InputSourceDataInputStream; +import org.apache.daffodil.processors.parsers.PState; +import org.apache.daffodil.processors.parsers.Parser; +import org.apache.daffodil.util.Misc; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TestCustomDebuggerAPI { + static class CustomDebugger implements Debugger { + public int nodes; + public boolean inited; + public boolean finished; + + @Override + public void init(PState state, Parser processor) { + inited = true; + } + + @Override + public void before(PState state, Parser processor) { + nodes += 1; + } + + @Override + public void fini(Parser processor) { + finished = true; + } + } + @Test + public void testCustomDebugger() throws IOException, ClassNotFoundException { + org.apache.daffodil.japi.Compiler c = Daffodil.compiler(); + + CustomDebugger dbg = new CustomDebugger(); + URI schemaFileName = Misc.getRequiredResource("/test/japi/mySchema1.dfdl.xsd"); + ProcessorFactory pf = c.compileSource(schemaFileName); + DataProcessor dp = pf.onPath("/") + .withDebugger(dbg) + .withDebugging(true); + + String file = Misc.getRequiredResource("/test/japi/myData2.dat").toURL().getFile(); + java.io.FileInputStream fis = new java.io.FileInputStream(file); + InputSourceDataInputStream dis = new InputSourceDataInputStream(fis); + ParseResult res = dp.parse(dis, new NullInfosetOutputter()); + + assertEquals(6, dbg.nodes); + assertTrue(dbg.inited); + assertTrue(dbg.finished); + } +} diff --git a/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java index f7f654a..99647e5 100644 --- a/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java +++ b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java @@ -99,7 +99,7 @@ public class TestJavaAPI { ProcessorFactory pf = c.compileFile(schemaFile); DataProcessor dp = pf.onPath("/"); dp = reserializeDataProcessor(dp); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); java.io.File file = getResource("/test/japi/myData.dat"); @@ -154,7 +154,7 @@ public class TestJavaAPI { ReadableByteChannel input = Channels.newChannel(is); org.apache.daffodil.japi.Compiler compiler = Daffodil.compiler(); DataProcessor parser = compiler.reload(input); - parser = parser.withDebugger(debugger); + parser = parser.withDebuggerRunner(debugger); parser = parser.withDebugging(true); java.io.File file = getResource("/test/japi/myData.dat"); @@ -199,7 +199,7 @@ public class TestJavaAPI { java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd"); ProcessorFactory pf = c.compileFile(schemaFile); DataProcessor dp = pf.onPath("/"); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); // Serialize the parser to memory, then deserialize for parsing. @@ -661,7 +661,7 @@ public class TestJavaAPI { ProcessorFactory pf = c.compileFile(schemaFile); DataProcessor dp = pf.onPath("/"); dp = reserializeDataProcessor(dp); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); java.io.File file = getResource("/test/japi/myData.dat"); @@ -702,7 +702,7 @@ public class TestJavaAPI { DataProcessor dp = pf.onPath("/"); dp = reserializeDataProcessor(dp); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); dp = dp.withExternalVariables(extVarsFile); @@ -744,7 +744,7 @@ public class TestJavaAPI { ProcessorFactory pf = c.compileFile(schemaFile); DataProcessor dp = pf.onPath("/"); dp = reserializeDataProcessor(dp); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); dp = dp.withExternalVariables(extVarFile); @@ -1085,7 +1085,7 @@ public class TestJavaAPI { ProcessorFactory pf = c.compileFile(schemaFile); DataProcessor dp = pf.onPath("/"); dp = reserializeDataProcessor(dp); - dp = dp.withDebugger(debugger); + dp = dp.withDebuggerRunner(debugger); dp = dp.withDebugging(true); java.util.AbstractMap<String, String> extVarsMap = new java.util.HashMap<String, String>(); diff --git a/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala b/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala index 384ca29..bd3c2a9 100644 --- a/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala +++ b/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala @@ -56,6 +56,7 @@ import java.net.URI import org.apache.daffodil.api.URISchemaSource import org.apache.daffodil.api.Validator +import org.apache.daffodil.debugger.Debugger import org.apache.daffodil.sapi.ValidationMode.ValidationMode import org.apache.daffodil.util.Maybe import org.apache.daffodil.util.Maybe._ @@ -494,7 +495,8 @@ class DataProcessor private[sapi] (private var dp: SDataProcessor) /** * Enable/disable debugging. * - * Before enabling, [[DataProcessor#setDebugger]] must be called with a non-null debugger. + * Before enabling, [[DataProcessor#withDebugger]] or [[DataProcessor#withDebuggerRunner]] must be called with a + * non-null debugger. * * @param flag true to enable debugging, false to disabled */ @@ -506,7 +508,8 @@ class DataProcessor private[sapi] (private var dp: SDataProcessor) /** * Obtain a new [[DataProcessor]] instance with debugging enabled or disabled. * - * Before enabling, [[DataProcessor#withDebugger]] must be called to obtain a [[DataProcessor]] with a non-null debugger. + * Before enabling, [[DataProcessor#withDebugger]] or [[DataProcessor#withDebuggerRunner]] must be called to obtain + * a [[DataProcessor]] with a non-null debugger. * * @param flag true to enable debugging, false to disabled */ @@ -519,7 +522,7 @@ class DataProcessor private[sapi] (private var dp: SDataProcessor) * * @param dr debugger runner */ - @deprecated("Use withDebugger.", "2.6.0") + @deprecated("Use withDebuggerRunner.", "2.6.0") def setDebugger(dr: DebuggerRunner): Unit = { val debugger = newDebugger(dr) dp = dp.withDebugger(debugger) @@ -530,11 +533,20 @@ class DataProcessor private[sapi] (private var dp: SDataProcessor) * * @param dr debugger runner */ - def withDebugger(dr: DebuggerRunner): DataProcessor = { + def withDebuggerRunner(dr: DebuggerRunner): DataProcessor = { val debugger = newDebugger(dr) copy(dp = dp.withDebugger(debugger)) } + /** + * Obtain a new [[DataProcessor]] with a specified debugger. + * + * @param dbg debugger + */ + def withDebugger(dbg: Debugger): DataProcessor = { + copy(dp = dp.withDebugger(dbg)) + } + private def newDebugger(dr: DebuggerRunner) = { val runner = dr match { case tdr: TraceDebuggerRunner => new STraceDebuggerRunner() diff --git a/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestCustomDebuggerAPI.scala b/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestCustomDebuggerAPI.scala new file mode 100644 index 0000000..dcc35e8 --- /dev/null +++ b/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestCustomDebuggerAPI.scala @@ -0,0 +1,62 @@ +/* + * 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 org.apache.daffodil.debugger.Debugger +import org.apache.daffodil.processors.parsers.PState +import org.apache.daffodil.processors.parsers.Parser +import org.apache.daffodil.sapi.Daffodil +import org.apache.daffodil.sapi.infoset.NullInfosetOutputter +import org.apache.daffodil.sapi.io.InputSourceDataInputStream +import org.apache.daffodil.util.Misc +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class TestCustomDebuggerAPI { + class CustomDebugger extends Debugger { + var nodes = 0 + var inited = false + var finished = false + + override def init(state: PState, processor: Parser): Unit = inited = true + override def before(state: PState, processor: Parser): Unit = nodes += 1 + override def fini(processor: Parser): Unit = finished = true + } + + @Test + def testCustomDebugger(): Unit = { + val c = Daffodil.compiler() + val dbg = new CustomDebugger() + + val schemaFile = Misc.getRequiredResource("/test/sapi/mySchema1.dfdl.xsd") + val pf = c.compileSource(schemaFile) + val dp = pf.onPath("/") + .withDebugger(dbg) + .withDebugging(true) + + val file = Misc.getRequiredResource("/test/sapi/myData.dat") + val fis = new java.io.FileInputStream(file.toURL.getFile) + val input = new InputSourceDataInputStream(fis) + dp.parse(input, new NullInfosetOutputter()) + + assertEquals(6, dbg.nodes) + assertTrue(dbg.inited) + assertTrue(dbg.finished) + } +} diff --git a/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestScalaAPI.scala b/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestScalaAPI.scala index dca0c73..45791ba 100644 --- a/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestScalaAPI.scala +++ b/daffodil-sapi/src/test/scala/org/apache/daffodil/example/TestScalaAPI.scala @@ -122,7 +122,7 @@ class TestScalaAPI { val pf = c.compileFile(schemaFile) val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) .withValidationMode(ValidationMode.Off) @@ -181,7 +181,7 @@ class TestScalaAPI { val savedParser = Channels.newChannel(is) val compiler = Daffodil.compiler() val parser = compiler.reload(savedParser) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) .withValidationMode(ValidationMode.Off) val file = getResource("/test/sapi/myData.dat") @@ -641,7 +641,7 @@ class TestScalaAPI { val pf = c.compileFile(schemaFile) val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) .withValidationMode(ValidationMode.Off) @@ -688,7 +688,7 @@ class TestScalaAPI { val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) .withExternalVariables(extVarsFile) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) .withValidationMode(ValidationMode.Off) @@ -729,7 +729,7 @@ class TestScalaAPI { val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) .withExternalVariables(extVarFile) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) .withValidationMode(ValidationMode.Off) @@ -779,7 +779,7 @@ class TestScalaAPI { val schemaFile = getResource("/test/sapi/mySchema1.dfdl.xsd") val pf = c.compileFile(schemaFile) val dp = pf.onPath("/") - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) // Serialize the parser to memory, then deserialize for parsing. val os = new ByteArrayOutputStream() @@ -816,7 +816,7 @@ class TestScalaAPI { val pf = c.compileFile(schemaFile) val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) val file = getResource("/test/sapi/myInfosetBroken.xml") @@ -1098,7 +1098,7 @@ class TestScalaAPI { val pf = c.compileFile(schemaFile) val dp1 = pf.onPath("/") val dp = reserializeDataProcessor(dp1) - .withDebugger(debugger) + .withDebuggerRunner(debugger) .withDebugging(true) val file = getResource("/test/sapi/myInfosetBroken.xml")