All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xmlcalabash.util.DefaultXMLCalabashConfigurer.scala Maven / Gradle / Ivy

package com.xmlcalabash.util

import com.jafpl.util.DefaultTraceEventManager
import com.xmlcalabash.XMLCalabash
import com.xmlcalabash.config.XMLCalabashConfigurer
import com.xmlcalabash.exceptions.XProcException
import com.xmlcalabash.model.util.XProcConstants
import net.sf.saxon.lib.{ModuleURIResolver, UnparsedTextURIResolver}
import net.sf.saxon.s9api.QName
import org.slf4j.{Logger, LoggerFactory}
import org.xml.sax.EntityResolver

import javax.xml.transform.URIResolver
import scala.collection.mutable.ListBuffer

class DefaultXMLCalabashConfigurer() extends XMLCalabashConfigurer {
  protected val logger: Logger = LoggerFactory.getLogger(this.getClass)

  override def configure(input: List[PipelineParameter]): List[PipelineParameter] = {
    val args = new ArgBundle()

    args.loadSettings()

    val searchProp = ListBuffer.empty[PipelineParameter] ++ input
    val propConfig = Option(System.getProperty("com.xmlcalabash.configFile"))

    if (propConfig.isDefined && (input collect { case opt: PipelineConfigurationFile => opt }).isEmpty) {
      searchProp += new PipelineConfigurationFile(new PipelineFilenameDocument(propConfig.get))
    }

    var loaded = false
    for (config <- searchProp.toList collect { case opt: PipelineConfigurationFile => opt }) {
      loaded = true
      config.doc match {
        case uri: PipelineURIDocument =>
          args.load(uri.value, true)
        case fn: PipelineFilenameDocument =>
          args.load(URIUtils.cwdAsURI.resolve(fn.value), true)
        case file: PipelineFileDocument =>
          args.load(file.value.toURI, true)
        case _ =>
          throw XProcException.xiThisCantHappen("Unexpected configuration file type", None)
      }
    }

    if (!loaded) {
      args.load(URIUtils.homeAsURI.resolve(".xmlcalabash"), false)
      val local = args.environmentOptions(XProcConstants.cc_load_local_config).headOption
      if (local.isEmpty || local.get.getBoolean.getOrElse(true)) {
        args.load(URIUtils.cwdAsURI.resolve(".xmlcalabash"), false)
      }
    }

    searchProp.toList ++ args.parameters
  }

  private def environmentOptions(parameters: List[PipelineParameter], name: QName): List[PipelineEnvironmentOption] = {
    parameters collect { case p: PipelineEnvironmentOption => p } filter { _.eqname == name.getEQName }
  }

  override def update(config: XMLCalabash): Unit = {
    config.traceEventManager = new DefaultTraceEventManager()
    val traces = Option(System.getProperty("com.xmlcalabash.trace")).getOrElse("")
    for (trace <- traces.split("\\s*,\\s*")) {
      if (trace.startsWith("-")) {
        config.traceEventManager.disableTrace(trace.substring(1))
      } else {
        if (trace.startsWith("+")) {
          config.traceEventManager.enableTrace(trace.substring(1))
        } else {
          config.traceEventManager.enableTrace(trace)
        }
      }
    }

    val resolver = new XProcURIResolver(config)
    config.uriResolver = loadResolver(environmentOptions(config.parameters, XProcConstants.cc_uri_resolver).headOption, resolver).asInstanceOf[URIResolver]
    config.entityResolver = loadResolver(environmentOptions(config.parameters, XProcConstants.cc_entity_resolver).headOption, resolver).asInstanceOf[EntityResolver]
    config.unparsedTextURIResolver = loadResolver(environmentOptions(config.parameters, XProcConstants.cc_unparsed_text_uri_resolver).headOption, resolver).asInstanceOf[UnparsedTextURIResolver]
    config.moduleURIResolver = loadResolver(environmentOptions(config.parameters, XProcConstants.cc_module_uri_resolver).headOption, resolver).asInstanceOf[ModuleURIResolver]

    // FIXME: support an alternate error listener (maybe)
    config.errorListener = new DefaultErrorListener()

    config.errorExplanation = new DefaultErrorExplanation()
    config.documentManager = new DefaultDocumentManager(config)
  }

  private def loadResolver(opt: Option[PipelineEnvironmentOption], default: XProcURIResolver): Any = {
    try {
      if (opt.isDefined && opt.get.getString.isDefined) {
        Class.forName(opt.get.getString.get).getDeclaredConstructor().newInstance()
      } else {
        default
      }
    } catch {
      case ex: Exception =>
        logger.error(s"Failed to instantiate resolver ${opt.get.getString.get}: ${ex.getMessage}")
        default
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy