Skip to content

Utilities#

Providing convenient helper classes for the piveau context

Build & Install#

Requirements:

  • Git
  • Maven 3
  • Java 11
$ git clone https://gitlab.com/piveau/utilities/piveau-utils.git
$ cd piveau-utils
$ mvn install

Use#

Add repository to your project pom file:

<repository>
    <id>paca</id>
    <name>paca</name>
    <url>https://paca.okd.fokus.fraunhofer.de/repository/maven-public/</url>
</repository>

Add dependency to your project pom file:

<dependency>
    <groupId>io.piveau.utils</groupId>
    <artifactId>piveau-utils</artifactId>
    <version>4.2.0</version>
</dependency>

APIs#

RDF#

General RDF helper and extensions

Hydra#

This API provides an implementation of the PagedCollection defined in the Hydra Core Vocabulary, a vocabulary for hypermedia-driven Web APIs.

val paging = findHydraPaging(model)
val total = paging.total ?: -1
val next = paging.next
HydraPaging paging = HydraPaging.findPaging(model);
int total = paging.getTotal() != null ? paging.getTotal() : -1;
String next = paging.getNext();

In some cases the provider uses the paging incorrectly. In these cases you can provide a base URI, and the class will try to fix the misbehaviour.

val paging = findHydraPaging(model, baseUri)
HydraPaging paging = HydraPaging.findPaging(model, baseUri);

The implementation currently only supports total items and next page.

Geo parsing#

Simple Method to convert an RDF Literal into a geo json object. The literal may be one of the following formats:

  • application/vnd.geo+json
  • http://www.openlinksw.com/schemas/virtrdf#Geometry
  • http://www.opengis.net/ont/geosparql#gmlLiteral

In all other cases and on any parsing problems the method returns an empty json object.

val jsonObject = parseGeoLiteral(geoLiteral)
JsonObject jsonObject = GeoParsingKt.parseGeoLiteral(geoLiteral);

Pre-Processing#

Apache Jena extensions#

Triple Hash#

RDF Vocabularies#

Common RDF vocabularies and concept schemes

DCAT-AP model builder#

POJOs for building DCAT-AP dataset graphs

DCAT-AP model parser#

Parsing rdf graphs for DCAT-AP classes and properties

DCAT-AP SPARQL triple store#

Connecting your app to a triple store following a DCAT-AP naming scheme

Using a DCAT-AP namespace schema#

DCATAPUriSchema.config = json {
    obj {
        "baseUri" to "https://piveau.io/"
        "catalogueContext" to "id/catalogues/"
        "datasetContext" to "set/data/"
        "distributionContext" to "set/distribution/"
        "recordContext" to "set/record/"
        "metricsContext" to "id/metrics/"
    }
}
DCATAPUriSchema.setConfig(new JsonObject()
        .put("baseUri", "https://piveau.io/")
        .put("catalogueContext", "id/catalogues/")
        .put("datasetContext", "set/data/")
        .put("distributionContext", "set/distribution/")
        .put("recordContext", "set/record/")
        .put("metricsContext", "id/metrics/"));

These are the default values. You can just override some or all of them if required.

The two main methods of this singleton is to parse a given uriRef and tells you what it is, and to generate a uriRef from a given external identifier

// check uri ref type
when {
    DCATAPUriSchema.isCatalogueUriRef(uriRef) -> {}
    DCATAPUriSchema.isDatasetUriRef(uriRef) -> {}
    DCATAPUriSchema.isDistributionUriRef(uriRef) -> {}
    DCATAPUriSchema.isRecordUriRef(uriRef) -> {}
    DCATAPUriSchema.isMetricsUriRef(uriRef) -> {}
    else -> {}
}

// parse given URIRef and provide a DCATAPUriRef
val dcatapUriRef = DCATAPUriSchema.parse(uriRef)

// context & id
val context = dcatapUriRef.context
val id = dcatapUriRef.id

// generate from external id.
val uriRef = DCATAPUriSchema.applyFor(externalId) 
// check uri ref type
if (DCATAPUriSchema.isCatalogueUriRef(uriRef)) {
} else if (DCATAPUriSchema.isDatasetUriRef(uriRef) {
} else if (DCATAPUriSchema.isDistributionUriRef(uriRef)) {
} else if (DCATAPUriSchema.isRecordUriRef(uriRef)) {
} else if (DCATAPUriSchema.isMetricsUriRef(uriRef)) {
} else {
}

// parse given URIRef and provide a DCATAPUriRef
DCATAPUriRef dcatapUriRef = DCATAPUriSchema.parse(uriRef);

// context & id
String context = dcatapUriRef.getContext();
String id = dcatapUriRef.getId();

// generate from external id.
DCATAPUriRef uriRef = DCATAPUriSchema.applyFor(externalId); 

Creating and configuring the triple store:#

val config = json {
    obj ("address" to "http://piveau-virtuoso:8890")   
}

val tripleStore = TripleStore(vertx, config)
JsonObject config = new JsonObject().put("address", "http://piveau-virtuoso:8890");
TripleStore tripleStore = new TripleStore(vertx, config);

with explicit WebClient

val client = WebClient.create(vertx)
val tripleStore = TripleStore(vertx, config, client)
WebClient client = WebClient.create(vertx);
TripleStore tripleStore = new TripleStore(vertx, config, client);

Using DCAT-AP specific managers#

The triple store comes with a set of DCAT-AP specific managers:

val catalogueManager = tripleStore.catalaogueManager
val datasetManager = tripleStore.datasetManager
val metricsManager = tripleStore.metricsManager
CatalogueManager catalogueManager = tripleStore.getCatalaogueManager();
DatasetManager datasetManager = tripleStore.getDatasetManager();
MetricsManager metricsManager = tripleStore.getMetricsManager();

Each manager provides a convenient API to deal with the corresponding DCAT-AP range. E.g.:

datasetManager.identify("datasetId", "catalogueId") {
    when {
        it.succeeded() -> {
            val (datasetResource, recordResource) = it.result()
        }
        else -> {}
    }
}
datasetManager.identify("datasetId", "catalogueId", ar -> {
    if (ar.succeeded()) {
        Resource datasetResource = ar.result().getFirst();
        Resource recordResource = ar.result().getSecond();

    } else {
    }
});

The managers rely heavenly on the DCATAPUriSchema, so make sure it is properly configured for your needs.

DQV extensions#

Building and managing DQV graphs

piveau Logging#

Convenient logging classes to log to a centralized ElasticStack instance

You need to create a PiveauContext in order to get access to the piveau logger.

val piveauContext = createPiveauContext("serviceName", "moduleName")
piveauContext.log.debug("I am here.")
PiveauContext piveauContext = PiveauContext.create("serviceName", "moduleName");
piveauContext.log().debug("I am here.");

The logger supports a slf4j style api.

You can extend the context for a specific resource:

val resourceContext = piveauContext.extend("resourceId")
resourceContext.log.debug("I am an extended resource.")
PiveauContext resourceContext = piveauContext.extend("resourceId");
resourceContext.log().debug("I am an extended resource.");

Triple store mock up server for testing#

A simple mock triple store for testing purposes

What else...#

All the rest

Normalize date time#

val dateTime = normalizeDateTime("2019-07-01T12:00:20.00+02")
String dateTime = DateTimeKt.normalizeDateTime("2019-07-01T12:00:20.00+02");

It returns the date or datetime as ISO-8601 instant standard string ("2019-07-01T14:00:20Z").

CORS helper#

To help you with the Vert.x CorsHandler.

CorsHelper(corsDomains).addRootHandler(routerBuilder)

// it is also possible to get assign the handler to a specific route yourself:

routerBuilder.route("/cors").handler(CorsHelper(corsDomains).handler)
new CorsHelper(corsDomains).addRootHandler(routerBuilder);

// it is also possible to get assign the handler to a specific route yourself:

routerBuilder.route("/cors").handler(new CorsHelper(corsDomains).handler)

If you want more customization options regarding the allowed Headers or Methods, you can overwrite the internal standard lists

val allowedHeaders = setOf<String>(
"x-requested-with",
"Access-Control-Allow-Origin",
"origin",
"Content-Type",
"accept");

val allowedMethods = setOf<HttpMethod>(HttpMethod.GET, HttpMethod.POST);

CorsHelper(corsDomains, allowedHeaders, allowedMethods).addRootHandler(routerBuilder)
Set<String> allowedHeaders = setOf<String>(
"x-requested-with",
"Access-Control-Allow-Origin",
"origin",
"Content-Type",
"accept");

Set<HttpMethod> allowedMethods = Set.of(HttpMethod.GET, HttpMethod.POST);

CorsHelper ch = new CorsHelper(corsDomains, allowedHeaders, allowedMethods);
ch.addRootHandler(routerBuilder);

Vert.x JsonObject and JsonArray extensions#

Although these extensions are most useful in Kotlin, you can use them also in Java.

val jsonObj = JsonObject()

// Put only if value is not null
jsonObj.putIfNotNull("key", value)
// Put only if json object is not empty
jsonObj.putIfNotEmpty("key", obj)

// Return json object of key or create a new one if not already exist. 
val obj = jsonObj.withJsonObject("key")
// Return json array of key or create a new one if not already exist. 
val array = jsonObj.withJsonArray("key")

// Forces key as `JsonObject`, even if it is a string   
val obj = jsonObj.asJsonObject("key")
// Forces key as `JsonArray`, even if it is a string   
val array = jsonObj.asJsonArray("key")

val jsonArray = JsonArray()
// Add only if value is not null
jsonArray.addIfNotNull(value)
// Add only if json object is not empty
jsonArray.addIfNotEmpty(obj)
JsonObject jsonObj = new JsonObject();

// Put only if value is not null
JsonExtensions.putIfNotNull(jsonObj, "key", value);
// Put only if json object is not empty
JsonExtensions.putIfNotEmpty(jsonObj, "key", obj);

// Return json object of key or create a new one if not already exist. 
JsonObject obj = JsonExtensions.withJsonObject(jsonObj, "key");
// Return json array of key or create a new one if not already exist. 
JsonArray array = JsonExtensions.withJsonArray(jsonObj, "key");

// Forces key as `JsonObject`, even if it is a string   
JsonObject obj = JsonExtensions.asJsonObject(jsonObj, "key");
// Forces key as `JsonArray`, even if it is a string   
JsonArray array = JsonExtensions.asJsonArray(jsonObj, "key");

JsonArray jsonArray = new JsonArray();
// Add only if value is not null
JsonExtensions.addIfNotNull(jsonArray, value);
// Add only if json object is not empty
JsonExtensions.addIfNotEmpty(jsonArray, obj);

Config helper#

Deprecated

Please use general Vert.x Json extension functions!

val jsonObject = config.asJsonObject("key")
val jsonArray = config.asJsonArray("key")
// Old way
JsonObject jsonObject = ConfigHelper.forConfig(config).forceJsonObject("key");
JsonObject jsonArray = ConfigHelper.forConfig(config).forceJsonArray("key");

// New way
JsonObject jsonObject = JsonExtensions.asJsonObject(config, "key");
JsonObject jsonArray = JsonExtensions.asJsonArray(config, "key");