Skip to content

OWL to Java generates a Java class model from an ontology defined using the W3C Web Ontology Language (OWL). The models are built by taking a specified list of OWL classes and creating Java classes for those OWL classes and their properties.

License

antonycc/owl-to-java

Repository files navigation

owl-to-java

build checks commit activity last commit

OWL to Java generates a Java class model from an ontology defined using the W3C Web Ontology Language (OWL). The models are built by taking a specified list of OWL classes and creating Java classes for those OWL classes and their properties.

Mission statement:

Be a useful bridge between ontologies defined using open standards and object models
which are of immediate practical use in applications.

Done

OWL to Java currently:

  • Includes Java class mappings to OWL and RDF elements.
  • Parses an OWL ontology into a map of java classes.
  • Generates Java source from an OWL ontology in a local file.
  • Runs as a Gradle Task
  • Creates Java Source that compiles
  • Publish to GitHub packages (0.1.1)

Bugs

  • None listed

TODO

  • Graph DB annotations + graph example
  • Lombok annotations
  • Graphical viewer + example
  • KDoc for code
  • Java Docs for output
  • Public website
  • Publish Detekt and Kover reports from the Quality Report Build
  • Consider progress against additional GitHub README badges.
  • GitHub and public website analytics
  • Donate option (linked to hosting account)
  • Automate library updates
  • Contributor guidelines
  • Library Launch: Release to Maven Central
  • Command-line execution from a shaded Jar
  • RDBMS annotations + relational example
  • Command line Examples
  • Command-line execution from a Docker container
  • Release to DockerHub
  • HATEOAS REST API
  • API docs with runnable swagger
  • REST API examples
  • Text based viewer
  • Examples that scrape groups of sites using something like https://github.com/creative-mines/schemaorg4j
  • Dashboard for Person data showing demographics and interpersonal connections
  • Platform Launch: API based generation and viewer
  • Kotlin idioms
  • Profiling
  • Non-failing report job and parallel multiple failing check job
  • Auto-fix and submit PR
  • Check and auto accept PR
  • Inheritance by interface (via Lombok, or better in Kotlin?) and aggregation
  • Handling of plurals as collections e.g. Person.parent is a relationship with multiplicity
  • Load configuration set by name e.g. (com.example.OwlToJavaConfigSetSchemaOrg.setTaskConfig(this))
  • Load configuration from Kotlin Script: https://kotlinexpertise.com/run-kotlin-scripts-from-kotlin-programs/
  • Read multiple files (as an overlay)
  • Pull strings into a multi-lingual template resource
  • Add a parameterised fuzzy match (regex) instead of the OwlParser's match of the last 3 characters
  • Extend one schema with another (by supporting mappings between schemas)
  • @since versioned annotation on tests and auto-generated version history to CHANGELOG.md
  • Review approach to guidance and help used here: https://github.com/researchgate/gradle-release

Annoyances

  • Dependency org.simpleframework:simple-xml:2.7.1 is vulnerable
CVE-2017-1000190 9.1 Improper Restriction of XML External Entity Reference vulnerability pending CVSS allocation
Results powered by Checkmarx(c)
  • đź«™ No valid plugin descriptors were found in META-INF/gradle-plugins

Example of Kotlin script evaluation

val script = compile("""listOf(1,2,3).joinToString(":")""")
assertEquals(listOf(1, 2, 3).joinToString(":"), script.eval())

val regenerate by registering(RegenerateOntologyTask::class) {
    compile(File(Paths.get("${projectDir}/owl2java-schema.org.config").absolutePath()).load()).eval(this)
}

See also

Examples:

Build with tests which generate Java Sources:

 % ./gradlew clean test                                                       
Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details

> Configure project :
WARNING: Unsupported Kotlin plugin version.
The `embedded-kotlin` and `kotlin-dsl` plugins rely on features of Kotlin `1.5.31` that might work differently than in the requested version `1.7.0-RC2`.

BUILD SUCCESSFUL in 22s
7 actionable tasks: 7 executed
 % 

The first 20 lines of Person Java object generated from a Parsed Schema.org OWL Schema describing humanity:

 % head -30 ./build/generated-sources/uk/co/polycode/org/schema/Person.java
package uk.co.polycode.org.schema;

import java.lang.String;
import java.time.ZonedDateTime;

/**
 * Person
 *
 * A person (alive, dead, undead, or fictional).
 *
 * This file was generated by OWL to Java as a transformation of the Schema.org schema Version 14.0.
 * Schema.org is released under the Creative Commons Attribution-ShareAlike License (version 3.0). 
 * The Schema.org license is applicable to the generated source files and the license is available from 
 * "<a href="https://creativecommons.org/licenses/by-sa/3.0/">...</a>"
 */
public class Person extends Thing {
	/**
	 * Where to find the definition of the OWL Class used to generate this Java class.
	 */
	public String isDefinedBy = "https://schema.org/Person";

	/**
	 * An additional name for a Person, can be used for a middle name.
	 */
	public String additionalName;

	/**
	 * Physical address of the item.
	 */
	public PostalAddress address;

	// truncated...
}

Examples:

Clone, build and publish to the local Maven repository (e.g. To use am unpublished Gradle Task fork in another project.):

 % git clone <owl-to-java>
 % cd <owl-to-java>
 % ./gradlew build publishToMavenLocal  
...BUILD SUCCESSFUL in 2m 35s...
 % find ~/.m2 -name "owl-to-java*.jar"
.../.m2/repository/co/uk/polycode/owl-to-java/0.0.5-SNAPSHOT/owl-to-java-0.0.5-SNAPSHOT.jar
 % 

Generating Java sources with default settings using a Gradle Task called "regenerate" in Gradle's Kotlin DSL:

buildscript {
    repositories {
        mavenLocal() // OWL to Java Task would be in local
    }
    dependencies {
        classpath("co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT")
    }
}

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

tasks {
    // Regenerate Java classes for schema.org using the OWL schema and default options
    val regenerate by registering(uk.co.polycode.owltojava.RegenerateOntologyTask::class) {
        outputs.upToDateWhen { false }
        val srcMain: String = Paths.get("${projectDir}/../src/main").toFile().absolutePath
        val sourceFileName = "schemaorg.owl"
        lang = "en"
        src = Paths.get("${srcMain}/resources/${sourceFileName}").toFile()
        dest = Paths.get("${srcMain}/java").toFile()
        javaBasePackage = "uk.co.polycode.ontology.with-defaults"
    }
}

Generating Java sources with default settings using a Gradle Task called "regenerate" in Gradle's Groovy DSL:

import java.nio.file.Paths

buildscript {
    repositories {
        mavenLocal() // OWL to Java Task would be in local
        mavenCentral()
    }
    dependencies {
        classpath 'co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT'
    }
}

repositories {
    mavenCentral()
}

// Override default library Task with:
//    ./gradlew regenerate -PuseIncludedBuild=regenerate-lib-with-groovy
tasks.register("regenerate", uk.co.polycode.owltojava.RegenerateOntologyTask) { //regenerateTask ->
    // Configure regenerateTask
    regenerate.outputs.upToDateWhen {false}
    def srcMain = Paths.get(projectDir.absolutePath + "/../src/main").toFile().absolutePath
    def sourceFileName = "schemaorg.owl"
    regenerate.lang = "en"
    regenerate.src = Paths.get(srcMain + "/resources/" + sourceFileName).toFile()
    regenerate.dest = Paths.get(projectDir.absolutePath + "/../build/generated-src-with-groovy").toFile()
    regenerate.javaBasePackage = "uk.co.polycode.ontology.with-groovy"
}

Generating Java sources with primitive types defined settings using Kotlin:

val srcTestResources = "./src/test/resources"
val wholeOwlFilePath = Paths.get("${srcTestResources}/schemaorg.owl")
val javaSourceDirectoryPath = Paths.get("./build/generated-sources")
val javaBasePackage = "uk.co.polycode"
val primitivePropertyTypes = mapOf(
    "https://schema.org/DataType" to Object::class.java.name,
    "https://schema.org/Text"     to String::class.java.name,
    "https://schema.org/Time"     to ZonedDateTime::class.java.name,
    "https://schema.org/DateTime" to ZonedDateTime::class.java.name,
    "https://schema.org/Date"     to ZonedDateTime::class.java.name,
    "https://schema.org/URL"      to URL::class.java.name,
    "https://schema.org/Integer"  to BigInteger::class.java.name,
    "https://schema.org/Float"    to BigDecimal::class.java.name,
    "https://schema.org/Number"   to BigDecimal::class.java.name,
    "https://schema.org/Boolean"  to "java.lang.Boolean", // Boolean::class.java.name, unboxes to boolean.
)
val taskDelegateWithDefaults = RegenerateOntologyTaskDelegate(
        src = wholeOwlFilePath.toFile(),
        dest = javaSourceDirectoryPath.toFile(),
        javaBasePackage = javaBasePackage).also {
        it.primitivePropertyTypes = this.primitivePropertyTypes
    }
taskDelegateWithDefaults.regenerateJavaSource()

Generating Java sources with settings tuned for this POJO library using a Gradle Task called "regenerate":

buildscript {
    repositories {
        mavenLocal() // OWL to Java Task would be in local
    }
    dependencies {
        classpath("co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT")
    }
}

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

tasks {
    val regenerate by registering(uk.co.polycode.owltojava.RegenerateOntologyTask::class) {
        outputs.upToDateWhen { false }
        val srcMain: String = Paths.get("${projectDir}/../src/main").toFile().absolutePath
        val sourceFileName = "schemaorg.owl"
        lang = "en"
        src = Paths.get("${srcMain}/resources/${sourceFileName}").toFile()
        dest = Paths.get("${srcMain}/java").toFile()
        javaBasePackage = "uk.co.polycode.ontology.lib"
        licenceText = """
            This file was generated by OWL to Java as a transformation of the Schema.org schema Version 14.0.
            Schema.org is released under the Creative Commons Attribution-ShareAlike License (version 3.0). 
            The Schema.org license is applicable to the generated source files and the license is available from 
            https://creativecommons.org/licenses/by-sa/3.0/
            """
        classes = listOf(
            "https://schema.org/Person",
            "https://schema.org/City",
            "https://schema.org/CorporationX",
            "https://schema.org/Project",
            "https://schema.org/Book",
            "https://schema.org/Article",
            "https://schema.org/Fake"
        )
        primitivePropertyTypes = mapOf(
            "https://schema.org/DataType" to Object::class.java.name,
            "https://schema.org/Text"     to String::class.java.name,
            "https://schema.org/Time"     to ZonedDateTime::class.java.name,
            "https://schema.org/DateTime" to ZonedDateTime::class.java.name,
            "https://schema.org/Date"     to ZonedDateTime::class.java.name,
            "https://schema.org/URL"      to URL::class.java.name,
            "https://schema.org/Integer"  to BigInteger::class.java.name,
            "https://schema.org/Float"    to BigDecimal::class.java.name,
            "https://schema.org/Number"   to BigDecimal::class.java.name,
            "https://schema.org/Boolean"  to "java.lang.Boolean"
        )
        ignoredPropertyTypes = listOf(
            "https://schema.org/Role"
        )
        prunedPropertyTypes = listOf(
            "https://schema.org/Text",
            "https://schema.org/URL"
        )
        ignoredSuperclasses = listOf<String>(
            "https://www.w3.org/2000/01/rdf-schema#Class"
        )
    }
}

Contributions

Owl to Java uses Trunk based Development https://www.flagship.io/git-branching-strategies/#trunk-based-development

An alternate branching strategy is likely to be required when there are multiple committers. While a low volume of commits and committers remains we have two paths to contribute to this project:

  • Contact me via my GitHub profile (->website -> LinkedIn) and ask to be added to this project.
  • Fork the repository then create a pull request.

Versioning is assisted by the Semantic Version Gradle Plugin, see: https://github.com/dipien/semantic-version-gradle-plugin

 % ./gradlew printVersion                                 
Version: 0.0.1-SNAPSHOT
 % ./gradlew incrementVersion --versionIncrementType=PATCH
 ...
 % ./gradlew printVersion                                 
Version: 0.0.2-SNAPSHOT
 % 

Request a feature

To request a new feature:

  1. Add an item to the TODO list

(see above for paths to contribute to this project).

Add a feature

To add a new feature:

  1. Pick a feature from this README.md
  2. Create at least one test for the feature, cut and paste the TODO list item into the test comment
  3. Build using gradle build
  4. Commit code which passes gradle clean check -PsafeBuildMode=false
  5. Get the commit hash using git rev-parse HEAD and add it to the test KDoc.

e.g.

    /**
     *  Support all classes as the default
     *  @since("Commit hash: e66cfd2dedd09bb496ac852a630ee1fb62466533")
     */
    @Test
    fun testExpectedClassInSkeletonClassMapWithDefaults() {
        // truncated...
    }

Licences

To generate a dependency license report, use Gradle License Report plugin. See https://github.com/jk1/Gradle-License-Report

 % ./gradlew generateLicenseReport
BUILD SUCCESSFUL in 3s
 % head -5 build/reports/dependency-license/index.html

<html>
<head>
    <title>
        Dependency License Report for owl-to-java
 % 

Licence - OWL to Java

OWL to Java is released under the Mozilla Public License, v. 2.0:

/**
 * OWL to Java generates Source Code from the W3C Web Ontology Language (OWL)
 * Copyright (C) 2022  Antony Cartwright, Polycode Limited
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * Mozilla Public License, v. 2.0 for more details.
 */

Licence - Schema.org

OWL to Java uses the Schema from Schema.org which is released under the Creative Commons Attribution-ShareAlike License (version 3.0): https://creativecommons.org/licenses/by-sa/3.0/ Schema.org Version 14.0 is currently used and this can be downloaded from https://schema.org/docs/schemaorg.owl ( Release archive: https://github.com/schemaorg/schemaorg/tree/main/data/releases/14.0/ ) The following files are copies of or derivatives of Schema.org schemas:

./src/test/resources/schemaorg.owl - Schema.org Version 14.0: copy of https://schema.org/docs/schemaorg.owl
./src/test/resources/schemaorg-minimal-person.owl - Schema.org Version 10: Cut down copy orientated aroung Person
./src/test/resources/schemaorg-skeleton.owl - Schema.org Version 10: Cut down smallest meaningful ontology

Fragment of these files are referenced in OWL to Java source code and tests

Licence - Semantic Version Gradle Plugin

OWL to Java used the Semantic Version Gradle Plugin which is released under the Apache License Version 2.0, January 2004: http://www.apache.org/licenses/ The following files are copies of or derivatives of Semantic Version Gradle Plugin source:

.github/workflows/increment_version.yml
  - Copy of https://github.com/dipien/semantic-version-gradle-plugin/blob/master/.github/workflows/increment_version.yml

About

OWL to Java generates a Java class model from an ontology defined using the W3C Web Ontology Language (OWL). The models are built by taking a specified list of OWL classes and creating Java classes for those OWL classes and their properties.

Topics

Resources

License

Stars

Watchers

Forks