diff --git a/binary-array-ld-cli/src/main/resources/logback.xml b/binary-array-ld-cli/src/main/resources/logback.xml new file mode 100644 index 0000000..4bd2e37 --- /dev/null +++ b/binary-array-ld-cli/src/main/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/binary-array-ld-cli/src/test/kotlin/net/bald/BinaryArrayConvertCliTest.kt b/binary-array-ld-cli/src/test/kotlin/net/bald/BinaryArrayConvertCliTest.kt index adb5491..dc35c1f 100644 --- a/binary-array-ld-cli/src/test/kotlin/net/bald/BinaryArrayConvertCliTest.kt +++ b/binary-array-ld-cli/src/test/kotlin/net/bald/BinaryArrayConvertCliTest.kt @@ -1,16 +1,23 @@ package net.bald import bald.model.ModelVerifier -import bald.netcdf.CdlConverter.convertToNetCdf +import bald.netcdf.CdlConverter.writeToNetCdf import net.bald.vocab.BALD import org.apache.jena.rdf.model.ModelFactory.createDefaultModel import org.apache.jena.vocabulary.RDF +import org.apache.jena.vocabulary.SKOS +import org.junit.Assume +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import ucar.nc2.jni.netcdf.Nc4Iosp import kotlin.test.assertEquals /** * Integration test for [BinaryArrayConvertCli]. + * + * Test resources are stored in CDL format and converted to temporary NetCDF 4 files. + * In order to write the NetCDF 4 files, the ncgen command line utility must be available. */ class BinaryArrayConvertCliTest { private fun run(vararg args: String) { @@ -32,7 +39,7 @@ class BinaryArrayConvertCliTest { @Test fun run_withoutUri_outputsToFileWithInputFileUri() { - val inputFile = convertToNetCdf("/netcdf/identity.cdl") + val inputFile = writeToNetCdf("/netcdf/identity.cdl") val inputFileUri = inputFile.toPath().toUri().toString() val outputFile = createTempFile() run(inputFile.absolutePath, outputFile.absolutePath) @@ -56,12 +63,33 @@ class BinaryArrayConvertCliTest { @Test fun run_withUri_withOutputFile_outputsToFile() { - val inputFile = convertToNetCdf("/netcdf/identity.cdl") + val inputFile = writeToNetCdf("/netcdf/identity.cdl") val outputFile = createTempFile() run("--uri", "http://test.binary-array-ld.net/example", inputFile.absolutePath, outputFile.absolutePath) val model = createDefaultModel().read(outputFile.toURI().toString(), "ttl") ModelVerifier(model).apply { + resource("http://test.binary-array-ld.net/example/") { + statement(RDF.type, BALD.Container) + statement(BALD.contains, model.createResource("http://test.binary-array-ld.net/example/var0")) { + statement(RDF.type, BALD.Resource) + } + statement(BALD.contains, model.createResource("http://test.binary-array-ld.net/example/var1")) { + statement(RDF.type, BALD.Resource) + } + } + } + } + + private fun run_withPrefixMapping_outputsPrefixMapping(cdlLoc: String) { + val inputFile = writeToNetCdf(cdlLoc) + val outputFile = createTempFile() + run("--uri", "http://test.binary-array-ld.net/example", inputFile.absolutePath, outputFile.absolutePath) + + val model = createDefaultModel().read(outputFile.toURI().toString(), "ttl") + ModelVerifier(model).apply { + prefix("bald", BALD.prefix) + prefix("skos", SKOS.uri) resource("http://test.binary-array-ld.net/example") { statement(RDF.type, BALD.Container) statement(BALD.contains, model.createResource("http://test.binary-array-ld.net/example/")) { @@ -77,9 +105,19 @@ class BinaryArrayConvertCliTest { } } + @Test + fun run_withPrefixMappingGroup_outputsPrefixMapping() { + run_withPrefixMapping_outputsPrefixMapping("/netcdf/prefix.cdl") + } + + @Test + fun run_withPrefixMappingVar_outputsPrefixMapping() { + run_withPrefixMapping_outputsPrefixMapping("/netcdf/prefix-var.cdl") + } + @Test fun run_withSubgroups_outputsWithSubgroups() { - val inputFile = convertToNetCdf("/netcdf/identity-subgroups.cdl") + val inputFile = writeToNetCdf("/netcdf/identity-subgroups.cdl") val outputFile = createTempFile() run("--uri", "http://test.binary-array-ld.net/example", inputFile.absolutePath, outputFile.absolutePath) diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/BinaryArray.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/BinaryArray.kt index d1f983f..730f0e0 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/BinaryArray.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/BinaryArray.kt @@ -1,5 +1,7 @@ package net.bald +import org.apache.jena.shared.PrefixMapping + /** * Represents the metadata of a binary array dataset. * See https://www.opengis.net/def/binary-array-ld/Array @@ -10,6 +12,11 @@ interface BinaryArray { */ val uri: String + /** + * The prefix mapping to apply to the RDF graph. + */ + val prefixMapping: PrefixMapping + /** * The root container. */ diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelBinaryArrayBuilder.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelBinaryArrayBuilder.kt index 0b8fe08..eb276a5 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelBinaryArrayBuilder.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/model/ModelBinaryArrayBuilder.kt @@ -3,16 +3,46 @@ package net.bald.model import net.bald.BinaryArray import net.bald.vocab.BALD import org.apache.jena.rdf.model.Model +import org.apache.jena.shared.PrefixMapping +import java.net.URI class ModelBinaryArrayBuilder( private val model: Model, private val containerFct: ModelContainerBuilder.Factory ) { fun addBinaryArray(ba: BinaryArray) { + addPrefixMapping(ba.prefixMapping) val baRes = model.createResource(ba.uri, BALD.Container) containerFct.forParent(baRes).addContainer(ba.root) } + private fun addPrefixMapping(prefixMapping: PrefixMapping) { + prefixMapping.nsPrefixMap.onEach { (prefix, uri) -> + validatePrefixMapping(prefix, uri) + }.let(model::setNsPrefixes) + } + + private fun validatePrefixMapping(prefix: String, uri: String) { + try { + if (!Prefix.pattern.matches(prefix)) { + throw IllegalArgumentException("Prefix must match pattern ${Prefix.pattern}.") + } else if (!uri.endsWith('/') && !uri.endsWith('#')) { + throw IllegalArgumentException("URI must end with / or #.") + } else { + val scheme = URI.create(uri).scheme + if (scheme != "http" && scheme != "https") { + throw IllegalArgumentException("URI must have HTTP or HTTPS scheme.") + } + } + } catch (e: Exception) { + throw IllegalArgumentException("Unable to add prefix mapping $prefix to model: ${e.message}") + } + } + + private object Prefix { + val pattern = Regex("[A-Za-z_]+") + } + class Factory( private val containerFct: ModelContainerBuilder.Factory ) { diff --git a/binary-array-ld-lib/src/main/kotlin/net/bald/vocab/BALD.kt b/binary-array-ld-lib/src/main/kotlin/net/bald/vocab/BALD.kt index 0f0c1ed..c280d1b 100644 --- a/binary-array-ld-lib/src/main/kotlin/net/bald/vocab/BALD.kt +++ b/binary-array-ld-lib/src/main/kotlin/net/bald/vocab/BALD.kt @@ -11,7 +11,7 @@ import org.apache.jena.rdf.model.ResourceFactory.createResource * See https://www.opengis.net/def/binary-array-ld/. */ object BALD { - private const val prefix = "https://www.opengis.net/def/binary-array-ld/" + const val prefix = "https://www.opengis.net/def/binary-array-ld/" /** * Resources diff --git a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayBuilderTest.kt b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayBuilderTest.kt index 8c9a397..a07bb5c 100644 --- a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayBuilderTest.kt +++ b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayBuilderTest.kt @@ -9,8 +9,13 @@ import net.bald.BinaryArray import net.bald.Container import net.bald.vocab.BALD import org.apache.jena.rdf.model.ModelFactory +import org.apache.jena.shared.PrefixMapping import org.apache.jena.vocabulary.RDF -import org.junit.jupiter.api.* +import org.apache.jena.vocabulary.SKOS +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.lang.IllegalArgumentException +import kotlin.test.assertEquals class ModelBinaryArrayBuilderTest { private val containerBuilder = mock() @@ -20,9 +25,13 @@ class ModelBinaryArrayBuilderTest { private val model = ModelFactory.createDefaultModel() private val builder = ModelBinaryArrayBuilder.Factory(containerFct).forModel(model) private val root = mock() + private val prefix = PrefixMapping.Factory.create() + .setNsPrefix("bald", BALD.prefix) + .setNsPrefix("skos", SKOS.uri) private val ba = mock { on { uri } doReturn "http://test.binary-array-ld.net/example" on { this.root } doReturn root + on { prefixMapping } doReturn prefix } @Test @@ -39,4 +48,40 @@ class ModelBinaryArrayBuilderTest { verify(containerFct).forParent(model.getResource("http://test.binary-array-ld.net/example")) verify(containerBuilder).addContainer(root) } + + @Test + fun addBinaryArray_addsPrefixMapping() { + builder.addBinaryArray(ba) + ModelVerifier(model).apply { + prefix("bald", BALD.prefix) + prefix("skos", SKOS.uri) + } + } + + @Test + fun addBinaryArray_prefixMappingWithInvalidChar_throwsException() { + prefix.setNsPrefix("bald-eg", "http://example.org/prefix/") + val iae = assertThrows { + builder.addBinaryArray(ba) + } + assertEquals("Unable to add prefix mapping bald-eg to model: Prefix must match pattern [A-Za-z_]+.", iae.message) + } + + @Test + fun addBinaryArray_prefixMappingWithInvalidScheme_throwsException() { + prefix.setNsPrefix("eg", "file:///example/prefix/") + val iae = assertThrows { + builder.addBinaryArray(ba) + } + assertEquals("Unable to add prefix mapping eg to model: URI must have HTTP or HTTPS scheme.", iae.message) + } + + @Test + fun addBinaryArray_prefixMappingWithoutTrailingChar_throwsException() { + prefix.setNsPrefix("eg", "http://example.org/prefix") + val iae = assertThrows { + builder.addBinaryArray(ba) + } + assertEquals("Unable to add prefix mapping eg to model: URI must end with / or #.", iae.message) + } } \ No newline at end of file diff --git a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayConverterTest.kt b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayConverterTest.kt index 77e0933..6371334 100644 --- a/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayConverterTest.kt +++ b/binary-array-ld-lib/src/test/kotlin/net/bald/model/ModelBinaryArrayConverterTest.kt @@ -8,7 +8,9 @@ import net.bald.Container import net.bald.Var import net.bald.vocab.BALD import org.apache.jena.rdf.model.Model +import org.apache.jena.shared.PrefixMapping import org.apache.jena.vocabulary.RDF +import org.apache.jena.vocabulary.SKOS import org.junit.jupiter.api.* /** @@ -33,13 +35,19 @@ class ModelBinaryArrayConverterTest { on { vars() } doReturn vars.asSequence() on { subContainers() } doReturn emptySequence() } + val prefix = PrefixMapping.Factory.create() + .setNsPrefix("bald", BALD.prefix) + .setNsPrefix("skos", SKOS.uri) val ba = mock { on { uri } doReturn "http://test.binary-array-ld.net/example" on { this.root } doReturn root + on { prefixMapping } doReturn prefix } val model = convert(ba) ModelVerifier(model).apply { + prefix("bald", BALD.prefix) + prefix("skos", SKOS.uri) resource("http://test.binary-array-ld.net/example") { statement(RDF.type, BALD.Container) statement(BALD.contains, model.createResource("http://test.binary-array-ld.net/example/")) { 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 37f1bc2..438cf0d 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 @@ -2,10 +2,11 @@ package net.bald.netcdf import net.bald.BinaryArray import net.bald.Container -import ucar.nc2.NetcdfFile -import ucar.nc2.NetcdfFiles +import org.apache.jena.shared.PrefixMapping +import ucar.nc2.* import java.io.Closeable import java.io.File +import java.lang.IllegalStateException /** * NetCDF implementation of [BinaryArray]. @@ -15,12 +16,41 @@ class NetCdfBinaryArray( override val uri: String, private val file: NetcdfFile ): BinaryArray, Closeable { - override val root: Container get() = NetCdfContainer(file.rootGroup) + override val root: Container get() = container(file.rootGroup) + override val prefixMapping: PrefixMapping get() = prefixMapping() ?: PrefixMapping.Factory.create() override fun close() { file.close() } + private fun container(group: Group): Container { + val prefixSrc = prefixSourceName() + return NetCdfContainer(group, prefixSrc) + } + + private fun prefixMapping(): PrefixMapping? { + return prefixSource()?.let(::NetCdfPrefixMappingBuilder)?.build() + } + + private fun prefixSource(): AttributeContainer? { + return prefixSourceName()?.let { name -> + file.findGroup(name) + ?: file.findVariable(name) + ?: throw IllegalStateException("Prefix group or variable $name not found.") + } + } + + private fun prefixSourceName(): String? { + return file.findGlobalAttribute(Attribute.prefix)?.let { attr -> + attr.stringValue + ?: throw IllegalStateException("Global prefix attribute ${Attribute.prefix} has a non-string value.") + } + } + + private object Attribute { + const val prefix = "bald__isPrefixedBy" + } + companion object { /** * Instantiate a [BinaryArray] representation of the given NetCDF file and identifying URI. @@ -31,9 +61,17 @@ class NetCdfBinaryArray( */ @JvmStatic fun create(fileLoc: String, uri: String? = null): NetCdfBinaryArray { - val requiredUri = uri ?: uri(fileLoc) val file = NetcdfFiles.open(fileLoc) - return NetCdfBinaryArray(requiredUri, file) + val requiredUri = uri ?: uri(fileLoc) + return create(file, requiredUri) + } + + /** + * @see [create]. + */ + @JvmStatic + fun create(file: NetcdfFile, uri: String): NetCdfBinaryArray { + return NetCdfBinaryArray(uri, file) } 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 1c42c55..9415d00 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,20 +3,30 @@ package net.bald.netcdf import net.bald.Container import net.bald.Var import ucar.nc2.Group +import ucar.nc2.Variable /** * NetCDF implementation of [Container]. */ class NetCdfContainer( - private val group: Group + private val group: Group, + private val prefixSrc: String? = null ): Container { override val name: String? get() = group.shortName override fun vars(): Sequence { - return group.variables.asSequence().map(::NetCdfVar) + return group.variables.asSequence().filter(::acceptVar).map(::NetCdfVar) } override fun subContainers(): Sequence { - return group.groups.asSequence().map(::NetCdfContainer) + return group.groups.asSequence().filter(::acceptGroup).map(::NetCdfContainer) + } + + private fun acceptVar(v: Variable): Boolean { + return prefixSrc != v.shortName + } + + private fun acceptGroup(group: Group): Boolean { + return prefixSrc != group.shortName } } \ No newline at end of file diff --git a/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfPrefixMappingBuilder.kt b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfPrefixMappingBuilder.kt new file mode 100644 index 0000000..f03e842 --- /dev/null +++ b/binary-array-ld-netcdf/src/main/kotlin/net/bald/netcdf/NetCdfPrefixMappingBuilder.kt @@ -0,0 +1,36 @@ +package net.bald.netcdf + +import org.apache.jena.shared.PrefixMapping +import ucar.nc2.Attribute +import ucar.nc2.AttributeContainer + +/** + * Class for building a + * NetCDF implementation of [PrefixMapping]. + */ +class NetCdfPrefixMappingBuilder( + private val attrs: AttributeContainer +) { + fun build(): PrefixMapping { + val prefixMap = attrs.asSequence() + .filter(::isPrefixAttr) + .associateBy(::prefix, ::uri) + return PrefixMapping.Factory.create().setNsPrefixes(prefixMap) + } + + private fun isPrefixAttr(attr: Attribute): Boolean { + return attr.shortName.endsWith(suffix) + } + + private fun prefix(attr: Attribute): String { + return attr.shortName.substringBeforeLast("__") + } + + private fun uri(attr: Attribute): String { + return attr.stringValue ?: throw IllegalStateException("Prefix attribute ${attr.shortName} has a non-string value.") + } + + companion object { + private const val suffix = "__" + } +} \ No newline at end of file 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 d9613b2..8d97019 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 @@ -1,34 +1,38 @@ package net.bald.netcdf -import bald.netcdf.CdlConverter.convertToNetCdf +import bald.netcdf.CdlConverter.writeToNetCdf import net.bald.BinaryArray import net.bald.Container +import net.bald.vocab.BALD +import org.apache.jena.vocabulary.SKOS import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import kotlin.test.assertEquals class NetCdfBinaryArrayTest { + private fun fromCdl(cdlLoc: String, uri: String? = null): BinaryArray { - val file = convertToNetCdf(cdlLoc) + val file = writeToNetCdf(cdlLoc) return NetCdfBinaryArray.create(file.absolutePath, uri) } @Test - fun create_withUri_returnsBinaryArray() { + fun uri_withUri_returnsValue() { val uri = "http://test.binary-array-ld.net/identity.nc" val ba = fromCdl("/netcdf/identity.cdl", uri) assertEquals(uri, ba.uri) } @Test - fun create_withoutUri_returnsBinaryArrayWithFileUri() { - val netCdfFile = convertToNetCdf("/netcdf/identity.cdl") + fun uri_withoutUri_returnsFileUri() { + val netCdfFile = writeToNetCdf("/netcdf/identity.cdl") val ba = NetCdfBinaryArray.create(netCdfFile.absolutePath) val expectedUri = netCdfFile.toPath().toUri().toString() assertEquals(expectedUri, ba.uri) } @Test - fun create_withVars_returnsBinaryArrayWithVars() { + fun root_vars_withVars_returnsVariables() { val uri = "http://test.binary-array-ld.net/identity.nc" val ba = fromCdl("/netcdf/identity.cdl", uri) @@ -39,7 +43,7 @@ class NetCdfBinaryArrayTest { } @Test - fun create_withSubgroups_returnsSubgroups() { + fun root_subContainers_withSubgroups_returnsSubgroups() { val uri = "http://test.binary-array-ld.net/identity-subgroups.nc" val ba = fromCdl("/netcdf/identity-subgroups.cdl", uri) val root = ba.root @@ -61,4 +65,74 @@ class NetCdfBinaryArrayTest { assertEquals("var4", group1Vars[0].name) assertEquals("var5", group1Vars[1].name) } + + @Test + fun root_subContainers_withInternalPrefixMappingGroup_excludesPrefixMapping() { + val ba = fromCdl("/netcdf/identity.cdl", "http://test.binary-array-ld.net/prefix.nc") + assertEquals(emptyList(), ba.root.subContainers().toList()) + } + + @Test + fun root_subContainers_withInternalPrefixMappingVar_excludesPrefixMapping() { + val ba = fromCdl("/netcdf/identity.cdl", "http://test.binary-array-ld.net/prefix-var.nc") + val vars = ba.root.vars().toList() + assertEquals(2, vars.size) + assertEquals("var0", vars[0].name) + assertEquals("var1", vars[1].name) + } + + @Test + fun prefixMapping_withoutPrefixMapping_returnsEmptyPrefixMapping() { + val ba = fromCdl("/netcdf/identity.cdl", "http://test.binary-array-ld.net/prefix.nc") + assertEquals(emptyMap(), ba.prefixMapping.nsPrefixMap) + } + + @Test + fun prefixMapping_withInternalPrefixMappingGroup_returnsPrefixMapping() { + val ba = fromCdl("/netcdf/prefix.cdl", "http://test.binary-array-ld.net/prefix.nc") + val prefix = ba.prefixMapping.nsPrefixMap + val expected = mapOf( + "bald" to BALD.prefix, + "skos" to SKOS.uri + ) + assertEquals(expected, prefix) + } + + @Test + fun prefixMapping_withInternalPrefixMappingVar_returnsPrefixMapping() { + val ba = fromCdl("/netcdf/prefix-var.cdl", "http://test.binary-array-ld.net/prefix.nc") + val prefix = ba.prefixMapping.nsPrefixMap + val expected = mapOf( + "bald" to BALD.prefix, + "skos" to SKOS.uri + ) + assertEquals(expected, prefix) + } + + @Test + fun prefixMapping_prefixGroupDoesNotExist_throwsException() { + val ba = fromCdl("/netcdf/prefix-group-error.cdl", "http://test.binary-array-ld.net/prefix.nc") + val ise = assertThrows { + ba.prefixMapping + } + assertEquals("Prefix group or variable not_prefix_list not found.", ise.message) + } + + @Test + fun prefixMapping_prefixGroupAttrNonString_throwsException() { + val ba = fromCdl("/netcdf/prefix-attr-error.cdl", "http://test.binary-array-ld.net/prefix.nc") + val ise = assertThrows { + ba.prefixMapping + } + assertEquals("Global prefix attribute bald__isPrefixedBy has a non-string value.", ise.message) + } + + @Test + fun prefixMapping_prefixUriNonString_throwsException() { + val ba = fromCdl("/netcdf/prefix-uri-error.cdl", "http://test.binary-array-ld.net/prefix.nc") + val ise = assertThrows { + ba.prefixMapping + } + assertEquals("Prefix attribute skos__ has a non-string value.", ise.message) + } } \ No newline at end of file diff --git a/binary-array-ld-test/pom.xml b/binary-array-ld-test/pom.xml index 50e0194..a9c62a4 100644 --- a/binary-array-ld-test/pom.xml +++ b/binary-array-ld-test/pom.xml @@ -27,6 +27,11 @@ cdm-core 5.3.2 + + edu.ucar + netcdf4 + 5.3.2 + org.jetbrains.kotlin kotlin-test-junit diff --git a/binary-array-ld-test/src/main/kotlin/bald/model/ModelVerifier.kt b/binary-array-ld-test/src/main/kotlin/bald/model/ModelVerifier.kt index 9e9a69a..2594c87 100644 --- a/binary-array-ld-test/src/main/kotlin/bald/model/ModelVerifier.kt +++ b/binary-array-ld-test/src/main/kotlin/bald/model/ModelVerifier.kt @@ -3,6 +3,7 @@ package bald.model import org.apache.jena.rdf.model.Model import org.apache.jena.rdf.model.Resource import org.junit.jupiter.api.fail +import kotlin.test.assertEquals import kotlin.test.assertTrue /** @@ -23,4 +24,13 @@ class ModelVerifier( assertTrue(model.containsResource(resource), "Expected resource $resource in model.") ResourceVerifier(resource).statements(verify) } + + /** + * Verify that the given prefix name is associated with the given URI. + * @param prefix The prefix name. + * @param uri The prefix URI. + */ + fun prefix(prefix: String, uri: String) { + assertEquals(uri, model.getNsPrefixURI(prefix), "Expected prefix mapping for $prefix.") + } } \ No newline at end of file diff --git a/binary-array-ld-test/src/main/kotlin/bald/netcdf/CdlConverter.kt b/binary-array-ld-test/src/main/kotlin/bald/netcdf/CdlConverter.kt index d69cf2c..efe8509 100644 --- a/binary-array-ld-test/src/main/kotlin/bald/netcdf/CdlConverter.kt +++ b/binary-array-ld-test/src/main/kotlin/bald/netcdf/CdlConverter.kt @@ -15,7 +15,7 @@ object CdlConverter { * @param cdlLoc The location of the CDL resource. * @return The NetCDF file. */ - fun convertToNetCdf(cdlLoc: String): File { + fun writeToNetCdf(cdlLoc: String): File { val cdlFile = createTempFile() javaClass.getResourceAsStream(cdlLoc).use { cdl -> cdlFile.outputStream().use(cdl::copyTo) diff --git a/binary-array-ld-test/src/main/kotlin/bald/netcdf/NcmlConverter.kt b/binary-array-ld-test/src/main/kotlin/bald/netcdf/NcmlConverter.kt index c9cc365..a16647a 100644 --- a/binary-array-ld-test/src/main/kotlin/bald/netcdf/NcmlConverter.kt +++ b/binary-array-ld-test/src/main/kotlin/bald/netcdf/NcmlConverter.kt @@ -1,5 +1,7 @@ package bald.netcdf +import ucar.nc2.NetcdfFile +import ucar.nc2.NetcdfFileWriter import ucar.nc2.ncml.NcMLReader import java.io.File @@ -10,17 +12,29 @@ import java.io.File */ object NcmlConverter { /** - * Convert a NCML resource into a temporary NetCDF file. + * Convert a NCML resource into a temporary NetCDF 4 file. + * In order to write NetCDF 4 successfully, the Unidata NetCDF C library must be available. * @param ncmlLoc The location of the NCML resource. * @return The NetCDF file. */ - fun convertToNetCdf(ncmlLoc: String): File { + fun writeToNetCdf(ncmlLoc: String): File { val netCdfFile = createTempFile() val netCdfLoc = netCdfFile.absolutePath javaClass.getResourceAsStream(ncmlLoc).use { ncml -> - NcMLReader.writeNcMLToFile(ncml, netCdfLoc) + NcMLReader.writeNcMLToFile(ncml, netCdfLoc, NetcdfFileWriter.Version.netcdf4, null) } return netCdfFile } + + /** + * Convert a NCML resource into a [NetcdfFile] in memory. + * @param ncmlLoc The location of the NCML resource. + * @return The NetCDF file representation. + */ + fun readAsNetCdf(ncmlLoc: String): NetcdfFile { + return javaClass.getResourceAsStream(ncmlLoc).use { ncml -> + NcMLReader.readNcML(ncml, null) + } + } } \ No newline at end of file diff --git a/binary-array-ld-test/src/main/resources/netcdf/prefix-attr-error.cdl b/binary-array-ld-test/src/main/resources/netcdf/prefix-attr-error.cdl new file mode 100644 index 0000000..acb589d --- /dev/null +++ b/binary-array-ld-test/src/main/resources/netcdf/prefix-attr-error.cdl @@ -0,0 +1,13 @@ +netcdf prefix { + dimensions: + d0 = 1 ; + d1 = 1 ; + variables: + int var0 ; + int var1 ; + :bald__isPrefixedBy = 100; + group: prefix_list { + :bald__ = "https://www.opengis.net/def/binary-array-ld/"; + :skos__ = "http://www.w3.org/2004/02/skos/core#"; + } +} \ No newline at end of file diff --git a/binary-array-ld-test/src/main/resources/netcdf/prefix-group-error.cdl b/binary-array-ld-test/src/main/resources/netcdf/prefix-group-error.cdl new file mode 100644 index 0000000..1cf9faf --- /dev/null +++ b/binary-array-ld-test/src/main/resources/netcdf/prefix-group-error.cdl @@ -0,0 +1,13 @@ +netcdf prefix { + dimensions: + d0 = 1 ; + d1 = 1 ; + variables: + int var0 ; + int var1 ; + :bald__isPrefixedBy = "not_prefix_list"; + group: prefix_list { + :bald__ = "https://www.opengis.net/def/binary-array-ld/"; + :skos__ = "http://www.w3.org/2004/02/skos/core#"; + } +} \ No newline at end of file diff --git a/binary-array-ld-test/src/main/resources/netcdf/prefix-uri-error.cdl b/binary-array-ld-test/src/main/resources/netcdf/prefix-uri-error.cdl new file mode 100644 index 0000000..16095ff --- /dev/null +++ b/binary-array-ld-test/src/main/resources/netcdf/prefix-uri-error.cdl @@ -0,0 +1,13 @@ +netcdf prefix { + dimensions: + d0 = 1 ; + d1 = 1 ; + variables: + int var0 ; + int var1 ; + :bald__isPrefixedBy = "prefix_list"; + group: prefix_list { + :bald__ = "https://www.opengis.net/def/binary-array-ld/"; + :skos__ = 100; + } +} \ No newline at end of file diff --git a/binary-array-ld-test/src/main/resources/netcdf/prefix-var.cdl b/binary-array-ld-test/src/main/resources/netcdf/prefix-var.cdl new file mode 100644 index 0000000..e51d28b --- /dev/null +++ b/binary-array-ld-test/src/main/resources/netcdf/prefix-var.cdl @@ -0,0 +1,13 @@ +netcdf identity { + dimensions: + d0 = 1 ; + d1 = 1 ; + variables: + int var0 ; + int var1 ; + int prefix_list ; + prefix_list:bald__ = "https://www.opengis.net/def/binary-array-ld/"; + prefix_list:skos__ = "http://www.w3.org/2004/02/skos/core#"; + + :bald__isPrefixedBy = "prefix_list"; +} \ No newline at end of file diff --git a/binary-array-ld-test/src/main/resources/netcdf/prefix.cdl b/binary-array-ld-test/src/main/resources/netcdf/prefix.cdl new file mode 100644 index 0000000..09671f6 --- /dev/null +++ b/binary-array-ld-test/src/main/resources/netcdf/prefix.cdl @@ -0,0 +1,13 @@ +netcdf identity { + dimensions: + d0 = 1 ; + d1 = 1 ; + variables: + int var0 ; + int var1 ; + :bald__isPrefixedBy = "prefix_list"; + group: prefix_list { + :bald__ = "https://www.opengis.net/def/binary-array-ld/"; + :skos__ = "http://www.w3.org/2004/02/skos/core#"; + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 958049a..432b56d 100644 --- a/pom.xml +++ b/pom.xml @@ -109,6 +109,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + +