buildscript {
  repositories {
    mavenLocal()
    mavenCentral()
    maven { url "https://dev.saxonica.com/maven" }
  }

  configurations.all {
    resolutionStrategy {
      force 'xml-apis:xml-apis:1.4.01',
        "net.sf.saxon:Saxon-HE:${saxonVersion}",
        "org.xmlresolver:xmlresolver:${resolverVersion}",
        'com.nwalsh:sinclude:4.1.0'
    }
  }

  dependencies {
    classpath group: "net.sf.saxon", name: "Saxon-HE", version: saxonVersion
    classpath group: 'org.docbook', name: 'docbook-xslTNG', version: xslTNGversion
  }
}

plugins {
  id "java"
  id "maven-publish"
  id "signing"
  id 'com.nwalsh.gradle.saxon.saxon-gradle' version '0.9.3'
  id 'com.nwalsh.gradle.relaxng.validate' version '0.0.8'
  id 'com.nwalsh.gradle.relaxng.translate' version '0.0.8'
}

import static groovy.io.FileType.FILES
import static groovy.io.FileType.DIRECTORIES
import com.nwalsh.gradle.saxon.SaxonXsltTask
import com.nwalsh.gradle.relaxng.validate.RelaxNGValidateTask
import com.nwalsh.gradle.relaxng.translate.RelaxNGTranslateTask
import com.nwalsh.gradle.relaxng.util.CollectingErrorHandler

repositories {
  mavenLocal()
  mavenCentral()
}

configurations.all {
  resolutionStrategy {
    force 'xml-apis:xml-apis:1.4.01',
      "org.xmlresolver:xmlresolver:${resolverVersion}",
      "net.sf.saxon:Saxon-HE:${saxonVersion}"
  }
}

configurations {
  validateRuntime.extendsFrom implementation
  transform.extendsFrom documentation
}

dependencies {
  implementation (
    [group: 'net.sf.saxon', name: 'Saxon-HE', version: saxonVersion],
    [group: 'org.relaxng', name: 'jing', version: "20181222" ],
    [group: 'org.relaxng', name: 'trang', version: "20181222" ],
    [group: 'org.xmlresolver', name: 'xmlresolver', version: resolverVersion]
  )
  documentation (
    [group: 'org.docbook', name: 'docbook-xslTNG', version: xslTNGversion]
  )
}

sourceSets {
  docbook {
    java {
    }
  }
  publishers {
    java {
    }
  }
}

saxon.configure {
  classpath configurations.transform
  initializer 'org.docbook.xsltng.extensions.Register'
}

println("Building with Java version ${System.getProperty('java.version')}")

def nextReleaseVer = dbver
if (nextReleaseVer.indexOf("a") > 0) {
  nextReleaseVer = nextReleaseVer.substring(0, nextReleaseVer.indexOf("a"))
}
if (nextReleaseVer.indexOf("b") > 0) {
  nextReleaseVer = nextReleaseVer.substring(0, nextReleaseVer.indexOf("b"))
}

defaultTasks 'dist'

def gitRef() {
  def ref = ""
  def proc = "git rev-parse --short --verify HEAD".execute()
  proc.in.eachLine { line ->
    ref = line
  }
  proc.err.eachLine { line ->
    println(line)
  }
  proc.waitFor()
  ref
}

def titles = [
  "assembly": "DocBook Assembly V${dbver}",
  "assemblyxi": "DocBook Assembly XIncludeV${dbver}",
  "dbforms": "DocBook Forms V${dbver}",
  "dbits": "DocBook ITS V${dbver}",
  "dbitsxi": "DocBook ITS XInclude V${dbver}",
  "defguide": "DocBook Def. GuideV${dbver}",
  "docbook": "DocBook V${dbver}",
  "docbookxi": "DocBook XInclude V${dbver}",
  "publishers": "DocBook Publishers V${dbver}",
  "sdocbook": "Simplified DocBook V${dbver}",
  "slides": "DocBook Slides V${dbver}-1",
  "slides-full": "DocBook Slides Full V${dbver}",
  "website": "DocBook Wesite V${dbver}-1",
  "website-full": "DocBook Wesite Full V${dbver}"
]

task makeSchemas() {
  // nop, just something to hang dependencies on
}

task make_rnd() {
  // nop, just something to hang dependencies on
}

task pass_tests() {
  // nop, just something to hang dependencies on
}

task fail_tests() {
  // nop, just something to hang dependencies on
}

test.dependsOn "pass_tests"
test.dependsOn "fail_tests"

// In this project, we have schemas divided into "packages" in a way
// that's roughly analogous to Java packages. Roughly. This map let's
// us easily get from a schema name (say "assembly") back to the package
// it belongs in ("docbook").
def packageMap = [:]

// For every schema, create a task to transform it from RNC to RNG.
// There's no 'defguide' directory anymore because we can manufacture
// it entirely in the build. But we still need some of the tasks
// created in this loop, so fake it.
def schemaDirectories = ["${projectDir}/src/defguide/relaxng/defguide"]
new File("${projectDir}/src").traverse([maxDepth: 2, type: DIRECTORIES]) { schema ->
  def dirname = schema.toString()
  if (!dirname.startsWith("${projectDir}/src/test/")) {
    def pos = dirname.indexOf("${File.separator}relaxng${File.separator}")
    if (pos >= 0) {
      packageMap[schema.getName()] = dirname.substring("${projectDir}".length()+5, pos)
      schemaDirectories.add(dirname)
    }
  }
}

schemaDirectories.each { dirname ->
  def pos = dirname.indexOf("${File.separator}relaxng${File.separator}")
  def basename = dirname.substring(pos+9)

  Task t = null
  if (basename != "defguide") {
    t = task "${basename}_rng_src"(type: RelaxNGTranslateTask) {
      inputs.files fileTree(dir: dirname)
      input "${dirname}/${basename}.rnc"
      output "${buildDir}/${basename}/${basename}.rng"
    }
  }

  t = task "${basename}_rng_include"(type: SaxonXsltTask,
                                     dependsOn: ["${basename}_rng_src"]) {
    inputs.file("${projectDir}/tools/include.xsl")
    input "${buildDir}/${basename}/${basename}.rng"
    output "${buildDir}/tmp/${basename}_rng_include.xml"
    stylesheet "${projectDir}/tools/include.xsl"
  }

  t = task "${basename}_rng_augment"(type: SaxonXsltTask,
                                     dependsOn: [ "${basename}_rng_include" ]) {
    inputs.file("${projectDir}/tools/augment.xsl")
    input "${buildDir}/tmp/${basename}_rng_include.xml"
    output "${buildDir}/tmp/${basename}_rng_augment.xml"
    stylesheet "${projectDir}/tools/augment.xsl"
  }

  t = task "${basename}_rng_cleanup"(type: SaxonXsltTask,
                                     dependsOn: [ "${basename}_rng_augment" ]) {
    inputs.file("${projectDir}/tools/cleanup.xsl")
    input "${buildDir}/tmp/${basename}_rng_augment.xml"
    output "${buildDir}/tmp/${basename}_rng_cleanup.xml"
    stylesheet "${projectDir}/tools/cleanup.xsl"
  }

  t = task "${basename}_rng_nodoc"(type: SaxonXsltTask,
                                   dependsOn: [ "${basename}_rng_cleanup" ]) {
    inputs.file("${projectDir}/tools/removedoc.xsl")
    input "${buildDir}/tmp/${basename}_rng_cleanup.xml"
    output "${buildDir}/tmp/${basename}_rng_nodoc.xml"
    stylesheet "${projectDir}/tools/removedoc.xsl"
    parameters (
      "remove-schematron": "0"
    )
  }

  t = task "${basename}_sch"(type: SaxonXsltTask,
                             dependsOn: [ "${basename}_rng_cleanup" ]) {
    inputs.file("${projectDir}/tools/schematron.xsl")
    input "${buildDir}/tmp/${basename}_rng_cleanup.xml"
    output "${buildDir}/schemas/sch/${packageMap[basename]}/${basename}.sch"
    stylesheet "${projectDir}/tools/schematron.xsl"
  }

  t = task "${basename}_compiled"(type: SaxonXsltTask,
                                  dependsOn: ["${basename}_rng_nodoc"]) {
    doFirst {
      copy {
        from "${projectDir}/src/${packageMap[basename]}/relaxng/${basename}"
        include "copyright.xml"
        into "${buildDir}/${basename}"
        filter { String line ->
          if (line.indexOf("{\$release}") >= 0) {
            line = line
              .replace("{\$release}", titles[basename])
          }
          line
        }
      }
    }

    input "${buildDir}/tmp/${basename}_rng_nodoc.xml"
    output "${buildDir}/tmp/${basename}_compiled.rng"
    stylesheet "${projectDir}/tools/attach-copyright.xsl"
    parameters (
      "copyright": "${buildDir}/${basename}/copyright.xml"
    )
  }

  t = task "${basename}_rnc"(type: RelaxNGTranslateTask,
                             dependsOn: ["${basename}_compiled"]) {
    input "${buildDir}/tmp/${basename}_compiled.rng"
    output "${buildDir}/schemas/rng/${packageMap[basename]}/${basename}.rnc"
  }

  t = task "${basename}_rng"(type: RelaxNGTranslateTask,
                             dependsOn: ["${basename}_rnc"]) {
    input "${buildDir}/schemas/rng/${packageMap[basename]}/${basename}.rnc"
    output "${buildDir}/schemas/rng/${packageMap[basename]}/${basename}.rng"
  }
  if (basename != "defguide") {
    makeSchemas.dependsOn t
    test.dependsOn t
  }

  t = task "${basename}_rnd"(type: SaxonXsltTask,
                             dependsOn: ["${basename}_rng_cleanup"]) {
    input "${buildDir}/tmp/${basename}_rng_cleanup.xml"
    output "${buildDir}/tmp/${basename}.rnd"
    stylesheet "${projectDir}/tools/rngdocxml.xsl"
    parameters (
      "buildhash": gitRef()
    )
  }
  make_rnd.dependsOn t

  if (file("${projectDir}/src/${basename}/xml/release-notes.xml").exists()) {
    Task r = task "copy_${basename}_resources"() {
      outputs.files
        fileTree(dir: "${buildDir}/stage/${basename}-${dbver}/release-notes")
      def dbjar = null
      configurations.transform.each { path ->
        if (path.toString().contains("docbook-xslTNG")) {
          dbjar = path
        }
      }

      doLast {
        if (dbjar == null) {
          throw new GradleException("Failed to locate DocBook xslTNG jar file")
        }
        copy {
          into "${buildDir}/stage/${basename}-${dbver}/release-notes"
          from ({ zipTree(dbjar.toString()) }) {
            include "org/docbook/xsltng/resources/**"
          }
          eachFile { fileCopyDetails ->
            def originalPath = fileCopyDetails.path
            fileCopyDetails.path
              = originalPath.replace('org/docbook/xsltng/resources/', '')
          }
        }
      }

      doLast {
        copy {
          into "${buildDir}/stage/${basename}-${dbver}/release-notes"
          from "${projectDir}/src/${basename}/xml"
          include "release-notes.xml"
        }
      }

      doLast {
        delete "${buildDir}/stage/${basename}-${dbver}/release-notes/org"
      }
    }

    t = task "${basename}_release_notes"(
      type: SaxonXsltTask
    ) {
      input "${projectDir}/src/${basename}/xml/release-notes.xml"
      output "${buildDir}/stage/${basename}-${dbver}/release-notes/index.html"
      stylesheet "${projectDir}/tools/docbook.xsl"
      parameters (
      )
    }
    t.dependsOn r
  }
}

task any_docbook_rng(type: SaxonXsltTask,
                     dependsOn: [ "docbook_compiled" ]) {
  input "${buildDir}/tmp/docbook_compiled.rng"
  output "${buildDir}/docbook/any.docbook.rng"
  stylesheet "${projectDir}/tools/all-patterns.xsl"
}

task defguide_rng_src(dependsOn: ["any_docbook_rng", "assembly_rng", "docbook_rng"]) {
  doLast {
    // The defguide.rng file is just a driver that combines 
    // a few schemas together for documentation purposes.
    // it doesn't exist to perform validation of any sort.
    def rng = new PrintStream(new File("${buildDir}/defguide/defguide.rng"))
    rng.println("<?xml version='1.0' encoding='UTF-8'?>")
    rng.println("<grammar ns='http://docbook.org/ns/docbook'")
    rng.println("         xmlns='http://relaxng.org/ns/structure/1.0'>")
    rng.println("  <include href='../docbook/docbook.rng'>")
    rng.println("    <start combine='choice'>")
    rng.println("      <ref name='db.assembly'/>")
    rng.println("    </start>")
    rng.println("  </include>")
    rng.println("  <include href='../docbook/any.docbook.rng'/>")
    rng.println("  <include href='../assembly/assembly-core.rng'/>")
    rng.println("</grammar>")
    rng.close()
  }
  doFirst {
    mkdir "${buildDir}/defguide"
  }
}

// ============================================================
// Create tasks to run all of the tests
def baseTests = [:]
def failResults = [:]
fileTree(dir: "${projectDir}/src/test").each { testfile ->
  def pos = projectDir.toString().length() + "/src/test/".length()
  def fn = testfile.toString().substring(pos)
  if (fn.endsWith(".xml")) {
    def taskName = fn.replace("${File.separator}", "_").replace(".", "_").replace("-","_")    
    def parts = fn.split("[/\\\\]") // e.g., docbook/pass/testname.xml
    def schema_name = parts[1]
    def passfail = parts[2]
    def document = testfile.toString()

    if (!baseTests.containsKey(schema_name)) {
      baseTests[schema_name] = task "${schema_name}_tests"() { }
    }

    if (passfail == "pass") {
      Task t = task "test_${taskName}_rng"(type: RelaxNGValidateTask,
                                           dependsOn: ["${schema_name}_rng"]) {
        input document
        output "${buildDir}/test/rng/${fn}"
        schema "${buildDir}/schemas/rng/${packageMap[schema_name]}/${schema_name}.rng"
        errorHandler new CollectingErrorHandler(System.err)
        idref (schema_name != 'website' && schema_name != 'website-full' && schema_name != 'dbforms')
        assertValid true
      }
      pass_tests.dependsOn t
      baseTests[schema_name].dependsOn t

      t = task "test_${taskName}_sch"(type: RelaxNGValidateTask,
                                      dependsOn: ["${schema_name}_sch"]) {
        input document
        output "${buildDir}/test/sch/${fn}"
        schema "${buildDir}/schemas/sch/${packageMap[schema_name]}/${schema_name}.sch"
        errorHandler new CollectingErrorHandler(System.err)
        idref (schema_name != 'website' && schema_name != 'website-full' && schema_name != 'dbforms')
        assertValid true
      }
      pass_tests.dependsOn t
      baseTests[schema_name].dependsOn t

    } else if (passfail == "fail") {
      Task t_rng = task "test_${taskName}_rng"(type: RelaxNGValidateTask,
                                               dependsOn: ["${schema_name}_rng"]) {
        def eh = new CollectingErrorHandler()
        input document
        schema "${buildDir}/schemas/rng/${packageMap[schema_name]}/${schema_name}.rng"
        output "${buildDir}/test/rng/${fn}"
        assertValid false
        errorHandler eh
        doLast {
          println("TEST test_${taskName}_rng: ${eh.errorCount()} errors")
          failResults["${taskName}_rng"] = eh.errorCount() == 0
        }
      }

      Task t_sch = task "test_${taskName}_sch"(type: RelaxNGValidateTask,
                                               dependsOn: ["${schema_name}_sch"]) {
        def eh = new CollectingErrorHandler()
        input document
        schema "${buildDir}/schemas/sch/${packageMap[schema_name]}/${schema_name}.sch"
        output "${buildDir}/test/sch/${fn}"
        assertValid false
        errorHandler eh
        doLast {
          println("TEST test_${taskName}_sch: ${eh.errorCount()} errors")
          failResults["${taskName}_sch"] = eh.errorCount() == 0
        }
      }

      Task t = task "test_${taskName}"(dependsOn: ["test_${taskName}_rng",
                                                   "test_${taskName}_sch"]) {
        doLast {
          // If both the Schematron test and the RELAX NG test passed, then fail!
          if (failResults["${taskName}_sch"] && failResults["${taskName}_rng"]) {
            throw new GradleException("Test should not have passed")
          }
        }
      }

      fail_tests.dependsOn t
      baseTests[schema_name].dependsOn t
    } else {
      println("Ignoring test file: ${fn}")
    }
  }
}

// ============================================================

def distributions = [
  "docbook": ["dependsOn": ["docbook_rng", "docbookxi_rng", "assembly_rng",
                            "assemblyxi_rng", "dbits_rng", "dbitsxi_rng",
                            "docbook_sch", "docbookxi_sch", "assembly_sch",
                            "assemblyxi_sch", "dbits_sch", "dbitsxi_sch",
                            "assembly_tests", "docbook_tests", "docbookxi_tests",
                            "dbits_tests", "dbitsxi_tests"],
              "schemas": ["docbook", "dbits", "assembly"]],
  "publishers": ["dependsOn": ["publishers_rng", "publishers_sch", "publishers_tests"],
                 "schemas": ["publishers"]],
  "sdocbook": ["dependsOn": ["sdocbook_rng", "sdocbook_sch", "sdocbook_tests"],
               "schemas": ["sdocbook"]],
  "slides": ["dependsOn": ["slides_rng", "slides_sch", "slides-full_rng",
                           "slides-full_sch", "slides_tests", "slides-full_tests"],
             "schemas": ["slides", "slides-full"]],
  "website": ["dependsOn": ["website_rng", "website_sch", "website-full_rng",
                            "website-full_sch", "website_tests", "website-full_tests"],
              "schemas": ["website", "website-full"]],
  "dbforms": ["dependsOn": ["dbforms_rng", "dbforms_sch", "dbforms_tests"],
               "schemas": ["dbforms"]]]

distributions.each { dist, obj ->
  task "${dist}_stage"(dependsOn: distributions[dist]["dependsOn"]) {
    ["rng", "sch"].each { lang ->
      distributions[dist]["schemas"].each { schema ->
        doFirst {
          copy {
            from "${buildDir}/schemas/${lang}/${schema}"
            into "${buildDir}/stage/${dist}-${dbver}/${lang}"
          }
        }
      }
    }

    distributions[dist]["schemas"].each { schema ->
      doFirst {
        copy {
          from "${projectDir}/src/${packageMap[schema]}/nvdl/${schema}"
          into "${buildDir}/stage/${dist}-${dbver}"
        }
      }
    }

    doLast {
      def list = new PrintStream(new File("${buildDir}/tmp/${dist}.uris"))
      def path = "${buildDir}/stage/${dist}-${dbver}"
      new File(path).traverse([maxDepth: 2, type: FILES]) { schema ->
        if (schema.getName() != "catalog.xml") {
          list.println(schema.toString().substring(path.length()+1))
        }
      }
      list.close()
    }
  }

  task "${dist}_catalog"(type: SaxonXsltTask, dependsOn: ["${dist}_stage"]) {
    def path = "${buildDir}/stage/${dist}-${dbver}"

    def catalogParameters = [
      'title': "XML Catalog for ${titles[dist]}",
      'version': dbver,
      'distribution': dist,
      'uris': "${buildDir}/tmp/${dist}.uris"
    ]

    if (dist == "docbook") {
      catalogParameters['oasisVersion'] = oasisDocBookVersion
      catalogParameters['oasisRelease'] = oasisDocBookRelease
    }

    if (dist == "publishers") {
      catalogParameters['oasisVersion'] = oasisPublishersVersion
      catalogParameters['oasisRelease'] = oasisPublishersRelease
      catalogParameters['prefix'] = 'publishers'
    }

    input "${projectDir}/tools/catalog.xsl"
    output "${path}/catalog.xml"
    stylesheet "${projectDir}/tools/catalog.xsl"
    parameters catalogParameters
  }

  Task zip = task "${dist}_zip"(type: Zip, dependsOn: ["${dist}_catalog"]) {
    from("${buildDir}/stage/${dist}-${dbver}")
    into "${dist}-${dbver}"
    archiveFileName = "${dist}-${dbver}.zip"
    doFirst {
      mkdir "${buildDir}/distributions"
    }
  }

  if (tasks.findByName("${dist}_release_notes") != null) {
    zip.dependsOn tasks.findByName("${dist}_release_notes")
  }
}

// ============================================================

task dist() {
  dependsOn "assemble"
  distributions.each { dist, obj ->
    dependsOn "${dist}_zip"
  }
}

// ============================================================

task docbook_javaConfig() {
  def jver = ""
  def java = "${projectDir}/src/docbook/java/org/docbook/schemas/docbook/DocBook.java"
  try (BufferedReader br = new BufferedReader(new FileReader(java))) {
    jver = br.readLine()
    while (jver != null) {
      if (jver.contains("VERSIONS")) {
        jver = jver.split("\s*=\s")[1]
        break;
      }
      jver = br.readLine()
    }
  }
  def expect = "{'4.5', '5.0', '5.1', '${dbver}'};".replace('\'', '"')
  if (jver != expect) {
    throw new GradleException("Check VERSIONS in DocBook.java; ${expect} != ${jver}")
  }
}

task docbook_jarSetup(dependsOn: ["docbook_stage", "docbook_catalog", "docbook_javaConfig"]) {
  doLast {
    copy {
      into "${buildDir}/stage-jar/docbook-${dbver}/org/docbook/schemas/docbook"
      from ("${projectDir}/src/docbook/schemas") {
        exclude "catalog.src"
      }
    }
  }

  doLast {
    copy {
      into "${buildDir}/stage-jar/docbook-${dbver}/org/docbook/schemas/docbook/${dbver}"
      from "${buildDir}/stage/docbook-${dbver}"
    }
  }

  doLast {
    copy {
      into "${buildDir}/stage-jar/docbook-${dbver}/org/docbook/schemas/docbook"
      from ("${projectDir}/src/docbook/schemas") {
        include "catalog.src"
      }
      rename { fn ->
        return "catalog.xml"
      }
      filter { String line ->
        line.replace("@@DBVER@@", dbver)
      }
    }
  }
}

task docbook_jarCatalog(type: SaxonXsltTask, dependsOn: ["docbook_jarSetup"]) {
  input "${buildDir}/stage-jar/docbook-${dbver}/org/docbook/schemas/docbook/${dbver}/catalog.xml"
  stylesheet "${projectDir}/tools/resolver-catalog.xsl"
  output "${buildDir}/stage-jar/docbook-${dbver}/org/xmlresolver/catalog.xml"
  parameters (
    'schema': 'docbook',
    'version': dbver
  )
}

// I'd make this a task called docbook_jar except that a default 'jar' task
// always runs. That creates an empty 'docbook.jar'. So this avoids that.
jar {
  dependsOn "compileDocbookJava"
  dependsOn "docbook_jarCatalog"
  from ("${buildDir}/stage-jar/docbook-${dbver}")
  from ("${buildDir}/classes/java/docbook")
  include("*/**")
  archiveBaseName = "docbook-${dbver}"
  manifest {
    attributes "Built-By": "Norman Walsh"
    attributes "Implementation-Vendor": "Norman Walsh"
    attributes "Implementation-Title": "DocBook Schemas"
    attributes "Implementation-Version": dbver
  }
}

task docbook_javadoc(type: Javadoc) {
  destinationDir = new File("${buildDir}/docs/docbook")
  source = sourceSets.docbook.allJava
  doFirst {
    mkdir("${buildDir}/docs/docbook")
  }
}

task docbook_javadocJar(type: Jar, dependsOn: ["docbook_javadoc"]) {
  archiveBaseName = "docbook-${dbver}"
  archiveClassifier = 'javadoc'
  from docbook_javadoc.destinationDir
}
assemble.dependsOn docbook_javadocJar

task docbook_sourcesJar(type: Jar) {
  archiveBaseName = "docbook-${dbver}"
  archiveClassifier = 'sources'
  from sourceSets.docbook.allSource
}
assemble.dependsOn docbook_sourcesJar

// ============================================================

task publishers_javaConfig() {
  def jver = ""
  def java = "${projectDir}/src/publishers/java/org/docbook/schemas/publishers/Publishers.java"
  try (BufferedReader br = new BufferedReader(new FileReader(java))) {
    jver = br.readLine()
    while (jver != null) {
      if (jver.contains("VERSIONS")) {
        jver = jver.split("\s*=\s")[1]
        break;
      }
      jver = br.readLine()
    }
  }
  def expect = "{'1.0', '${dbver}'};".replace('\'', '"')
  if (jver != expect) {
    throw new GradleException("Check VERSIONS in Publishers.java; ${expect} != ${jver}")
  }
}

task publishers_jarSetup(dependsOn: ["publishers_stage", "publishers_catalog", "publishers_javaConfig"]) {
  doLast {
    copy {
      into "${buildDir}/stage-jar/publishers-${dbver}/org/docbook/schemas/publishers"
      from ("${projectDir}/src/publishers/schemas") {
        exclude "catalog.src"
      }
    }
  }

  doLast {
    copy {
      into "${buildDir}/stage-jar/publishers-${dbver}/org/docbook/schemas/publishers/${dbver}"
      from "${buildDir}/stage/publishers-${dbver}"
    }
  }

  doLast {
    copy {
      into "${buildDir}/stage-jar/publishers-${dbver}/org/docbook/schemas/publishers"
      from ("${projectDir}/src/publishers/schemas") {
        include "catalog.src"
      }
      rename { fn ->
        return "catalog.xml"
      }
      filter { String line ->
        line.replace("@@DBVER@@", dbver)
      }
    }
  }
}

task publishers_jarCatalog(type: SaxonXsltTask, dependsOn: ["publishers_jarSetup"]) {
  input "${buildDir}/stage-jar/publishers-${dbver}/org/docbook/schemas/publishers/${dbver}/catalog.xml"
  stylesheet "${projectDir}/tools/resolver-catalog.xsl"
  output "${buildDir}/stage-jar/publishers-${dbver}/org/xmlresolver/catalog.xml"
  parameters (
    'schema': 'publishers',
    'version': dbver
  )
}

task publishers_jar(type: Jar, dependsOn: ["compilePublishersJava", "publishers_jarCatalog"]) {
  from ("${buildDir}/stage-jar/publishers-${dbver}")
  from ("${buildDir}/classes/java/publishers")
  include("*/**")
  archiveBaseName = "publishers-${dbver}"
  manifest {
    attributes "Built-By": "Norman Walsh"
    attributes "Implementation-Vendor": "Norman Walsh"
    attributes "Implementation-Title": "DocBook Publishers Schemas"
    attributes "Implementation-Version": dbver
  }
}
assemble.dependsOn publishers_jar

task publishers_javadoc(type: Javadoc) {
  destinationDir = new File("${buildDir}/docs/publishers")
  source = sourceSets.publishers.allJava
  doFirst {
    mkdir("${buildDir}/docs/publishers")
  }
}

task publishers_javadocJar(type: Jar, dependsOn: ["publishers_javadoc"]) {
  archiveBaseName = "publishers-${dbver}"
  archiveClassifier = 'javadoc'
  from publishers_javadoc.destinationDir
}
assemble.dependsOn publishers_javadocJar

task publishers_sourcesJar(type: Jar) {
  archiveBaseName = "publishers-${dbver}"
  archiveClassifier = 'sources'
  from sourceSets.publishers.allSource
}
assemble.dependsOn publishers_sourcesJar

signing {
  sign publishing.publications
}

publishing {
  publications {
    docbookJava(MavenPublication) {
      pom {
        name = 'DocBook Schemas'
        packaging = 'jar'
        description = 'The DocBook schemas'
        url = 'https://github.com/docbook/docbook'

        scm {
          url = 'scm:git@github.com:docbook/docbook.git'
          connection = 'scm:git@github.com:docbook/docbook.git'
          developerConnection = 'scm:git@github.com:docbook/docbook.git'
        }

        licenses {
          license {
            name = 'Apache License version 2.0'
            url = 'https://www.apache.org/licenses/LICENSE-2.0'
            distribution = 'repo'
          }
        }

        developers {
          developer {
            id = 'ndw'
            name = 'Norman Walsh'
          }
        }
      }

      groupId = "org.docbook"
      artifactId = "schemas-docbook"
      version = dbver
      artifact jar
      artifact docbook_javadocJar
      artifact docbook_sourcesJar
    }

    publishersJava(MavenPublication) {
      pom {
        name = 'DocBook Publishers Schemas'
        packaging = 'jar'
        description = 'The DocBook Publishers schemas'
        url = 'https://github.com/docbook/docbook'

        scm {
          url = 'scm:git@github.com:docbook/docbook.git'
          connection = 'scm:git@github.com:docbook/docbook.git'
          developerConnection = 'scm:git@github.com:docbook/docbook.git'
        }

        licenses {
          license {
            name = 'Apache License version 2.0'
            url = 'https://www.apache.org/licenses/LICENSE-2.0'
            distribution = 'repo'
          }
        }

        developers {
          developer {
            id = 'ndw'
            name = 'Norman Walsh'
          }
        }
      }

      groupId = "org.docbook"
      artifactId = "schemas-publishers"
      version = dbver
      artifact publishers_jar
      artifact publishers_javadocJar
      artifact publishers_sourcesJar
    }
  }

  repositories {
    maven {
      url = dbver.contains("SNAPSHOT") ?
        "https://oss.sonatype.org/content/repositories/snapshots/" :
        "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
      credentials {
        username = findProperty("sonatypeUsername") ?: ""
        password = findProperty("sonatypePassword") ?: ""
      }
    }
  }
}
println(publishing.publications)

// ============================================================

task helloWorld() {
  doLast {
    println("Hello.")
    /*
    configurations.validateRuntime.each { path ->
      println(path)
    }
    println(System.getProperty("javax.xml.transform.TransformerFactory"))
     */
  }
}
