diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..fa544a0 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,44 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven +name: GitHub tagged release +on: + push: + branches: [ "master" ] + tags: [ "*" ] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Maven packages + uses: actions/cache@v2 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Install NetCDF tools + run: sudo apt install netcdf-bin + - name: Maven build + run: mvn clean package + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./binary-array-ld-cli/target/bald-cli.jar + asset_name: bald-cli.jar + asset_content_type: application/java-archive diff --git a/README.md b/README.md index aa122ce..da3d5fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Binary Array Linked Data [Kotlin](https://kotlinlang.org/) library and CLI for Binary Array Linked Data (BALD) functionality. -* NetCDF to RDF conversion according to [OGC draft specification](http://docs.opengeospatial.org/DRAFTS/19-002.html). +* [GitHub Pages](https://binary-array-ld.github.io/net.binary_array_ld.bald/) This project consists of the following modules: * **binary-array-ld-lib** Core library containing BALD functionality. In particular, binary array to linked data (RDF) conversion. @@ -11,87 +11,17 @@ RDF representations are provided by [Apache Jena](https://jena.apache.org/). * **binary-array-ld-test** Common test utilities used by other modules. * **binary-array-ld-demo** Demonstrations of BALD API usage. -## Development - -Note that, in order to run the automated tests for this project, -the `ncgen` command line tool must be available on your system. - ## Usage -This project can be used either as a library or as a command line application. - -### Library - -To use the BALD core library, add the following dependency to your Maven project: - -```xml - - net.binary-array-ld - binary-array-ld-lib - ${bald.version} - -``` - -You can implement the `net.bald.BinaryArray` interface with your own metadata representations and supply them to the API. - -For NetCDF metadata files, you can use the pre-made NetCDF implementation in the `binary-array-ld-netcdf` module. -To use this module, add the following dependency to your Maven project: +See the [GitHub pages](https://binary-array-ld.github.io/net.binary_array_ld.bald/usage.html) for usage documentation. -```xml - - net.binary-array-ld - binary-array-ld-netcdf - ${bald.version} - -``` - -#### Example -Kotlin: -```kotlin -val ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example") -val model = ModelBinaryArrayConverter.convert(ba) -File("/path/to/output.ttl").outputStream.use { output -> - model.write(output, "ttl") -} -``` -Java: -``` -BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.ttl", "http://test.binary-array-ld.net/example"); -Model model = ModelBinaryArrayConverter.convert(ba); - -try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { - model.write(output, "ttl"); -} -``` - -### Command Line Interface - -To use the BALD CLI, build the project using `mvn clean package` on the root directory. -Then, you can run the JAR located at `binary-array-ld-cli/target/bald-cli.jar` using the `java-jar` command. - -The application accepts arguments in the following format: - ``` -java -jar binary-array-ld-cli/target/bald-cli.jar [options] inputFile [outputFile] -``` -Where `inputFile` is the location of the NetCDF file to convert, -and `outputFile` is the location of the file in which to output the RDF graph. -If you don't specify an `outputFile`, the graph will be printed on the command line. - -By default, the RDF graph output will be in [Turtle](https://www.w3.org/TR/turtle/) format. -You can use the `--output` or `-o` option to specify the RDF format to emit. -This option can accept any of the RDF formats supported by Apache Jena, eg. JSON-LD and RDFXML. +## Development -You can also supply various options. -Use the `-h` or `--help` option to emit full documentation for the available options. -``` -java -jar binary-array-ld-cli/target/bald-cli.jar -h -``` +Note that, in order to run the automated tests for this project, +the `ncgen` command line tool must be available on your system. -#### Example -From the `binary-array-ld-cli/target` directory: -``` -java -jar bald-cli.jar --uri http://test.binary-array-ld.net/example /path/to/netcdf.nc /path/to/graph.ttl -``` +You can use Maven to build this project and each of its modules with `mvn clean package`. +After building, the JAR for the command line application is located at `binary-array-ld-cli/target/bald-cli.jar`. diff --git a/binary-array-ld-cli/src/main/kotlin/net/bald/BinaryArrayConvertCli.kt b/binary-array-ld-cli/src/main/kotlin/net/bald/BinaryArrayConvertCli.kt index 74603ba..f43aa97 100644 --- a/binary-array-ld-cli/src/main/kotlin/net/bald/BinaryArrayConvertCli.kt +++ b/binary-array-ld-cli/src/main/kotlin/net/bald/BinaryArrayConvertCli.kt @@ -1,7 +1,8 @@ package net.bald +import net.bald.alias.AliasDefinition import net.bald.context.ModelContext -import net.bald.model.ModelAliasDefinition +import net.bald.alias.ModelAliasDefinition import net.bald.model.ModelBinaryArrayConverter import net.bald.netcdf.NetCdfBinaryArray import org.apache.commons.cli.DefaultParser @@ -38,9 +39,10 @@ class BinaryArrayConvertCli { } private fun doRun(opts: CommandLineOptions) { - val context = context(opts.contextLocs, opts.aliasLocs) + val context = context(opts.contextLocs) + val alias = alias(opts.aliasLocs) val inputLoc = opts.inputLoc ?: throw IllegalArgumentException("First argument is required: NetCDF file to convert.") - val ba = NetCdfBinaryArray.create(inputLoc, opts.uri, context) + val ba = NetCdfBinaryArray.create(inputLoc, opts.uri, context, alias) val model = ba.use(ModelBinaryArrayConverter::convert) val outputFormat = opts.outputFormat ?: "ttl" @@ -49,15 +51,18 @@ class BinaryArrayConvertCli { } } - private fun context(contextLocs: List, aliasLocs: List): ModelContext { + private fun context(contextLocs: List): ModelContext { val prefixes = contextLocs.map { contextLoc -> ModelFactory.createDefaultModel().read(contextLoc, "json-ld") } - val alias = ModelFactory.createDefaultModel().apply { + + return ModelContext.create(prefixes) + } + + private fun alias(aliasLocs: List): AliasDefinition { + return ModelFactory.createDefaultModel().apply { aliasLocs.forEach(::read) }.let(ModelAliasDefinition::create) - - return ModelContext.create(prefixes, alias) } private fun options(opts: Options, vararg args: String): CommandLineOptions { diff --git a/binary-array-ld-demo/src/main/java/net/bald/NetCdfConvertJava.java b/binary-array-ld-demo/src/main/java/net/bald/NetCdfConvertJava.java index 6ce8e34..9b9b0fe 100644 --- a/binary-array-ld-demo/src/main/java/net/bald/NetCdfConvertJava.java +++ b/binary-array-ld-demo/src/main/java/net/bald/NetCdfConvertJava.java @@ -1,8 +1,8 @@ package net.bald; -import net.bald.context.AliasDefinition; +import net.bald.alias.AliasDefinition; import net.bald.context.ModelContext; -import net.bald.model.ModelAliasDefinition; +import net.bald.alias.ModelAliasDefinition; import net.bald.model.ModelBinaryArrayConverter; import net.bald.netcdf.NetCdfBinaryArray; import org.apache.jena.rdf.model.Model; @@ -26,8 +26,8 @@ public static void convert() throws Exception { public static void convertWithExternalPrefixes() throws Exception { PrefixMapping prefix = ModelFactory.createDefaultModel().read("/path/to/context.json", "json-ld"); - ModelContext context = ModelContext.create(prefix, null); - BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", context); + ModelContext context = ModelContext.create(prefix); + BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", context, null); Model model = ModelBinaryArrayConverter.convert(ba); try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { @@ -36,13 +36,9 @@ public static void convertWithExternalPrefixes() throws Exception { } public static void convertWithAliases() throws Exception { - PrefixMapping prefix = PrefixMapping.Factory.create(); Model aliasModel = ModelFactory.createDefaultModel().read("/path/to/alias.ttl", "ttl"); AliasDefinition alias = ModelAliasDefinition.create(aliasModel); - ModelContext context = ModelContext.create(prefix, alias); - - BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", context); - + BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", null, alias); Model model = ModelBinaryArrayConverter.convert(ba); try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { diff --git a/binary-array-ld-lib/pom.xml b/binary-array-ld-lib/pom.xml index 7950ec5..7f853ee 100644 --- a/binary-array-ld-lib/pom.xml +++ b/binary-array-ld-lib/pom.xml @@ -41,4 +41,13 @@ ${jena.version} + + + + + org.jetbrains.dokka + dokka-maven-plugin + + + diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/context/AliasDefinition.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/alias/AliasDefinition.kt similarity index 91% rename from binary-array-ld-lib/src/main/kotlin/net/bald/context/AliasDefinition.kt rename to binary-array-ld-lib/src/main/kotlin/net/bald/alias/AliasDefinition.kt index a9cb0a7..487f515 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/context/AliasDefinition.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/alias/AliasDefinition.kt @@ -1,4 +1,4 @@ -package net.bald.context +package net.bald.alias import org.apache.jena.rdf.model.Property import org.apache.jena.rdf.model.Resource @@ -29,6 +29,9 @@ interface AliasDefinition { */ fun isReferenceProperty(prop: Property): Boolean + /** + * A substitute [AliasDefinition] implementation that represents a null or empty definition. + */ object Empty: AliasDefinition { override fun property(identifier: String): Property? { return null diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelAliasDefinition.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/alias/ModelAliasDefinition.kt similarity index 97% rename from binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelAliasDefinition.kt rename to binary-array-ld-lib/src/main/kotlin/net/bald/alias/ModelAliasDefinition.kt index 9ab970c..6064e35 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelAliasDefinition.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/alias/ModelAliasDefinition.kt @@ -1,6 +1,5 @@ -package net.bald.model +package net.bald.alias -import net.bald.context.AliasDefinition import net.bald.vocab.BALD import org.apache.jena.rdf.model.* import org.apache.jena.vocabulary.DCTerms diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/context/ModelContext.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/context/ModelContext.kt index 6fccfba..b8c098b 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/context/ModelContext.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/context/ModelContext.kt @@ -1,16 +1,12 @@ package net.bald.context -import org.apache.jena.rdf.model.Property -import org.apache.jena.rdf.model.Resource import org.apache.jena.shared.PrefixMapping /** * The external context in which a binary array can be resolved. - * This includes resource and property aliases as defined by [AliasDefinition] - * and the available namespace prefix mappings. - * @see AliasDefinition + * This includes any available namespace prefix mappings. */ -interface ModelContext: AliasDefinition { +interface ModelContext { /** * Prefix mappings that are available in this context. */ @@ -21,41 +17,24 @@ interface ModelContext: AliasDefinition { */ object Empty: ModelContext { override val prefixMapping: PrefixMapping get() = PrefixMapping.Factory.create() - override fun property(identifier: String): Property? = null - override fun resource(identifier: String): Resource? = null - override fun isReferenceProperty(prop: Property): Boolean = false } /** * A basic [ModelContext] implementation that simply composes the prefix mapping and alias elements. */ class Base( - override val prefixMapping: PrefixMapping, - private val alias: AliasDefinition - ): ModelContext { - override fun property(identifier: String): Property? { - return alias.property(identifier) - } - - override fun resource(identifier: String): Resource? { - return alias.resource(identifier) - } - - override fun isReferenceProperty(prop: Property): Boolean { - return alias.isReferenceProperty(prop) - } - } + override val prefixMapping: PrefixMapping + ): ModelContext companion object { /** * Instantiate a wrapper for the external elements which contextualise a binary array conversion. * @throws IllegalArgumentException If there are conflicting definitions in the prefix mappings. * @param prefixes The contextual prefix mappings. - * @param alias The contextual alias definition. * @return The [ModelContext]. */ @JvmStatic - fun create(prefixes: List, alias: AliasDefinition? = null): ModelContext { + fun create(prefixes: List): ModelContext { val prefix = if (prefixes.isEmpty()) { PrefixMapping.Factory.create() } else { @@ -73,15 +52,15 @@ interface ModelContext: AliasDefinition { } } } - return create(prefix, alias) + return create(prefix) } /** * @see create */ @JvmStatic - fun create(prefix: PrefixMapping, alias: AliasDefinition? = null): ModelContext { - return Base(prefix, alias ?: AliasDefinition.Empty) + fun create(prefix: PrefixMapping): ModelContext { + return Base(prefix) } } } \ No newline at end of file diff --git a/binary-array-ld-lib/src/test/kotlin/net/bald/context/ModelContextTest.kt b/binary-array-ld-lib/src/test/kotlin/net/bald/context/ModelContextTest.kt index 3b91aaf..784b31e 100644 --- a/binary-array-ld-lib/src/test/kotlin/net/bald/context/ModelContextTest.kt +++ b/binary-array-ld-lib/src/test/kotlin/net/bald/context/ModelContextTest.kt @@ -1,19 +1,18 @@ package net.bald.context -import com.nhaarman.mockitokotlin2.mock import org.apache.jena.shared.PrefixMapping import org.apache.jena.vocabulary.DCTerms import org.apache.jena.vocabulary.SKOS import org.apache.jena.vocabulary.VCARD -import org.junit.jupiter.api.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import kotlin.test.assertEquals class ModelContextTest { private val prefix = PrefixMapping.Factory.create() .setNsPrefix("skos", SKOS.uri) .setNsPrefix("dct", DCTerms.getURI()) - private val alias = mock() - private val context = ModelContext.create(prefix, alias) + private val context = ModelContext.create(prefix) /** * Requirements class B-4 @@ -41,7 +40,7 @@ class ModelContextTest { .setNsPrefix("vcard", VCARD.uri) .setNsPrefix("dct", DCTerms.getURI()) ) - val context = ModelContext.create(prefixes, alias) + val context = ModelContext.create(prefixes) val result = context.prefixMapping.nsPrefixMap val expected = mapOf( "skos" to SKOS.uri, @@ -65,7 +64,7 @@ class ModelContextTest { .setNsPrefix("dct", DCTerms.getURI()) ) val iae = assertThrows { - ModelContext.create(prefixes, alias) + ModelContext.create(prefixes) } assertEquals("The namespace prefixes [skos] have conflicting definitions in contexts.", iae.message) } diff --git a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelAliasDefinitionTest.kt b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelAliasDefinitionTest.kt index 9e8b275..151f193 100644 --- a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelAliasDefinitionTest.kt +++ b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelAliasDefinitionTest.kt @@ -1,5 +1,6 @@ package net.bald.model +import net.bald.alias.ModelAliasDefinition import net.bald.vocab.BALD import org.apache.jena.rdf.model.ModelFactory import org.apache.jena.rdf.model.ResourceFactory.createProperty diff --git a/binary-array-ld-netcdf/pom.xml b/binary-array-ld-netcdf/pom.xml index 46a613e..d178710 100644 --- a/binary-array-ld-netcdf/pom.xml +++ b/binary-array-ld-netcdf/pom.xml @@ -40,6 +40,22 @@ + + + + org.jetbrains.dokka + dokka-maven-plugin + + + + https://www.unidata.ucar.edu/software/netcdf-java/v4.5/javadoc/ + + + + + + + unidata-all diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfAttributeSource.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfAttributeSource.kt index 38fa16a..0135271 100644 --- a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfAttributeSource.kt +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfAttributeSource.kt @@ -1,9 +1,6 @@ package net.bald.netcdf import net.bald.AttributeSource -import net.bald.context.AliasDefinition -import org.apache.jena.rdf.model.Property -import org.apache.jena.shared.PrefixMapping import ucar.nc2.Attribute import ucar.nc2.AttributeContainer diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfBinaryArray.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfBinaryArray.kt index ecdf1cb..34201d4 100644 --- a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfBinaryArray.kt +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfBinaryArray.kt @@ -1,6 +1,7 @@ package net.bald.netcdf import net.bald.BinaryArray +import net.bald.alias.AliasDefinition import net.bald.context.ModelContext import org.apache.jena.shared.PrefixMapping import ucar.nc2.AttributeContainer @@ -16,7 +17,8 @@ import java.io.File class NetCdfBinaryArray( override val uri: String, private val file: NetcdfFile, - val context: ModelContext + private val context: ModelContext, + val alias: AliasDefinition ): BinaryArray { override val root: NetCdfContainer get() = container(file.rootGroup) @@ -66,18 +68,20 @@ class NetCdfBinaryArray( * The resulting [NetCdfBinaryArray] should be closed after use. * @param fileLoc The location of the NetCDF file on the local file system. * @param uri The URI which identifies the dataset. - * @param context The external context in which to resolve the binary array. + * @param context The external context with which to resolve prefix mappings. + * @param alias The alias definition with which to resolve resource and property references. * @return A [BinaryArray] representation of the NetCDF file. */ @JvmStatic fun create( fileLoc: String, - uri: String?, - context: ModelContext? + uri: String? = null, + context: ModelContext? = null, + alias: AliasDefinition? = null ): NetCdfBinaryArray { val file = NetcdfFiles.open(fileLoc) val requiredUri = uri ?: uri(fileLoc) - return create(file, requiredUri, context) + return create(file, requiredUri, context, alias) } /** @@ -85,7 +89,7 @@ class NetCdfBinaryArray( */ @JvmStatic fun create(fileLoc: String, uri: String? = null): NetCdfBinaryArray { - return create(fileLoc, uri, null) + return create(fileLoc, uri, null, null) } /** @@ -95,9 +99,12 @@ class NetCdfBinaryArray( fun create( file: NetcdfFile, uri: String, - context: ModelContext? = null + context: ModelContext? = null, + alias: AliasDefinition? = null ): NetCdfBinaryArray { - return NetCdfBinaryArray(uri, file, context ?: ModelContext.Empty) + val requiredContext = context ?: ModelContext.Empty + val requiredAlias = alias ?: AliasDefinition.Empty + return NetCdfBinaryArray(uri, file, requiredContext, requiredAlias) } private fun uri(fileLoc: String): String { diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfContainer.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfContainer.kt index d91f21a..798cf64 100644 --- a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfContainer.kt +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfContainer.kt @@ -3,7 +3,7 @@ package net.bald.netcdf import net.bald.Attribute import net.bald.Container import net.bald.Var -import net.bald.context.ModelContext +import net.bald.alias.AliasDefinition import org.apache.jena.rdf.model.Property import org.apache.jena.rdf.model.RDFNode import org.apache.jena.rdf.model.ResourceFactory @@ -23,7 +23,7 @@ abstract class NetCdfContainer( ): Container { abstract val parent: NetCdfContainer? abstract val root: NetCdfContainer - abstract val context: ModelContext + abstract val alias: AliasDefinition abstract val uriParser: UriParser abstract fun childUri(name: String): String @@ -73,14 +73,14 @@ abstract class NetCdfContainer( fun parseProperty(name: String): Property { return uriParser.parse(name)?.let(ResourceFactory::createProperty) - ?: context.property(name) + ?: alias.property(name) ?: childUri(name).let(ResourceFactory::createProperty) } fun parseRdfNodes(prop: Property, value: String): List { return uriParser.parse(value)?.let(::createResource)?.let(::listOf) - ?: context.resource(value)?.let(::listOf) - ?: prop.takeIf(context::isReferenceProperty)?.let { + ?: alias.resource(value)?.let(::listOf) + ?: prop.takeIf(alias::isReferenceProperty)?.let { refParser.parse(value) } ?: createPlainLiteral(value).let(::listOf) diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfRootContainer.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfRootContainer.kt index 14f677b..b6a39e8 100644 --- a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfRootContainer.kt +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfRootContainer.kt @@ -3,7 +3,7 @@ package net.bald.netcdf import ucar.nc2.Group import ucar.nc2.Variable import net.bald.Container -import net.bald.context.ModelContext +import net.bald.alias.AliasDefinition /** * NetCDF implementation of [Container] based on the root group. @@ -13,7 +13,7 @@ class NetCdfRootContainer( group: Group, ): NetCdfContainer(group) { override val uri: String get() = ba.uri + "/" - override val context: ModelContext get() = ba.context + override val alias: AliasDefinition get() = ba.alias override val parent: NetCdfContainer? get() = null override val root: NetCdfContainer get() = this override val uriParser: UriParser get() = UriParser(ba.prefixMapping) diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfSubContainer.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfSubContainer.kt index ce0177c..8d065d0 100644 --- a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfSubContainer.kt +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfSubContainer.kt @@ -1,7 +1,7 @@ package net.bald.netcdf import net.bald.Container -import net.bald.context.ModelContext +import net.bald.alias.AliasDefinition import ucar.nc2.Group /** @@ -12,8 +12,8 @@ class NetCdfSubContainer( private val group: Group ): NetCdfContainer(group) { override val uri: String get() = parent.childUri(group.shortName) - override val context: ModelContext get() = parent.context override val root: NetCdfContainer get() = parent.root + override val alias: AliasDefinition get() = parent.alias override val uriParser: UriParser get() = parent.uriParser override fun childUri(name: String): String { diff --git a/binary-array-ld-netcdf/src/test/kotlin/net/bald/netcdf/NetCdfBinaryArrayTest.kt b/binary-array-ld-netcdf/src/test/kotlin/net/bald/netcdf/NetCdfBinaryArrayTest.kt index 97ee0b1..4409cc4 100644 --- a/binary-array-ld-netcdf/src/test/kotlin/net/bald/netcdf/NetCdfBinaryArrayTest.kt +++ b/binary-array-ld-netcdf/src/test/kotlin/net/bald/netcdf/NetCdfBinaryArrayTest.kt @@ -3,8 +3,9 @@ package net.bald.netcdf import bald.TestVocab import bald.netcdf.CdlConverter.writeToNetCdf import net.bald.BinaryArray +import net.bald.alias.AliasDefinition import net.bald.context.ModelContext -import net.bald.model.ModelAliasDefinition +import net.bald.alias.ModelAliasDefinition import net.bald.vocab.BALD import org.apache.jena.rdf.model.ModelFactory import org.apache.jena.rdf.model.ResourceFactory.createPlainLiteral @@ -20,9 +21,9 @@ import kotlin.test.assertEquals class NetCdfBinaryArrayTest { - private fun fromCdl(cdlLoc: String, uri: String? = null, context: ModelContext? = null): BinaryArray { + private fun fromCdl(cdlLoc: String, uri: String? = null, context: ModelContext? = null, alias: AliasDefinition? = null): BinaryArray { val file = writeToNetCdf(cdlLoc) - return NetCdfBinaryArray.create(file.absolutePath, uri, context) + return NetCdfBinaryArray.create(file.absolutePath, uri, context, alias) } /** @@ -243,8 +244,8 @@ class NetCdfBinaryArrayTest { val alias = javaClass.getResourceAsStream("/turtle/alias.ttl").use { input -> ModelFactory.createDefaultModel().read(input, null, "ttl") }.let(ModelAliasDefinition::create) - val ctx = ModelContext.create(prefix, alias) - val ba = fromCdl("/netcdf/alias.cdl", "http://test.binary-array-ld.net/alias.nc", ctx) + val ctx = ModelContext.create(prefix) + val ba = fromCdl("/netcdf/alias.cdl", "http://test.binary-array-ld.net/alias.nc", ctx, alias) ContainerVerifier(ba.root).apply { attributes { attribute(BALD.isPrefixedBy.uri, createPlainLiteral("prefix_list")) @@ -278,8 +279,8 @@ class NetCdfBinaryArrayTest { val alias = javaClass.getResourceAsStream("/turtle/var-alias.ttl").use { input -> ModelFactory.createDefaultModel().read(input, null, "ttl") }.let(ModelAliasDefinition::create) - val ctx = ModelContext.create(prefix, alias) - val ba = fromCdl("/netcdf/var-ref.cdl", "http://test.binary-array-ld.net/var-ref.nc", ctx) + val ctx = ModelContext.create(prefix) + val ba = fromCdl("/netcdf/var-ref.cdl", "http://test.binary-array-ld.net/var-ref.nc", ctx, alias) ContainerVerifier(ba.root).apply { attributes { diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..c741881 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/docs/alias.md b/docs/alias.md new file mode 100644 index 0000000..b673639 --- /dev/null +++ b/docs/alias.md @@ -0,0 +1,41 @@ +# Aliases + +The BALD CLI and library allow you to specify property and resource aliases to be resolved in the NetCDF metadata, +as described in the [draft specification](http://docs.opengeospatial.org/DRAFTS/19-002.html#_alias_definition). + +## CLI + +You can provide aliases as a set of RDF files. +Use the `--alias` or `-a` option to specify the locations of alias files +as a comma-delimited list. +Note that these files must have a suitable extension in order to be parsed correctly. + +#### Example +``` +java -jar bald-cli.jar --alias /path/to/alias.ttl /path/to/netcdf.nc /path/to/graph.ttl +``` + +## Library + +You can provide aliases as an Apache Jena [model](https://jena.apache.org/documentation/javadoc/jena/org/apache/jena/rdf/model/Model.html). +You can create a `Model` instance programmatically, or by reading in an RDF file. +See the [Jena docs](https://jena.apache.org/tutorials/rdf_api.html) for more information. + +Pass a model to the `ModelAliasDefinition.create` method to create an `AliasDefinition` instance. +You may also create your own implementation of `AliasDefinition`. + +You can pass this instance to the `NetCdfBinaryArray.create` method to create a binary array with the given aliases. + +Note that you can pass both a contextual [prefix mapping](context.md), +and an alias definition to create a `BinaryArray` with both. + +```java +Model aliasModel = ModelFactory.createDefaultModel().read("/path/to/alias.ttl", "ttl"); +AliasDefinition alias = ModelAliasDefinition.create(aliasModel); +BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", null, alias); +Model model = ModelBinaryArrayConverter.convert(ba); + +try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { + model.write(output, "ttl"); +} +``` diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 0000000..c167623 --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,60 @@ +# Command Line Interface + +You can download the latest release of the CLI [here](https://github.com/binary-array-ld/net.binary_array_ld.bald/releases/latest/download/bald-cli.jar). + +You can browse older versions [here](https://github.com/binary-array-ld/net.binary_array_ld.bald/releases). + +You can run the JAR using the `java -jar` command. +You can run the application with no arguments to output documentation: +``` +java -jar bald-cli.jar +``` + +The application accepts arguments in the following format: + ``` +java -jar bald-cli.jar [options] inputFile [outputFile] +``` + +Where `inputFile` is the location of the NetCDF file to convert, +and `outputFile` is the location of the file in which to output the RDF graph. +If you don't specify an `outputFile`, the graph will be printed on the command line. + +See the [quick reference](#quick-reference) for the full list of options. + +#### Example + +To read a NetCDF binary array and emit it to a file in [Turtle](https://www.w3.org/TR/turtle/) format: + +``` +java -jar bald-cli.jar --uri http://test.binary-array-ld.net/example /path/to/netcdf.nc /path/to/graph.ttl +``` + +### RDF Format + +By default, the RDF graph output will be in [Turtle](https://www.w3.org/TR/turtle/) format. +You can use the `--output` or `-o` option to specify the RDF format to emit. +This option can accept any of the RDF formats supported by Apache Jena, eg. JSON-LD, RDFXML. +See [here](https://jena.apache.org/documentation/io/rdf-output.html#jena_model_write_formats) for supported formats. + +### Context + +The CLI supports [contexts](context.md). +You can find the documentation for this feature [here](context.md#cli). + +### Aliases + +The CLI supports [aliases](alias.md). +You can find the documentation for this feature [here](alias.md#cli). + +### Quick Reference + +You can supply command line options in long form with the `--` prefix or short form with `-`, +followed by their value. + +| Option | Short form | Value | Default | +|--------|------------|-------|---------| +| --help | -h | Flag to show usage documentation (no value). || +| --uri | -u | The URI which identifies the dataset. | Input file URI | +| --output | -o | Output format, eg. ttl, json-ld, rdfxml. | ttl | +| --context | -c | Comma-delimited list of JSON-LD context files. || +| --alias | -a | Comma-delimited list of RDF alias files. || \ No newline at end of file diff --git a/docs/context.md b/docs/context.md new file mode 100644 index 0000000..36e777e --- /dev/null +++ b/docs/context.md @@ -0,0 +1,39 @@ +# Context + +The BALD CLI and library allow you to specify contextual prefix mappings to be resolved in the NetCDF metadata +as described in the [draft specification](http://docs.opengeospatial.org/DRAFTS/19-002.html#_externally_defined_prefixes). + +## CLI + +You can provide the context as a set of JSON-LD files. +Use the `--context` or `-c` option to specify the locations of the context files +as a comma-delimited list. + +#### Example +``` +java -jar bald-cli.jar --context /path/to/context.json /path/to/netcdf.nc /path/to/graph.ttl +``` + +## Library + +You can provide the context as an Apache Jena [prefix mapping](https://jena.apache.org/documentation/javadoc/jena/org/apache/jena/shared/PrefixMapping.html). +Pass a prefix mapping (or list of mappings) to the `ModelContext.create` method to create a `ModelContext` instance. +You may also create your own implementation of `ModelContext`. + +You can pass this instance to the `NetCdfBinaryArray.create` method to create a binary array with the given context. + +Note that you can pass both a contextual prefix mapping, and an [alias definition](alias.md) +to create a `BinaryArray` with both. + +#### Example + +```java +PrefixMapping prefix = ModelFactory.createDefaultModel().read("/path/to/context.json", "json-ld"); +ModelContext context = ModelContext.create(prefix); +BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example", context, null); +Model model = ModelBinaryArrayConverter.convert(ba); + +try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { + model.write(output, "ttl"); +} +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..49b9e8a --- /dev/null +++ b/docs/index.md @@ -0,0 +1,13 @@ +# Binary Array Linked Data + +This project contains a [Kotlin](https://kotlinlang.org/) library and CLI for integrating binary array data with linked data. +This includes NetCDF to RDF conversion according to [OGC draft specification](http://docs.opengeospatial.org/DRAFTS/19-002.html). + +### Releases +* No releases yet. + +### Links +* [Usage Documentation](usage.md) + * [CLI](cli.md) + * [Library](lib.md) +* [Javadoc](todo) \ No newline at end of file diff --git a/docs/lib.md b/docs/lib.md new file mode 100644 index 0000000..977ac52 --- /dev/null +++ b/docs/lib.md @@ -0,0 +1,66 @@ +# Library + +Javadocs are available [here](todo). +You can find Java examples [here](https://github.com/binary-array-ld/net.binary_array_ld.bald/tree/master/binary-array-ld-demo/src/main/java/net/bald). + +To use the BALD core library in your Maven project, add the following dependency: + +```xml + + net.binary-array-ld + binary-array-ld-lib + ${bald.version} + +``` + +To convert NetCDF metadata files, you can use the pre-made NetCDF implementation in the `binary-array-ld-netcdf` module. +To use this module, add the following dependency to your Maven project: + +```xml + + net.binary-array-ld + binary-array-ld-netcdf + ${bald.version} + +``` + +Use the `NetCdfBinaryArray.create` method to create a new binary array representation from a NetCDF file. +NetCDF and CDL file formats are supported. +You can also optionally supply a URI as the identifier of the dataset. + +You can pass the resulting `BinaryArray` instance to the `ModelBinaryArrayConverter.convert` +method to obtain an RDF graph in Apache Jena [model](https://jena.apache.org/documentation/javadoc/jena/org/apache/jena/rdf/model/Model.html) form. +See the [Jena docs](https://jena.apache.org/tutorials/rdf_api.html) for how to use the `Model` class. + +You can also implement the `BinaryArray` interface with your own binary array metadata representations. + +#### Example +To read a NetCDF binary array and emit it to a file in [Turtle](https://www.w3.org/TR/turtle/) format: + +Kotlin +```kotlin +val ba = NetCdfBinaryArray.create("/path/to/input.nc", "http://test.binary-array-ld.net/example") +val model = ModelBinaryArrayConverter.convert(ba) +File("/path/to/output.ttl").outputStream().use { output -> + model.write(output, "ttl") +} +``` +Java +```java +BinaryArray ba = NetCdfBinaryArray.create("/path/to/input.ttl", "http://test.binary-array-ld.net/example"); +Model model = ModelBinaryArrayConverter.convert(ba); + +try (OutputStream output = new FileOutputStream("/path/to/output.ttl")) { + model.write(output, "ttl"); +} +``` + +### Context + +The library supports [contexts](context.md). +You can find the documentation for this feature [here](context.md#library). + +### Aliases + +The library supports [aliases](alias.md). +You can find the documentation for this feature [here](alias.md#library). diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..b8262db --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,9 @@ +# Usage + +This project can be used as a command line interface or as a library. +* [CLI](cli.md) +* [Library](lib.md) + +### Features +* [Context](context.md) +* [Aliases](alias.md) \ No newline at end of file diff --git a/pom.xml b/pom.xml index 432b56d..0e0865e 100644 --- a/pom.xml +++ b/pom.xml @@ -118,5 +118,37 @@ + + + + org.jetbrains.dokka + dokka-maven-plugin + 1.4.30 + + + package + + javadoc + + + + + + + https://jena.apache.org/documentation/javadoc/jena/ + + + + + + + + + + jcenter + JCenter + https://jcenter.bintray.com/ + +