blob: 4cb03eb94ab5583da7f67f6b73caf7cabf558088 [file] [log] [blame]
package edu.illinois.ncsa.daffodil.dsom
/* Copyright (c) 2012-2013 Tresys Technology, LLC. All rights reserved.
*
* Developed by: Tresys Technology, LLC
* http://www.tresys.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal with
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of Tresys Technology, nor the names of its contributors
* may be used to endorse or promote products derived from this Software
* without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
* SOFTWARE.
*/
import edu.illinois.ncsa.daffodil.xml._
import edu.illinois.ncsa.daffodil.processors._
import edu.illinois.ncsa.daffodil.processors.xpath._
import junit.framework.Assert._
import edu.illinois.ncsa.daffodil.processors._
import edu.illinois.ncsa.daffodil.compiler._
import edu.illinois.ncsa.daffodil.processors.WithParseErrorThrowing
import org.junit.Test
import edu.illinois.ncsa.daffodil.Implicits._
import edu.illinois.ncsa.daffodil.util.Misc
import edu.illinois.ncsa.daffodil.api._
import edu.illinois.ncsa.daffodil.util.SchemaUtils
/**
* Tests for compiler-oriented XPath interface aka CompiledExpression
*/
class TestCompiledExpression2 extends WithParseErrorThrowing {
val xsd = XMLUtils.XSD_NAMESPACE
val dfdl = XMLUtils.DFDL_NAMESPACE
val xsi = XMLUtils.XSI_NAMESPACE
val example = XMLUtils.EXAMPLE_NAMESPACE
val dafint = XMLUtils.DAFFODIL_INTERNAL_NAMESPACE
var context: SchemaComponent = null
/**
* Test the XPath evaluator, but provide namespace information on the XML
*/
@Test def testCompiledAbsolutePathEvaluation2_withNamespace() {
val testSchema = SchemaUtils.dfdlTestSchema(
<dfdl:format xmlns={ example } xmlns:tns={ example } ref="tns:daffodilTest1"/>,
<xs:element name="root" type="xs:string"/>)
val origInfoset = <tns:root xmlns={ example } xmlns:tns={ example } xmlns:dafint={ dafint }>19</tns:root>
val c = new Compiler()
val (sset, pf) = c.compileInternal(Seq.empty, testSchema)
val infoset = sset.getSCIDAugmentedInfoset(origInfoset)
val edecl = sset.getGlobalElementDecl(example, "root").get.forRoot()
val doc = new org.jdom.Document(infoset) // root must have a document node
val root = new InfosetElement(doc.getRootElement())
val dummyState = PState.createInitialState(sset.schemaComponentRegistry, edecl, "", 0, Fakes.fakeDP)
val ec = new ExpressionCompiler(edecl)
val xpathString = "{ /tns:root/text() }"
val compiled = ec.compile(ConvertToType.String, Found(xpathString, edecl)) // as a string
val R(result, _) = compiled.evaluate(root, new VariableMap(), dummyState)
assertEquals("19", result)
}
@Test def testCompiledRelativePathEvaluation5_WithNamespaces() {
// Note Use of target namespace here.
// Note that tns is bound to the same namespace as the target namespace
// The relative path used below has a QName in it that uses this tns qualification.
//
// However, path evaluation seems to miss this, and the test fails because it doesn't find a node in the right namespace so the
// expression returns null (no nodes in the nodeset that is the result of the XPath query)
val tns = example
val testSchema = SchemaUtils.dfdlTestSchema(
<dfdl:format xmlns={ example } xmlns:tns={ example } ref="tns:daffodilTest1"/>,
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="e1" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="2"/>
<xs:element name="e2" type="xs:string" dfdl:inputValueCalc="{ ../e1 }"/>
</xs:sequence>
</xs:complexType>
</xs:element>)
// Note that we specify the namespace of the unqualified elements here, and it matches
// the target namespace.
val origInfoset = <data xmlns={ example } xmlns:dafint={ dafint }><e1>42</e1><e2/></data>
val c = new Compiler()
val (sset, pf) = c.compileInternal(Seq.empty, testSchema)
val infoset = sset.getSCIDAugmentedInfoset(origInfoset)
//
// Note that we specify the namespace here as well.
val edecl = sset.getGlobalElementDecl(tns, "data").get.forRoot()
val ct = edecl.typeDef.asInstanceOf[ComplexTypeBase]
val seq = ct.modelGroup.asInstanceOf[Sequence]
val Seq(e1: ElementBase, e2: ElementBase) = seq.groupMembers
val ivcPrim = InputValueCalc(e2.asInstanceOf[LocalElementDecl])
val parser = ivcPrim.parser.asInstanceOf[IVCParser]
val d = Misc.stringToReadableByteChannel("xx") // it's not going to read from here.
val initialState = PState.createInitialState(sset.schemaComponentRegistry, edecl, d, Fakes.fakeDP)
val doc = new org.jdom.Document(infoset) // root must have a document node
val root = new InfosetElement(doc.getRootElement())
val rootns = root.namespace
val child2 = root.getChild("e2", rootns)
val c2state = initialState.withParent(child2)
val resState = parser.parse(c2state)
val updatedChild2 = resState.parentElement
val dataNode = updatedChild2.toXML
// println(dataNode)
val result = updatedChild2.dataValue
assertEquals("42", result)
}
/**
* Negative test. Insure we get a diagnostic that is useful.
*/
@Test def testCompiledEvaluationError_DoesntExist() {
val testSchema = SchemaUtils.dfdlTestSchema(
<dfdl:format xmlns={ example } xmlns:tns={ example } ref="tns:daffodilTest1"/>,
<xs:element name="root" type="xs:string"/>)
val origInfoset = <tns:root xmlns={ example } xmlns:tns={ example } xmlns:dafint={ dafint }>19</tns:root>
val c = new Compiler()
val (sset, pf) = c.compileInternal(Seq.empty, testSchema)
val infoset = sset.getSCIDAugmentedInfoset(origInfoset)
val edecl = sset.getGlobalElementDecl(example, "root").get.forRoot()
val doc = new org.jdom.Document(infoset) // root must have a document node
val root = new InfosetElement(doc.getRootElement())
val dummyState = PState.createInitialState(sset.schemaComponentRegistry, edecl, "", 0, Fakes.fakeDP)
context = edecl
val ec = new ExpressionCompiler(edecl)
val xpathString = "{ /tns:doesntExist/text() }"
val compiled = ec.compile(ConvertToType.String, Found(xpathString, edecl)) // as a string
val st = PState.createInitialState(sset.schemaComponentRegistry, edecl, "x", 0, Fakes.fakeDP)
withParseErrorThrowing(st) {
val e = intercept[ParseError] {
val R(res, _) = compiled.evaluate(root, new VariableMap(), dummyState)
res
}
assertTrue(e.getMessage().contains("doesntExist"))
assertTrue(e.getMessage().contains("XPathExpressionException"))
st
}
}
}