<commit_before>/**
 *  Copyright (C) 2013 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util

import org.orbeon.datatypes.LocationData
import org.orbeon.dom
import org.orbeon.oxf.xml.XMLReceiver
import org.orbeon.saxon.functions.FunctionLibrary
import org.orbeon.saxon.om
import org.orbeon.saxon.sxpath.{XPathExpression, XPathStaticContext}
import org.orbeon.xml.NamespaceMapping

// TODO: Check what really belongs to the form compilation and split out the rest.
trait StaticXPathTrait {

  // These types are temporary indirections while we have two incompatible versions of Saxon (9.1 and 10)
  type SaxonConfiguration
  type DocumentNodeInfoType
  type VirtualNodeType
  type ValueRepresentationType
  type AxisType
  type PathMapType
  type SchemaTypeType

  def PrecedingSiblingAxisType: AxisType
  def NamespaceAxisType: AxisType

  def IntegerType: SchemaTypeType

  // Used by `ShareableXPathStaticContext`
  type VariableResolver

  // Compiled expression with source information
  case class CompiledExpression(expression: XPathExpression, string: String, locationData: LocationData)

  def makeStringExpression   (expression: String): String =  "string((" + expression + ")[1])"
  // This assumes that `xs:` is in scope. It should be in practical cases but it is not correct. With XPath 3.x, could
  // we use a [`URIQualifiedName`](https://www.w3.org/TR/xpath-31/#prod-xpath31-URIQualifiedName)?
  def makeStringOptExpression(expression: String): String =  "xs:string((" + expression + ")[1])"
  def makeBooleanExpression  (expression: String): String =  "boolean(" + expression + ")"

  val GlobalConfiguration: SaxonConfiguration

  // Create and compile an expression
  def compileExpression(
    xpathString      : String,
    namespaceMapping : NamespaceMapping,
    locationData     : LocationData,
    functionLibrary  : FunctionLibrary,
    avt              : Boolean)(implicit
    logger           : IndentedLogger
  ): CompiledExpression

  def orbeonDomToTinyTree(doc: dom.Document): DocumentNodeInfoType   // `xforms-compiler`
  def tinyTreeToOrbeonDom(nodeInfo: om.NodeInfo): dom.Document       // `xforms-runtime`
  def tinyTreeToString(nodeInfo: om.NodeInfo): String                // `xforms-runtime`
  def newTinyTreeReceiver: (XMLReceiver, () => DocumentNodeInfoType) // `xforms-runtime` and `xforms-compiler` (used by orbeonDomToTinyTree)<commit_msg>For #4843: don't require in-scope namespace<commit_after>/**
 *  Copyright (C) 2013 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util

import org.orbeon.datatypes.LocationData
import org.orbeon.dom
import org.orbeon.oxf.xml.XMLReceiver
import org.orbeon.saxon.functions.FunctionLibrary
import org.orbeon.saxon.om
import org.orbeon.saxon.sxpath.{XPathExpression, XPathStaticContext}
import org.orbeon.xml.NamespaceMapping

// TODO: Check what really belongs to the form compilation and split out the rest.
trait StaticXPathTrait {

  // These types are temporary indirections while we have two incompatible versions of Saxon (9.1 and 10)
  type SaxonConfiguration
  type DocumentNodeInfoType
  type VirtualNodeType
  type ValueRepresentationType
  type AxisType
  type PathMapType
  type SchemaTypeType

  def PrecedingSiblingAxisType: AxisType
  def NamespaceAxisType: AxisType

  def IntegerType: SchemaTypeType

  // Used by `ShareableXPathStaticContext`
  type VariableResolver

  // Compiled expression with source information
  case class CompiledExpression(expression: XPathExpression, string: String, locationData: LocationData)

  def makeStringExpression   (expression: String): String =  "string((" + expression + ")[1])"
  // With XPath 3.x, we could use a [`URIQualifiedName`](https://www.w3.org/TR/xpath-31/#prod-xpath31-URIQualifiedName)
  // and `Q{http://www.w3.org/2001/XMLSchema}string((expression)[1])`.
  def makeStringOptExpression(expression: String): String =  "for $_orbeon_private in (" + expression + ")[1] return string($_orbeon_private)"
  def makeBooleanExpression  (expression: String): String =  "boolean(" + expression + ")"

  val GlobalConfiguration: SaxonConfiguration

  // Create and compile an expression
  def compileExpression(
    xpathString      : String,
    namespaceMapping : NamespaceMapping,
    locationData     : LocationData,
    functionLibrary  : FunctionLibrary,
    avt              : Boolean)(implicit
    logger           : IndentedLogger
  ): CompiledExpression

  def orbeonDomToTinyTree(doc: dom.Document): DocumentNodeInfoType   // `xforms-compiler`
  def tinyTreeToOrbeonDom(nodeInfo: om.NodeInfo): dom.Document       // `xforms-runtime`
  def tinyTreeToString(nodeInfo: om.NodeInfo): String                // `xforms-runtime`
  def newTinyTreeReceiver: (XMLReceiver, () => DocumentNodeInfoType) // `xforms-runtime` and `xforms-compiler` (used by orbeonDomToTinyTree)
{'fraction_non_alphanumeric': 0.08352706741946198, 'fraction_numerical': 0.007638658253072069, 'mean_word_length': 4.143467122117848, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 5, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3440457', 'n_tokens_mistral': 1751, 'n_tokens_neox': 1693, 'n_words': 558}