diff --git a/.gitignore b/.gitignore index 39f4c1f4ac2..f464e64c585 100644 --- a/.gitignore +++ b/.gitignore @@ -344,3 +344,6 @@ gradle-app.setting # do not distribute Oracle's JDBC driver lib/ojdbc.jar + +# do not ignore the source of the build +!/buildSrc/src/ diff --git a/build.gradle b/build.gradle index a45f7880af2..bf20ba87fc0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ import groovy.json.JsonSlurper import org.gradle.internal.os.OperatingSystem +import org.jabref.build.xjc.XjcTask // to update the gradle wrapper, execute // ./gradlew wrapper --gradle-version=4.4.1 --distribution-type=bin @@ -35,10 +36,11 @@ apply plugin: 'jacoco' apply plugin: 'install4j' apply plugin: 'me.champeau.gradle.jmh' apply plugin: 'checkstyle' +apply plugin: org.jabref.build.antlr.AntlrPlugin +apply plugin: org.jabref.build.xjc.XjcPlugin +apply plugin: org.jabref.build.localization.LocalizationPlugin apply from: 'eclipse.gradle' -apply from: 'localization.gradle' -apply from: 'xjc.gradle' group = "org.jabref" version = "5.0-dev" @@ -81,8 +83,6 @@ repositories { } configurations { - antlr3 - antlr4 errorprone } @@ -174,6 +174,8 @@ dependencies { testCompile "org.testfx:testfx-junit5:4.0.+" checkstyle 'com.puppycrawl.tools:checkstyle:8.20' + xjc 'com.sun.xml.bind:jaxb-xjc:2.2.4-1' + jython 'org.python:jython-standalone:2.7.1' } jacoco { @@ -264,65 +266,87 @@ processResources { } -task generateSource(dependsOn: ["generateBstGrammarSource", "generateSearchGrammarSource"]) { +task generateSource(dependsOn: ["generateBstGrammarSource", + "generateSearchGrammarSource", + "generateMedlineSource", + "generateBibtexmlSource", + "generateEndnoteSource", + "generateModsSource"]) { group = 'JabRef' description 'Generates all Java source files.' } -task generateBstGrammarSource(type: JavaExec) { - group 'JabRef' - description 'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr3.' +task generateBstGrammarSource(type: org.jabref.build.antlr.AntlrTask) { + group = "JabRef" + description = 'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr3.' - File antlrSource = file('src/main/antlr3/org/jabref/bst/Bst.g') + antlr = ANTLR3 + inputFile = 'src/main/antlr3/org/jabref/bst/Bst.g' + outputDir = 'src/main/gen/org/jabref/logic/bst/' +} - inputs.file antlrSource - outputs.file file('src/main/gen/org/jabref/logic/bst/BstLexer.java') - outputs.file file('src/main/gen/org/jabref/logic/bst/BstParser.java') +task generateSearchGrammarSource(type: org.jabref.build.antlr.AntlrTask) { + group = 'JabRef' + description = "Generates java files for Search.g antlr4." - main = 'org.antlr.Tool' - classpath = configurations.antlr3 - args = ["-o", file('src/main/gen/org/jabref/logic/bst/'), antlrSource] + antlr = ANTLR4 + inputFile = "src/main/antlr4/org/jabref/search/Search.g4" + outputDir = "src/main/gen/org/jabref/search" + javaPackage = "org.jabref.search" } -task generateSearchGrammarSource(type: JavaExec) { - String grammarFile = "Search" +task generateMedlineSource(type: XjcTask) { + group = 'JabRef' + description = "Generates java files for the medline importer." - group 'JabRef' - description "Generates java files for ${grammarFile}.g antlr4." + schemaFile = "src/main/resources/xjc/medline/medline.xsd" + outputDirectory = "src/main/gen/" + javaPackage = "org.jabref.logic.importer.fileformat.medline" +} - String packagePath = "org/jabref/search" - File antlrPath = file("src/main/antlr4") - File genPath = file("src/main/gen") +task generateBibtexmlSource(type: XjcTask) { + group = 'JabRef' + description = "Generates java files for the bibtexml importer." - File antlrSource = file("$antlrPath/$packagePath/${grammarFile}.g4") - File destinationDir = file("$genPath/$packagePath") + schemaFile = "src/main/resources/xjc/bibtexml/bibtexml.xsd" + outputDirectory = "src/main/gen" + javaPackage = "org.jabref.logic.importer.fileformat.bibtexml" +} - inputs.file antlrSource - outputs.file file("$destinationDir/${grammarFile}Parser.java") - outputs.file file("$destinationDir/${grammarFile}Lexer.java") - outputs.file file("$destinationDir/${grammarFile}Visitor.java") - outputs.file file("$destinationDir/${grammarFile}BaseVisitor.java") - outputs.file file("$destinationDir/${grammarFile}.tokens") - outputs.file file("$destinationDir/${grammarFile}Lexer.tokens") +task generateEndnoteSource(type: XjcTask) { + group = 'JabRef' + description = "Generates java files for the endnote importer." - main = 'org.antlr.v4.Tool' - classpath = configurations.antlr4 - args = ["-o", destinationDir, "-visitor", "-no-listener", "-package", "org.jabref.search", antlrSource] + schemaFile = "src/main/resources/xjc/endnote/RSXML.dtd" + outputDirectory = "src/main/gen/" + javaPackage = "org.jabref.logic.importer.fileformat.endnote" + arguments = '-dtd' } -compileJava { - options.encoding = 'UTF-8' - options.compilerArgs << "-Xlint:none" - //ignore annotation processor from log4j2 - options.compilerArgs += '-proc:none' +task generateModsSource(type: XjcTask) { + group = 'JabRef' + description = "Generates java files for the mods importer." + + schemaFile = "src/main/resources/xjc/mods/mods-3-7.xsd" + bindingFile = "src/main/resources/xjc/mods/mods-binding.xjb" + outputDirectory = "src/main/gen/" + javaPackage = "org.jabref.logic.importer.fileformat.mods" + arguments = '-npa' } -compileJava.dependsOn "generateSource" -compileTestJava { +tasks.withType(JavaCompile) { + // use UTF-8 options.encoding = 'UTF-8' + + // ignore annotation processor from log4j2 options.compilerArgs += '-proc:none' } +compileJava { + options.compilerArgs << "-Xlint:none" + dependsOn "generateSource" +} + javadoc { options { encoding = 'UTF-8' @@ -331,6 +355,8 @@ javadoc { } } +localization.script = 'scripts/syncLang.py' + // Test tasks test { useJUnitPlatform { diff --git a/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr3CommandLine.groovy b/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr3CommandLine.groovy new file mode 100644 index 00000000000..48213e8f07e --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr3CommandLine.groovy @@ -0,0 +1,27 @@ +package org.jabref.build.antlr + +import org.gradle.api.file.FileCollection + +class Antlr3CommandLine implements AntlrCommandLine { + + private final task + + Antlr3CommandLine(AntlrTask task) { + this.task = task + } + + @Override + String getMain() { + return "org.antlr.Tool" + } + + @Override + FileCollection getClasspath() { + return task.project.configurations.antlr3 + } + + @Override + List getArguments() { + return ["-o", task.project.file(task.outputDir).toString(), task.project.file(task.inputFile).toString()] + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr4CommandLine.groovy b/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr4CommandLine.groovy new file mode 100644 index 00000000000..6c74a04ad88 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/antlr/Antlr4CommandLine.groovy @@ -0,0 +1,31 @@ +package org.jabref.build.antlr + +import org.gradle.api.file.FileCollection + +class Antlr4CommandLine implements AntlrCommandLine { + + private final AntlrTask task + + Antlr4CommandLine(AntlrTask task) { + this.task = task + } + + @Override + String getMain() { + return "org.antlr.v4.Tool" + } + + @Override + FileCollection getClasspath() { + return task.project.configurations.antlr4 + } + + @Override + List getArguments() { + return ["-o", file(task.outputDir), "-visitor", "-no-listener", "-package", task.javaPackage, file(task.inputFile)] + } + + private String file(String path) { + return task.project.file(path).toString() + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrCommandLine.groovy b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrCommandLine.groovy new file mode 100644 index 00000000000..bcfe0ecc371 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrCommandLine.groovy @@ -0,0 +1,16 @@ +package org.jabref.build.antlr + +import org.gradle.api.file.FileCollection + +/** + * Encapsulates a command line call to an version of the ANTLR tools. + */ +interface AntlrCommandLine { + + String getMain() + + FileCollection getClasspath() + + List getArguments() + +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrPlugin.groovy b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrPlugin.groovy new file mode 100644 index 00000000000..ce9a7301445 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrPlugin.groovy @@ -0,0 +1,23 @@ +package org.jabref.build.antlr + +import org.gradle.api.Plugin +import org.gradle.api.Project + +/** + * Configures the project for use with ANTLR 3 or 4. + */ +class AntlrPlugin implements Plugin { + + public static final def ANTLR3_CONFIGURATION_NAME = "antlr3" + public static final def ANTLR4_CONFIGURATION_NAME = "antlr4" + + @Override + void apply(Project target) { + def antlr3Cfg = target.configurations.create(ANTLR3_CONFIGURATION_NAME) + antlr3Cfg.description = "Dependencies required to run the ANTLR3 tool." + + def antlr4Cfg = target.configurations.create(ANTLR4_CONFIGURATION_NAME) + antlr4Cfg.description = "Dependencies required to run the ANTLR4 tool." + } + +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrTask.groovy b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrTask.groovy new file mode 100644 index 00000000000..6ff19a1a02f --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/antlr/AntlrTask.groovy @@ -0,0 +1,68 @@ +package org.jabref.build.antlr + +import org.gradle.api.tasks.JavaExec +import org.gradle.api.tasks.TaskAction + +class AntlrTask extends JavaExec { + + static def ANTLR3 = Antlr3CommandLine + static def ANTLR4 = Antlr4CommandLine + + private Class antlr = ANTLR3 + private String inputFile = "" + private String outputDir = "" + private String javaPackage = "" + + public AntlrTask() { + project.configurations { + antlr3 + antlr4 + } + } + + @TaskAction + @Override + void exec() { + AntlrCommandLine commandLine = antlr.newInstance(this) + + main = commandLine.main + classpath = commandLine.classpath + args = commandLine.arguments + + super.exec() + } + + Class getAntlr() { + return antlr + } + + void setAntlr(Class antlr) { + this.antlr = antlr + } + + String getInputFile() { + return inputFile + } + + void setInputFile(String inputFile) { + this.inputFile = inputFile + inputs.file(inputFile) + } + + String getOutputDir() { + return outputDir + } + + void setOutputDir(String outputDir) { + this.outputDir = outputDir + outputs.dir(outputDir) + } + + String getJavaPackage() { + return javaPackage + } + + void setJavaPackage(String javaPackage) { + this.javaPackage = javaPackage + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/localization/JythonTask.groovy b/buildSrc/src/main/groovy/org/jabref/build/localization/JythonTask.groovy new file mode 100644 index 00000000000..437083035cf --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/localization/JythonTask.groovy @@ -0,0 +1,19 @@ +package org.jabref.build.localization + +import org.gradle.api.tasks.JavaExec +import org.gradle.api.tasks.TaskAction + +class JythonTask extends JavaExec { + + + public static final String JYTHON_MAIN = 'org.python.util.jython' + + @TaskAction + @Override + void exec() { + main JYTHON_MAIN + classpath project.configurations.getByName(LocalizationPlugin.CONFIGURATION_NAME).asPath + + super.exec() + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationExtension.groovy b/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationExtension.groovy new file mode 100644 index 00000000000..e47ef5ef600 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationExtension.groovy @@ -0,0 +1,7 @@ +package org.jabref.build.localization + +class LocalizationExtension { + + def script + +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationPlugin.groovy b/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationPlugin.groovy new file mode 100644 index 00000000000..2e03f8d55e1 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/localization/LocalizationPlugin.groovy @@ -0,0 +1,66 @@ +package org.jabref.build.localization + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class LocalizationPlugin implements Plugin { + + public static final def CONFIGURATION_NAME = "jython" + public static final def TASK_GROUP = 'Localization' + + @Override + void apply(Project target) { + def configuration = target.configurations.create("jython") + configuration.description = "Dependencies needed to run jython." + + target.extensions.create('localization', LocalizationExtension) + + target.afterEvaluate { project -> + initLocalizationTasks(project, project.extensions.getByType(LocalizationExtension)) + } + } + + private def initLocalizationTasks(Project project, LocalizationExtension extension) { + project.tasks.create('localizationStatusWithMarkdown', JythonTask) { + description "Creates an update file in Markdown" + group = TASK_GROUP + + args project.file(extension.script) + args "markdown" + } + + project.tasks.create('localizationStatus', JythonTask) { + description "Prints the current status" + group = TASK_GROUP + + args project.file(extension.script) + args "status" + } + + project.tasks.create('localizationStatusExtended', JythonTask) { + description "Prints the current status (extended output)" + group = TASK_GROUP + + args project.file(extension.script) + args "status" + args "--extended" + } + + project.tasks.create('localizationUpdate', JythonTask) { + description "Updates the localization files (fixes duplicates, adds missing keys, and sort them" + group = TASK_GROUP + + args project.file(extension.script) + args "update" + } + + project.tasks.create('localizationUpdateExtended', JythonTask) { + description "Updates the localization files (fixes duplicates, adds missing keys, and sort them (extended output)" + group = TASK_GROUP + + args project.file(extension.script) + args "update" + args "--extended" + } + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcPlugin.groovy b/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcPlugin.groovy new file mode 100644 index 00000000000..72e2c3644a7 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcPlugin.groovy @@ -0,0 +1,20 @@ +package org.jabref.build.xjc + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class XjcPlugin implements Plugin { + + static final def CONFIGURATION_NAME = "xjc" + + @Override + void apply(Project target) { + def configuration = target.configurations.create(CONFIGURATION_NAME) + configuration.description = "Dependencies needed to run the XJC tool." + + target.afterEvaluate { evaluated -> + evaluated.logger.info(evaluated.configurations.xjc.asPath) + evaluated.ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: evaluated.configurations.getByName(CONFIGURATION_NAME).asPath) + } + } +} diff --git a/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcTask.groovy b/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcTask.groovy new file mode 100644 index 00000000000..bb859ea10c1 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jabref/build/xjc/XjcTask.groovy @@ -0,0 +1,93 @@ +package org.jabref.build.xjc + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction + +class XjcTask extends DefaultTask { + + private def schemaFile + @Optional + private def bindingFile + private def outputDirectory + private String javaPackage + @Optional + private String arguments + + @TaskAction + def generateClasses() { + project.mkdir(outputDirectory) + project.ant.xjc(destdir: outputDirectory, package: javaPackage) { + schema(dir: schemaFile.getParent(), includes: schemaFile.getName()) + if (bindingFile != null) { + binding(dir: bindingFile.getParent(), includes: bindingFile.getName()) + } + if (arguments != null) { + arg(value: arguments) + } + } + } + + @Input + File getSchemaFile() { + if (schemaFile == null) { + return null + } + return project.file(schemaFile) + } + + void setSchemaFile(Object schemaFile) { + this.schemaFile = schemaFile + } + + File getOutputDirectory() { + if (outputDirectory == null) { + return null + } + return project.file(outputDirectory) + } + + void setOutputDirectory(Object outputDirectory) { + this.outputDirectory = outputDirectory + updateOutput() + } + + String getJavaPackage() { + return javaPackage + } + + void setJavaPackage(String javaPackage) { + this.javaPackage = javaPackage + updateOutput() + } + + String getArguments() { + return arguments + } + + void setArguments(String args) { + this.arguments = args + } + + @Input + File getBindingFile() { + if (bindingFile == null) { + return null + } + return project.file(bindingFile) + } + + void setBindingFile(Object binding) { + this.bindingFile = binding + } + + private void updateOutput() { + if (outputDirectory != null && javaPackage != null) + outputs.dir(new File(getOutputDirectory(), packageAsPath(javaPackage))) + } + + private static String packageAsPath(String pkg) { + return pkg.replace((char) '.', File.separatorChar) + } +} diff --git a/localization.gradle b/localization.gradle deleted file mode 100644 index b41f201359f..00000000000 --- a/localization.gradle +++ /dev/null @@ -1,58 +0,0 @@ -repositories { - jcenter() -} - -configurations { - jython -} - -dependencies { - jython 'org.python:jython-standalone:2.7.1' -} - -task localizationStatusWithMarkdown(type: JavaExec) { - description "Creates an update file in Markdown" - group = 'Localization' - main 'org.python.util.jython' - classpath project.configurations.jython.asPath - args file("scripts/syncLang.py") - args "markdown" -} - -task localizationStatus(type: JavaExec) { - description "Prints the current status" - group = 'Localization' - main 'org.python.util.jython' - classpath project.configurations.jython.asPath - args file("scripts/syncLang.py") - args "status" -} - -task localizationStatusExtended(type: JavaExec) { - description "Prints the current status (extended output)" - group = 'Localization' - main 'org.python.util.jython' - classpath project.configurations.jython.asPath - args file("scripts/syncLang.py") - args "status" - args "--extended" -} - -task localizationUpdate(type: JavaExec) { - description "Updates the localization files (fixes duplicates, adds missing keys, and sort them" - group = 'Localization' - main 'org.python.util.jython' - classpath project.configurations.jython.asPath - args file("scripts/syncLang.py") - args "update" -} - -task localizationUpdateExtended(type: JavaExec) { - description "Updates the localization files (fixes duplicates, adds missing keys, and sort them (extended output)" - group = 'Localization' - main 'org.python.util.jython' - classpath project.configurations.jython.asPath - args file("scripts/syncLang.py") - args "update" - args "--extended" -} diff --git a/xjc.gradle b/xjc.gradle deleted file mode 100644 index ea33b543a03..00000000000 --- a/xjc.gradle +++ /dev/null @@ -1,41 +0,0 @@ -configurations { - xjc -} - -dependencies { - // Cannot be updated. - xjc 'com.sun.xml.bind:jaxb-xjc:2.2.4-1' -} - -task xjc { - inputs.dir "src/main/resources/xjc/medline/" - inputs.dir "src/main/resources/xjc/bibtexml/" - inputs.dir "src/main/resources/xjc/endnote/" - inputs.dir "src/main/resources/xjc/mods/" - outputs.dir "src/main/gen/org/jabref/logic/importer/fileformat/medline" - outputs.dir "src/main/gen/org/jabref/logic/importer/fileformat/bibtexml" - outputs.dir "src/main/gen/org/jabref/logic/importer/fileformat/endnote" - outputs.dir "src/main/gen/org/jabref/logic/importer/fileformat/mods" - - ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.xjc.asPath) - - doLast { - ant.xjc(destdir: 'src/main/gen/', package: 'org.jabref.logic.importer.fileformat.medline') { - schema(dir: 'src/main/resources/xjc/medline', includes: 'medline.xsd') - } - ant.xjc(destdir: 'src/main/gen/', package: 'org.jabref.logic.importer.fileformat.bibtexml') { - schema(dir: 'src/main/resources/xjc/bibtexml', includes: 'bibtexml.xsd') - } - ant.xjc(destdir: 'src/main/gen/', package: 'org.jabref.logic.importer.fileformat.endnote') { - arg(value: '-dtd') - schema(dir: 'src/main/resources/xjc/endnote', includes: 'RSXML.dtd') - } - ant.xjc(destdir: 'src/main/gen/', package: 'org.jabref.logic.importer.fileformat.mods') { - arg(value: '-npa') //don't create package-info.java because it was manually added in src/main/java to ensure the namespace prefix mapping - schema(dir: 'src/main/resources/xjc/mods', includes: 'mods-3-7.xsd') - binding(dir: 'src/main/resources/xjc/mods', includes: 'mods-binding.xjb') - } - } -} - -tasks.compileJava.dependsOn xjc