diff --git a/.development/coolrdf-eclipse-code-style.xml b/.development/coolrdf-eclipse-code-style.xml new file mode 100644 index 00000000..b931f82b --- /dev/null +++ b/.development/coolrdf-eclipse-code-style.xml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.development/coolrdf-eclipse.importorder b/.development/coolrdf-eclipse.importorder new file mode 100644 index 00000000..aae7aba0 --- /dev/null +++ b/.development/coolrdf-eclipse.importorder @@ -0,0 +1,6 @@ +#Organize Import Order +#Tue Dec 30 12:34:00 CET 2025 +0=java +1=javax +2=org +3=com diff --git a/.development/coolrdf-intellij-code-style.xml b/.development/coolrdf-intellij-code-style.xml new file mode 100644 index 00000000..dcb47ed8 --- /dev/null +++ b/.development/coolrdf-intellij-code-style.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + diff --git a/docs/settings.gradle b/.development/coolrdf-license-header.txt similarity index 80% rename from docs/settings.gradle rename to .development/coolrdf-license-header.txt index 8fe75cd7..e8ec0efd 100644 --- a/docs/settings.gradle +++ b/.development/coolrdf-license-header.txt @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,5 +14,3 @@ * limitations under the License. */ -rootProject.name = 'docs' -include ':cli' diff --git a/.editorconfig b/.editorconfig index d7459b72..aac5a8f3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,11 +7,11 @@ end_of_line = lf [*.java] insert_final_newline = true indent_style = space -indent_size = 4 +indent_size = 3 trim_trailing_whitespace = true -max_line_length = 120 +max_line_length = 140 [build.gradle] indent_style = space -indent_size = 4 +indent_size = 3 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 294aaf7c..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,264 +0,0 @@ -name: build - -on: - push: - branches: 'main' - tags-ignore: - - 'v**' - pull_request: - branches: '*' - -jobs: - build-linux: - runs-on: ubuntu-latest - timeout-minutes: 30 - env: - OS: Ubuntu - name: ubuntu - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle-v2- - - name: Setup Environment - # - Install SDKMAN - # - Install msttcorefonts, so we have the Verdana font available for diagram generation - # - Install graphviz, so we have the dot binary available for diagram generation - # - Install GraalVM 21.3.0.r17 (JDK 17) - # - Clean Antora cache - run: |- - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - ls /etc/apt/sources.list.d - find /etc/apt -type f -name '*.list' -exec sed -i -e '/dl.bintray.com\/sbt/d' "{}" \; - sudo apt-get update - echo msttcorefonts msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections - sudo apt-get install ttf-mscorefonts-installer - sudo apt-get install -y graphviz - sudo apt-get install -y build-essential libz-dev - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - gu install native-image - unset _JAVA_OPTIONS - echo Path settings: $PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - rm -rf .cache - - name: Gradle Build - run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check jacocoRootReport nativeImage integrationTest antora --stacktrace --no-daemon - - name: Run UPX - uses: crazy-max/ghaction-upx@v1.4.0 - with: - version: latest - files: cli/build/bin/owl - args: -9 - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2 - with: - name: codecov-umbrella - env_vars: OS - - name: Prepare Artifacts - run: |- - mv cli/build/bin/owl owl-x86_64-linux-snapshot - mv cli/build/libs/owl-cli-snapshot.jar . - - name: Upload Linux Artifacts - uses: actions/upload-artifact@v2 - with: - name: artifacts-linux - path: | - owl-x86_64-linux-snapshot - owl-cli-snapshot.jar - - name: Deploy GH Pages - uses: JamesIves/github-pages-deploy-action@4.1.0 - with: - branch: gh-pages - folder: build/site - - build-macos: - runs-on: macos-latest - timeout-minutes: 30 - env: - OS: Macos - name: macos - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle-v2- - - name: Setup Environment - # - Install SDKMAN - # - Install graphviz, so we have the dot binary available for diagram generation - # - Install GraalVM 21.3.0.r17 (JDK 17) - # - Clean Antora cache - run: |- - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - brew install graphviz - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - gu install native-image - unset _JAVA_OPTIONS - echo Path settings: $PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - rm -rf .cache - - name: Gradle Build - run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check nativeImage integrationTest --stacktrace --no-daemon - - name: Prepare Artifacts - run: mv cli/build/bin/owl owl-x86_64-apple-darwin-snapshot - - name: Upload Macos Artifacts - uses: actions/upload-artifact@v2 - with: - name: artifacts-macos - path: owl-x86_64-apple-darwin-snapshot - - build-windows: - runs-on: windows-latest - timeout-minutes: 30 - env: - OS: Windows - name: windows - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: ilammy/msvc-dev-cmd@v1.10.0 - - uses: microsoft/setup-msbuild@v1.1 - - name: Configure Pagefile - # Fix for "LINK : fatal error LNK1171: unable to load mspdbcore.dll (error code: 1455)": - # This seems to be caused by running out of memory; increasing page file - # size suggested here: - # https://github.com/actions/virtual-environments/issues/3420#issuecomment-861342418 - uses: al-cheb/configure-pagefile-action@v1.2 - with: - minimum-size: 16GB - maximum-size: 16GB - disk-root: "C:" - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle-v2- - - name: Setup Environment - # - Install SDKMAN - # - Install graphviz, so we have the dot binary available for diagram generation - # - Install GraalVM 21.3.0.r17 (JDK 17) - # - Clean Antora cache - run: |- - choco install zip --execution-timeout=600 - choco install unzip --execution-timeout=600 - choco install graphviz --execution-timeout=600 - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - echo Path settings: $PATH - export PATH=$HOME/.sdkman/candidates/java/current/lib/installer/bin:$PATH - export GRAALVM_HOME=$HOME/.sdkman/candidates/java/17.0.8-graal - gu.cmd install native-image - find $HOME/.sdkman -type f -name '*native-image*' - unset _JAVA_OPTIONS - export PATH=$HOME/.sdkman/candidates/java/current/lib/svm/bin:$PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - rm -rf .cache - shell: bash - - name: Gradle Build - run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check nativeImage integrationTest --info --stacktrace --no-daemon - shell: bash - - name: Prepare Artifacts - run: mv cli/build/bin/owl owl-x86_64-windows-snapshot.exe - shell: bash - - name: Run UPX - uses: crazy-max/ghaction-upx@v1.4.0 - with: - version: latest - files: ./*.exe - args: -9 - - name: Upload Windows Artifacts - uses: actions/upload-artifact@v2 - with: - name: artifacts-windows - path: owl-x86_64-windows-snapshot.exe - - publish: - needs: [build-linux, build-macos, build-windows] - runs-on: ubuntu-latest - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Fetch Linux Artifacts - uses: actions/download-artifact@v2 - with: - name: artifacts-linux - - name: Fetch Macos Artifacts - uses: actions/download-artifact@v2 - with: - name: artifacts-macos - - name: Fetch Windows Artifacts - uses: actions/download-artifact@v2 - with: - name: artifacts-windows - - name: Push Snapshot Release - uses: "marvinpinto/action-automatic-releases@latest" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - automatic_release_tag: "snapshot" - prerelease: true - title: "Snapshot Build" - files: |- - owl-cli-snapshot.jar - owl-x86_64-linux-snapshot - owl-x86_64-apple-darwin-snapshot - owl-x86_64-windows-snapshot.exe - - buildDone: - name: Build Ok - needs: publish - runs-on: ubuntu-latest - steps: - - name: Build Ok - run: echo 'all builds passed' diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 00000000..4c76cd80 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,131 @@ +name: Build Pull Request +on: + pull_request: + branches: + - main +jobs: + build-and-test: + name: Build ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ windows-latest, ubuntu-20.04, macos-latest ] + include: + - os: windows-latest + binary-file-extension: .exe + - os: ubuntu-20.04 + binary-file-extension: '' + - os: macos-latest + binary-file-extension: '' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + # - Install msttcorefonts, so we have the Verdana font available for diagram generation + # - Install graphviz, so we have the dot binary available for diagram generation + run: |- + find /etc/apt -type f -name '*.list' -exec sed -i -e '/dl.bintray.com\/sbt/d' "{}" \; + sudo apt-get update + echo msttcorefonts msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections + sudo apt-get install ttf-mscorefonts-installer + sudo apt-get install -y graphviz + sudo apt-get install -y build-essential libz-dev + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + # - Install graphviz, so we have the dot binary available for diagram generation + run: |- + choco install zip --execution-timeout=600 + choco install unzip --execution-timeout=600 + choco install graphviz --execution-timeout=600 + shell: bash + + - name: Install dependencies (MacOs) + if: runner.os == 'macOS' + # - Install graphviz, so we have the dot binary available for diagram generation + run: |- + brew install graphviz + + - name: Setup JDK + uses: graalvm/setup-graalvm@b8dc5fccfbc65b21dd26e8341e7b21c86547f61b # v1 + with: + java-version: '17.0.10' + distribution: 'graalvm' + components: 'native-image,js' + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: 'true' + + - name: Cache Maven packages + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + - name: Configure Pagefile (Windows) + if: runner.os == 'Windows' + # Fix for "LINK : fatal error LNK1171: unable to load mspdbcore.dll (error code: 1455)": + # This seems to be caused by running out of memory; increasing page file + # size suggested here: + # https://github.com/actions/virtual-environments/issues/3420#issuecomment-861342418 + uses: al-cheb/configure-pagefile-action@86589fd789a4de3e62ba628dda2cb10027b66d67 # v1.3 + with: + minimum-size: 32GB + maximum-size: 32GB + disk-root: "C:" + + - name: Set Swap Space (Linux) + if: runner.os == 'Linux' + uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # master + with: + swap-size-gb: 12 + + - name: Build and run tests + run: | + mvn -B clean install + mvn -B clean verify -pl cool-rdf-cli -Pnative + mv cool-rdf-cli/target/cool${{ matrix.binary-file-extension }} cool-rdf-cli/target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} + shell: bash + + - name: Switch to Temurin JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + overwrite-settings: false + + - name: Test executable jar on Temurin + if: runner.os == 'Linux' + run: | + mvn -B -Dskip.maven.surefire -pl cool-rdf-cli failsafe:integration-test@default + + - name: Compress executable + # UPX doesn't work on mac + if: runner.os != 'macOS' + uses: crazy-max/ghaction-upx@0fc45e912669ba9e8fa2b430e97c8da2a632e29b # v3.0.0 + with: + version: latest + files: cool-rdf-cli/target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} + args: -9 + + - name: Upload jar + # We only need one OS job to upload the jar + if: runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: cool-rdf-cli-jar + path: cool-rdf-cli/target/cool-rdf-cli-DEV-SNAPSHOT.jar + + - name: Upload executable + uses: actions/upload-artifact@v4 + with: + name: cool-rdf-cli-${{ runner.os }} + # .dlls only exist on Windows of course + path: | + cool-rdf-cli/target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} + cool-rdf-cli/target/*.dll diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c64900d0..843694f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,239 +1,212 @@ -name: release - +name: Release on: - push: - tags: - - 'v*.*.*' - + workflow_dispatch: + inputs: + release_version: + description: 'Version number' + required: true jobs: - build-linux: - runs-on: ubuntu-latest - timeout-minutes: 30 - env: - OS: Ubuntu - name: ubuntu + build: + name: Build ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ windows-latest, ubuntu-20.04, macos-latest ] + include: + - os: windows-latest + binary-file-extension: .exe + - os: ubuntu-20.04 + binary-file-extension: '' + - os: macos-latest + binary-file-extension: '' + steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle- - - name: Setup Environment - # - Install SDKMAN + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + # - Install msttcorefonts, so we have the Verdana font available for diagram generation # - Install graphviz, so we have the dot binary available for diagram generation - # - Install GraalVM 21.3.0.r17 (JDK 17) run: |- - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - ls /etc/apt/sources.list.d find /etc/apt -type f -name '*.list' -exec sed -i -e '/dl.bintray.com\/sbt/d' "{}" \; sudo apt-get update + echo msttcorefonts msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections + sudo apt-get install ttf-mscorefonts-installer sudo apt-get install -y graphviz sudo apt-get install -y build-essential libz-dev - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - gu install native-image - unset _JAVA_OPTIONS - echo Path settings: $PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - - name: Set env - run: echo "RELEASE_VERSION=$(grep version= gradle.properties | sed 's/.*=//')" >> $GITHUB_ENV - - name: Gradle Build - run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check nativeImage integrationTest --stacktrace --no-daemon - - name: Run UPX - uses: crazy-max/ghaction-upx@v1.4.0 - with: - version: latest - files: cli/build/bin/owl - args: -9 - - name: Prepare Artifacts - run: |- - mv cli/build/bin/owl owl-x86_64-linux-${RELEASE_VERSION} - mv cli/build/libs/owl-cli-${RELEASE_VERSION}.jar . - - name: Upload Linux Artifacts - uses: actions/upload-artifact@v2 - with: - name: artifacts-linux - path: | - owl-x86_64-linux-${{ env.RELEASE_VERSION }} - owl-cli-${{ env.RELEASE_VERSION }}.jar - - build-macos: - runs-on: macos-latest - timeout-minutes: 30 - env: - OS: Macos - name: macos - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle- - - name: Setup Environment - # - Install SDKMAN - # - Install GraalVM 21.3.0.r17 (JDK 17) - run: |- - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - brew install graphviz - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - gu install native-image - unset _JAVA_OPTIONS - echo Path settings: $PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - - name: Set env - run: echo "RELEASE_VERSION=$(grep version= gradle.properties | sed 's/.*=//')" >> $GITHUB_ENV - - name: Gradle Build - run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check nativeImage integrationTest --stacktrace --no-daemon - - name: Prepare Artifacts - run: mv cli/build/bin/owl owl-x86_64-apple-darwin-${RELEASE_VERSION} - - name: Upload Macos Artifacts - uses: actions/upload-artifact@v2 - with: - name: artifacts-macos - path: owl-x86_64-apple-darwin-${{ env.RELEASE_VERSION }} - - build-windows: - runs-on: windows-latest - timeout-minutes: 30 - env: - OS: Windows - name: windows - steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: ilammy/msvc-dev-cmd@v1.10.0 - - uses: microsoft/setup-msbuild@v1.1 - - name: Cache Gradle - uses: actions/cache@v2 - with: - path: ~/.gradle/caches/ - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: ${{ runner.os }}-gradle- - - name: Setup Environment - # - Install SDKMAN + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' # - Install graphviz, so we have the dot binary available for diagram generation - # - Install GraalVM 21.3.0.r17 (JDK 17) run: |- choco install zip --execution-timeout=600 choco install unzip --execution-timeout=600 choco install graphviz --execution-timeout=600 - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source $HOME/.sdkman/bin/sdkman-init.sh - sdk update - sdk list java - sdk install java 17.0.8-graal || true - sdk use java 17.0.8-graal - echo Path settings: $PATH - export PATH=$HOME/.sdkman/candidates/java/current/lib/installer/bin:$PATH - export GRAALVM_HOME=$HOME/.sdkman/candidates/java/17.0.8-graal - gu.cmd install native-image - find $HOME/.sdkman -type f -name '*native-image*' - unset _JAVA_OPTIONS - export PATH=$HOME/.sdkman/candidates/java/current/lib/svm/bin:$PATH - which native-image - which java - java -version - file `which native-image` - native-image --version - shell: bash - - name: Set env - run: echo "RELEASE_VERSION=$(grep version= gradle.properties | sed 's/.*=//')" >> $GITHUB_ENV shell: bash - - name: Gradle Build + + - name: Install dependencies (MacOs) + if: runner.os == 'macOS' + # - Install graphviz, so we have the dot binary available for diagram generation run: |- - source $HOME/.sdkman/bin/sdkman-init.sh - ./gradlew clean generateStaticProperties test check nativeImage integrationTest --info --stacktrace --no-daemon - shell: bash - - name: Prepare Artifacts - run: mv cli/build/bin/owl owl-x86_64-windows-${RELEASE_VERSION}.exe + brew install graphviz + + - name: Setup JDK + uses: graalvm/setup-graalvm@b8dc5fccfbc65b21dd26e8341e7b21c86547f61b # v1 + with: + java-version: '17.0.10' + distribution: 'graalvm' + components: 'native-image,js' + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: 'true' + + - name: Cache Maven packages + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + - name: Configure Pagefile (Windows) + if: runner.os == 'Windows' + # Fix for "LINK : fatal error LNK1171: unable to load mspdbcore.dll (error code: 1455)": + # This seems to be caused by running out of memory; increasing page file + # size suggested here: + # https://github.com/actions/virtual-environments/issues/3420#issuecomment-861342418 + uses: al-cheb/configure-pagefile-action@86589fd789a4de3e62ba628dda2cb10027b66d67 # v1.3 + with: + minimum-size: 32GB + maximum-size: 32GB + disk-root: "C:" + + - name: Set Swap Space (Linux) + if: runner.os == 'Linux' + uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # master + with: + swap-size-gb: 12 + + - name: Build and run tests + run: | + # Required for reactor dependencies + mvn -B clean install -DskipTests + mvn -B versions:set -DnewVersion=${{ github.event.inputs.release_version }} + mvn -B versions:commit + + # Actual build + mvn -B clean install + mvn -B clean verify -pl cool-rdf-cli -Pnative + mv target/cool${{ matrix.binary-file-extension }} target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} shell: bash - - name: Run UPX - uses: crazy-max/ghaction-upx@v1.4.0 + + - name: Switch to Temurin JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + overwrite-settings: false + + - name: Test executable jar on Temurin + run: | + mvn -B -Dskip.maven.surefire -pl cool-rdf-cli failsafe:integration-test@default + + - name: Compress native executable + # UPX doesn't work on mac + if: runner.os != 'macOS' + uses: crazy-max/ghaction-upx@0fc45e912669ba9e8fa2b430e97c8da2a632e29b # v3.0.0 with: version: latest - files: ./*.exe + files: cool-rdf-cli/target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} args: -9 - - name: Upload Windows Artifacts - uses: actions/upload-artifact@v2 + + - name: Upload workspace + # We need to upload the generated jars for every submodule, + # so that we have it available for release. Also includes the Linux executable. + if: runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: workspace + path: . + + - name: Upload executable + if: ${{ runner.os == 'Windows' || runner.os == 'macOS' }} + uses: actions/upload-artifact@v4 with: - name: artifacts-windows - path: owl-x86_64-windows-${{ env.RELEASE_VERSION }}.exe + name: cool-rdf-cli-${{ runner.os }} + # .dlls only exist on Windows of course + path: | + cool-rdf-cli/target/cool-${{ runner.os }}-${{ runner.arch }}${{ matrix.binary-file-extension }} + cool-rdf-cli/target/*.dll - publish: - needs: [build-linux, build-macos, build-windows] + release: + name: Release + needs: build runs-on: ubuntu-latest steps: - - name: Check Out Repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Fetch Linux Artifacts - uses: actions/download-artifact@v2 + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + gpg-private-key: ${{ secrets.PGP_KEY }} + gpg-passphrase: PGP_KEY_PASSWORD + server-id: central + server-username: MAVEN_CENTRAL_USERNAME + server-password: MAVEN_CENTRAL_TOKEN + overwrite-settings: false + + - name: Fetch source tree + uses: actions/download-artifact@v4 with: - name: artifacts-linux - - name: Fetch Macos Artifacts - uses: actions/download-artifact@v2 + name: workspace + + - name: Release to Maven Central + run: | + git config user.name github-actions + git config user.email github-actions@github.com + mvn -B -DreleaseVersion=${{ github.event.inputs.release_version }} \ + -DskipTests -Darguments="-DskipTests" release:prepare release:release + env: + MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} + PGP_KEY_PASSWORD: ${{ secrets.PGP_KEY_PASSWORD }} + + - name: Fetch Windows executable + uses: actions/download-artifact@v4 with: - name: artifacts-macos - - name: Fetch Windows Artifacts - uses: actions/download-artifact@v2 + name: cool-rdf-cli-Windows + + - name: Fetch macOS executable + uses: actions/download-artifact@v4 with: - name: artifacts-windows - - name: Set env - run: echo "RELEASE_VERSION=$(grep version= gradle.properties | sed 's/.*=//')" >> $GITHUB_ENV - - name: Push Release - uses: "marvinpinto/action-automatic-releases@latest" + name: cool-rdf-cli-macOS + + - name: Create Windows zip + run: | + cd target + zip -9 -r cool-rdf-cli-Windows-X64.zip cool*.exe *.dll + + - name: Create GitHub release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844v1 # v0.1.15 with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" + body: "Release version ${{ github.event.inputs.release_version }}" + tag_name: v${{ github.event.inputs.release_version }} + draft: false prerelease: false - title: "Release v${{ env.RELEASE_VERSION }}" - files: |- - owl-cli-${{ env.RELEASE_VERSION }}.jar - owl-x86_64-linux-${{ env.RELEASE_VERSION }} - owl-x86_64-apple-darwin-${{ env.RELEASE_VERSION }} - owl-x86_64-windows-${{ env.RELEASE_VERSION }}.exe - - buildDone: - name: Build Ok - needs: publish - runs-on: ubuntu-latest - steps: - - name: Build Ok - run: echo 'all builds passed' + files: | + target/cool-rdf-cli-${{ github.event.inputs.release_version }}.jar + target/cool-rdf-cli-Linux-X64 + target/cool-rdf-cli-Windows-X64.zip + target/cool-rdf-cli-macOS-X64 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy GitHub Pages + uses: JamesIves/github-pages-deploy-action@65b5dfd4f5bcd3a7403bbc2959c144256167464e # 4.5.0 + with: + branch: gh-pages + folder: docs/target/docs diff --git a/.gitignore b/.gitignore index 820d767f..ed5fb1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,22 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build - .idea +*.iml out/ catalog-v*.xml -.cache - # The diagrams are generated at build time -docs/modules/ROOT/assets/images/*.svg +docs/src/docs/antora/modules/ROOT/assets/images/generated/*.svg -!docs/modules/ROOT/assets/images/splash.svg +docs/.cache +docs/build +docs/node/** +docs/node_modules/** +docs/package.json +docs/package-lock.json +**/pom.xml.versionsBackup **/.jqwik-database - **/src/generated/java - -*/lombok.config \ No newline at end of file +*/lombok.config +**/.flattened-pom.xml +**/target +**/src-gen diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 00000000..009d20f5 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,3 @@ +Andreas Textor +Florian Kleedorfer +Bogdan Toma diff --git a/LICENSE b/LICENSE index 86700381..261eeb9e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -187,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2021 Andreas Textor + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 77ab5f3a..51af707f 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,19 @@ [![build](https://github.com/atextor/owl-cli/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/owl-cli/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/atextor/owl-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/atextor/owl-cli) [![Known Vulnerabilities](https://snyk.io/test/github/atextor/owl-cli/badge.svg)](https://snyk.io/test/github/atextor/owl-cli) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![](https://tokei.rs/b1/github/atextor/owl-cli)](https://github.com/Aaronepower/tokei) - **owl-cli** is a command line tool for ontology engineering. It targets the [Web Ontology Language](https://en.wikipedia.org/wiki/Web_Ontology_Language) (OWL 2) and [RDF](https://en.wikipedia.org/wiki/Resource_Description_Framework). You can * generate a diagram for an OWL ontology with the `diagram command` -* read any RDF document in [RDF/Turtle](https://www.w3.org/TR/turtle/), [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/), [RDF N-Triples](https://www.w3.org/TR/n-triples/) or [N3](https://www.w3.org/TeamSubmission/n3/) format and write it in configurable, pretty-printed RDF/Turtle or one of the other formats using the `write command` +* read any RDF document in [RDF/Turtle](https://www.w3.org/TR/turtle/) + , [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/), [RDF N-Triples](https://www.w3.org/TR/n-triples/) + or [N3](https://www.w3.org/TeamSubmission/n3/) format and write it in configurable, pretty-printed RDF/Turtle or one + of the other formats using the `write command` * perform OWL DL reasoning on an input ontology using the `infer command` -owl diagram splash image +owl diagram splash image ## Documentation diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 69807f27..00000000 --- a/build.gradle +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'com.github.ben-manes.versions' version '0.48.0' - id 'com.adarshr.test-logger' version '3.2.0' apply false - id 'io.freefair.lombok' version '8.3' apply false - id 'com.github.johnrengelman.shadow' version '8.1.1' apply false - id 'org.ajoberstar.grgit' version '5.2.0' -} - -allprojects { - repositories { - mavenCentral() - } -} - -def currentTag = { - def grgit = grgit.open{ dir = "${projectDir}" } - def tag = grgit.describe{ tags = true } - if (tag != null) { - tag.startsWith('snapshot') ? 'snapshot' : tag.replace('v', '') - } else { - 'snapshot' - } -} - -subprojects { - version = currentTag() - task allDeps(type: DependencyReportTask) {} - ext { - homeDir = System.getProperty("user.home") - lombokAnnotationProcessor = 'lombok.launch.AnnotationProcessorHider$AnnotationProcessor' - lombokClaimingProcessor = 'lombok.launch.AnnotationProcessorHider$ClaimingProcessor' - picocliProcessor = 'picocli.codegen.aot.graalvm.processor.NativeImageConfigGeneratorProcessor' - } -} - -apply plugin: 'jacoco' -apply plugin: 'java' - -task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates an aggregate report from all subprojects' - classDirectories.from = [ - "${projectDir}/cli/build/classes/java/main", - "${projectDir}/diagram/build/classes/java/main", - "${projectDir}/write/build/classes/java/main", - "${projectDir}/infer/build/classes/java/main", - ] - sourceDirectories.from = [ - "${projectDir}/cli/src/main/java", - "${projectDir}/diagram/src/main/java", - "${projectDir}/write/src/main/java", - "${projectDir}/infer/src/main/java", - ] - - executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") - reports { - html.required = true - xml.required = true - xml.destination(file("${buildDir}/reports/jacoco/report.xml")) - csv.required = false - } - - dependsOn ':test' - dependsOn ':cli:test' - dependsOn ':diagram:test' - dependsOn ':write:test' - dependsOn ':infer:test' -} - -defaultTasks 'test', 'shadowJar' - -def isNonStable = { String version -> - return ['ALPHA', 'BETA', 'RC', 'M'].any { it -> version.toUpperCase().contains(it) } -} - -dependencyUpdates { - rejectVersionIf { - isNonStable(it.candidate.version) - } -} diff --git a/cli/build.gradle b/cli/build.gradle deleted file mode 100644 index d4ec8662..00000000 --- a/cli/build.gradle +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import org.apache.tools.ant.taskdefs.condition.Os - -plugins { - id 'java' - id 'application' - id 'jacoco' - id 'com.github.johnrengelman.shadow' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -configurations { - integrationTestImplementation.extendsFrom implementation - integrationTestRuntimeOnly.extendsFrom runtimeOnly -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation project(':diagram') - implementation project(':write') - implementation project(':infer') - implementation(deps.owlapi) { - exclude group: 'org.slf4j', module: 'slf4j-simple' - } - implementation(deps.jena_core) - implementation(deps.jena_arq) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - implementation(deps.picocli) - implementation(deps.logback) - annotationProcessor(deps.picocli_codegen) - - // Override transitive dependency versions due to features - implementation(deps.caffeine) - - // Override transitive dependency versions due to vulns - implementation(deps.guava) - implementation(deps.jackson_databind) - implementation(deps.httpclient) - implementation(deps.commons_codec) - - // To support GraalVM substitution classes - compileOnly(deps.svm) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.junit_jupiter_params) - testImplementation(deps.commons_io) - testImplementation(deps.assertj) - testImplementation(deps.classgraph) - testRuntimeOnly(deps.junit_jupiter_engine) - - // Integration test - integrationTestImplementation(deps.junit_jupiter_api) - integrationTestImplementation(deps.junit_jupiter_params) - integrationTestImplementation(deps.assertj) - integrationTestImplementation(deps.classgraph) - integrationTestRuntimeOnly(deps.junit_jupiter_engine) -} - -configurations.all { - exclude group: "org.eclipse.rdf4j", module: "rdf4j-model" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-api" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-languages" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-datatypes" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-binary" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-n3" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-nquads" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-ntriples" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-rdfjson" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-jsonld" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-rdfxml" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-trix" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-trig" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-turtle" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-util" -} - -shadowJar { - archiveBaseName = 'owl-cli' - archiveClassifier = null -} - -def nativeImageBinary = Os.isFamily(Os.FAMILY_WINDOWS) ? file("${homeDir}/.sdkman/candidates/java/current/lib/svm/bin/native-image") : file("${homeDir}/.sdkman/candidates/java/17.0.8-graal/lib/svm/bin/native-image") -def nativeImageArgs = ['--verbose', '-jar', "${buildDir}/libs/owl-cli-${version}.jar", "${buildDir}/bin/owl"] -task nativeImage(type: Exec, dependsOn: "shadowJar") { - doFirst { - println nativeImageArgs.join(' ') - } - executable nativeImageBinary - args nativeImageArgs - inputs.file file("${buildDir}/libs/owl-cli-${version}.jar") - outputs.file file("${buildDir}/bin/owl") -} - -def appConfigClass = "OWLCLIConfig" -def genSrc = "${project.projectDir}/src/generated/java" -def genPackage = "${genSrc}/de/atextor/owlcli" -def genAppConfig = "${genPackage}/${appConfigClass}.java" -task generateStaticProperties() { - doLast { - file("${genPackage}").mkdirs() - file("${genAppConfig}").text = """/* Generated file, do not change */ -package de.atextor.owlcli; - -public class ${appConfigClass} { - public static final String VERSION = "${version}"; - public static final String BUILD_DATE = "${new Date().format("yyyy-MM-dd HH:mm:ss")}"; -} -""" - } -} - -tasks.register("integrationTest", Test) { - description = 'Runs integration tests.' - group = 'verification' - outputs.upToDateWhen { false } - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath - dependsOn shadowJar - shouldRunAfter nativeImage - onlyIf { project(':cli').file('build/bin/owl').exists() } - - testLogging { - showStandardStreams = true - } -} - -sourceSets { - generated { - java.srcDir "${genSrc}" - } - main { - compileClasspath += sourceSets.generated.output - } - integrationTest { - compileClasspath += sourceSets.main.output + sourceSets.test.output - runtimeClasspath += sourceSets.main.output + sourceSets.test.output - } -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 - dependsOn(generateStaticProperties) -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } - - testLogging { - showStandardStreams = true - } -} - -integrationTest { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } - - testLogging { - showStandardStreams = true - } - - systemProperty "owlBinary", project(':cli').file('build/bin/owl').getCanonicalPath() -} - -mainClassName = 'de.atextor.owlcli.OWLCLI' diff --git a/cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java b/cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java deleted file mode 100644 index 0f3a6685..00000000 --- a/cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * This test runs several subcommands and see if they work correctly. This is done by calling the built native - * binary with the corresponding command line switches. This is important, because this tests whether the binary - * was built and starts correctly. - */ -public class BinaryIntegrationTest { - private final Runtime runtime = Runtime.getRuntime(); - - static String owl; - - /** - * This is set by the gradle build. If you want to run the tests in the IDE, you need to add - * -DowlBinary=/path/to/owl to the VM arguments. - */ - @BeforeAll - public static void setup() { - owl = System.getProperty( "owlBinary" ); - } - - @Test - public void testWithoutArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl [-hv] [--version] [COMMAND]" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testHelp() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " --help" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl [-hv] [--version] [COMMAND]" ); - assertThat( stdout ).contains( "See the online documentation" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testInvalidArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " definitelynotavalidargument" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @Test - public void testHelpDiagram() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " help diagram" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl diagram" ); - assertThat( stdout ).contains( "--direction=" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testDiagramWithoutArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " diagram" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @Test - public void testDiagramWithInvalidArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " diagram definitelynotavalidargument" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @ParameterizedTest - @ArgumentsSource( ResourceArgumentsProvider.class ) - public void testDiagramGeneration( final String testFileName ) throws IOException, InterruptedException { - final Path tempDir = Files.createTempDirectory( "owldiagram" ); - - final URL input = DiagramCommandTest.class.getResource( "/" + testFileName + ".ttl" ); - final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); - - assertThat( input ).isNotNull(); - FileUtils.copyURLToFile( input, output ); - assertThat( output ).isFile(); - assertThat( fileContent( output ) ).isNotEmpty(); - - final String command = owl + " diagram " + output.getAbsolutePath(); - final Process process = runtime.exec( command ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - if ( process.exitValue() != 0 ) { - System.out.println( "Something went wrong for " + command ); - System.out.println( "=== stdout ===" ); - System.out.println( stdout ); - System.out.println( "=== stderr ===" ); - System.out.println( stderr ); - } - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).isEmpty(); - - final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); - assertThat( writtenFile ).isFile(); - assertThat( fileContent( writtenFile ) ).contains( " . - @prefix rdfs: . - - :Person a rdfs:Class . - :name a rdfs:Property . - :address a rdfs:Property . - :city a rdfs:Property . - :Max a :Person ; - :name "Max" ; - :address [ - :city "City Z" - ] . - """; - return new ByteArrayInputStream( turtleDocument.getBytes() ); - } - - private InputStream rdfXmlInputStream() { - final String rdfXmlDocument = """ - - - - - -
- Max - - - - City Z - - - - - - - - - - - - """; - return new ByteArrayInputStream( rdfXmlDocument.getBytes() ); - } - - private InputStream ntripleInputStream() { - final String ntripleDocument = """ - . - . - . - _:gen0 "City Z"^^ . - _:gen0 . - "Max"^^ . - . - . - """; - return new ByteArrayInputStream( ntripleDocument.getBytes() ); - } - - private Model parseModel( final String document, final String format ) { - final Model model = ModelFactory.createDefaultModel(); - try { - model.read( new StringReader( document ), "", format ); - return model; - } catch ( final Throwable t ) { - return null; - } - } - - private boolean canBeParsedAs( final String document, final String format, final int expectedNumberOfStatements ) { - final Model model = parseModel( document, format ); - return model != null && model.listStatements().toList().size() == expectedNumberOfStatements; - } - - - @Test - public void testWriteTurtle() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteRdfXml() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -o rdfxml -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "RDF/XML", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteNtriple() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -o ntriple -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "N-TRIPLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testReadRdfXml() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -i rdfxml -o turtle -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( rdfXmlInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testReadNtriple() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -i ntriple -o turtle -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( ntripleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteTurtleWithEmptyBase() throws InterruptedException, IOException { - final String turtleDocument = """ - @prefix rdfs: . - @prefix : . - - :Person a rdfs:Class ; - :foo <> . - """; - - final Process process = runtime.exec( owl + " write -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.write( turtleDocument, process.getOutputStream(), StandardCharsets.UTF_8 ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( stdout ).isEqualToIgnoringWhitespace( turtleDocument ); - } -} diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java b/cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java deleted file mode 100644 index ced260b9..00000000 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli; - -import de.atextor.owlcli.diagram.diagram.Configuration; -import de.atextor.owlcli.diagram.diagram.DiagramGenerator; -import de.atextor.owlcli.diagram.diagram.GraphvizDocument; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import picocli.CommandLine; - -@CommandLine.Command( name = "diagram", - description = "Generate automatically-layouted diagrams for an ontology", - descriptionHeading = "%n@|bold Description|@:%n%n", - parameterListHeading = "%n@|bold Parameters|@:%n", - optionListHeading = "%n@|bold Options|@:%n", - footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#diagram-command" -) -public class OWLCLIDiagramCommand extends AbstractCommand implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIDiagramCommand.class ); - - private static final Configuration config = GraphvizDocument.DEFAULT_CONFIGURATION; - - @CommandLine.Mixin - LoggingMixin loggingMixin; - - @CommandLine.Option( names = { "--fontname" }, description = "The font to use (Default: ${DEFAULT-VALUE})" ) - private String fontname = config.fontname; - - @CommandLine.Option( names = { "--fontsize" }, description = "Default font size (Default: ${DEFAULT-VALUE})" ) - private int fontsize = config.fontsize; - - @CommandLine.Option( names = { "--nodefontname" }, description = "Font for nodes (Default: ${DEFAULT-VALUE})" ) - private String nodeFontName = config.nodeFontname; - - @CommandLine.Option( names = { "--nodefontsize" }, description = "Font size for nodes (Default: ${DEFAULT-VALUE})" ) - private int nodeFontsize = config.nodeFontsize; - - @CommandLine.Option( names = { "--nodeshape" }, description = "Node shape (Default: ${DEFAULT-VALUE})" ) - private String nodeShape = config.nodeShape; - - @CommandLine.Option( names = { "--nodemargin" }, description = "Node margin (Default: ${DEFAULT-VALUE})" ) - private String nodeMargin = config.nodeMargin; - - @CommandLine.Option( names = { "--nodestyle" }, description = "Node style (Default: ${DEFAULT-VALUE})" ) - private String nodeStyle = config.nodeStyle; - - @CommandLine.Option( names = { "--format" }, - description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) - private Configuration.Format format = config.format; - - @CommandLine.Option( names = { "--direction" }, - description = "Diagram layout direction, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) - private Configuration.LayoutDirection layoutDirection = config.layoutDirection; - - @CommandLine.Option( names = { "--dotbinary" }, description = "Path to dot binary (Default: ${DEFAULT-VALUE})" ) - private String dotBinary = config.dotBinary; - - @CommandLine.Option( names = { "--fgcolor" }, description = "Foreground color (Default: ${DEFAULT-VALUE})" ) - private String fgColor = config.fgColor; - - @CommandLine.Option( names = { "--bgcolor" }, description = "Background color (Default: ${DEFAULT-VALUE})" ) - private String bgColor = config.bgColor; - - @CommandLine.Parameters( paramLabel = "INPUT", description = "File name or - for stdin", arity = "1", - index = "0" ) - private String input; - - @CommandLine.Parameters( paramLabel = "OUTPUT", - description = "File name or - for stdout. If left out, the input file name is used, e.g. foo.ttl -> " + - "foo.svg or stdout if INPUT is -.", - arity = "0..1", index = "1" ) - private String output; - - @Override - public void run() { - final Configuration configuration = Configuration.builder() - .fontname( fontname ) - .fontsize( fontsize ) - .nodeFontname( nodeFontName ) - .nodeFontsize( nodeFontsize ) - .nodeShape( nodeShape ) - .nodeMargin( nodeMargin ) - .nodeStyle( nodeStyle ) - .format( format ) - .layoutDirection( layoutDirection ) - .dotBinary( dotBinary ) - .fgColor( fgColor ) - .bgColor( bgColor ) - .build(); - - final MappingConfiguration mappingConfig = DefaultMappingConfiguration.builder().build(); - openInput( input ).flatMap( inputStream -> - loadOntology( inputStream ).flatMap( ontology -> - openOutput( input, output, format.toString() ).flatMap( outputStream -> - new DiagramGenerator( configuration, mappingConfig ) - .generate( ontology, outputStream, configuration ) ) ) - ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); - } -} diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json deleted file mode 100644 index 600e7476..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json +++ /dev/null @@ -1,15 +0,0 @@ -[ -{ - "name":"java.lang.ClassLoader", - "methods":[ - {"name":"getPlatformClassLoader","parameterTypes":[] }, - {"name":"loadClass","parameterTypes":["java.lang.String"] } - ] -}, -{ - "name":"java.lang.ClassNotFoundException" -}, -{ - "name":"java.lang.NoSuchMethodError" -} -] diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties deleted file mode 100644 index 601cf551..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright 2021 Andreas Textor -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -ImageName = owl -Args = -H:ConfigurationFileDirectories=${.},${.}/../../picocli-generated/owl-cli/cli \ - --initialize-at-build-time=uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl \ - --initialize-at-build-time=org.slf4j.impl.SimpleLogger \ - --initialize-at-build-time=org.slf4j.LoggerFactory \ - --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder \ - --initialize-at-build-time=ch.qos.logback.core.util.Loader \ - --initialize-at-build-time=ch.qos.logback.core.util.StatusPrinter \ - --initialize-at-build-time=ch.qos.logback.classic.Level \ - --initialize-at-build-time=ch.qos.logback.classic.Logger \ - --initialize-at-build-time=ch.qos.logback.core.status.InfoStatus \ - --initialize-at-build-time=ch.qos.logback.core.status.StatusBase \ - --initialize-at-build-time=ch.qos.logback.core.spi.AppenderAttachableImpl \ - --initialize-at-build-time=org.apache.jena.base.module.SubsystemRegistryServiceLoader \ - --initialize-at-build-time=org.apache.jena.util.LocationMapper \ - --initialize-at-build-time=org.apache.jena.riot.system.stream.JenaIOEnvironment \ - -H:-UseServiceLoaderFeature \ - -H:+AllowIncompleteClasspath \ - -H:EnableURLProtocols=http,https \ - -H:+ReportExceptionStackTraces \ - --no-fallback \ - --report-unsupported-elements-at-runtime \ No newline at end of file diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json deleted file mode 100644 index 0d4f101c..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json deleted file mode 100644 index 85d2bd91..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json +++ /dev/null @@ -1,643 +0,0 @@ -[ -{ - "name": "ch.qos.logback.core.util.StatusPrinter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name": "ch.qos.logback.classic.pattern.DateConverter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"ch.qos.logback.classic.pattern.LevelConverter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"ch.qos.logback.classic.pattern.LineSeparatorConverter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"ch.qos.logback.classic.pattern.LoggerConverter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"ch.qos.logback.classic.pattern.MessageConverter", - "allDeclaredConstructors": true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name": "ch.qos.logback.classic.pattern.ThrowableProxyConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.NopThrowableInformationConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ContextNameConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.ReplacingCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.CyanCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.RedCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.WhiteCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.PropertyConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.MethodOfCallerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.IdentityCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.MarkerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.RelativeTimeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.MagentaCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.LineOfCallerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.FileOfCallerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.LocalSequenceNumberConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.YellowCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.GrayCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.MDCConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BoldRedCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.GreenCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.core.pattern.color.BlackCompositeConverter", - "allDeclaredConstructors": true -}, -{ - "name": "ch.qos.logback.classic.pattern.ThreadConverter", - "allDeclaredConstructors": true -}, -{ - "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef", - "fields":[{"name":"writeCounter", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadCounterRef", - "fields":[{"name":"readCounter", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef", - "fields":[{"name":"drainStatus", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueColdProducerFields", - "fields":[{"name":"producerLimit", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueConsumerFields", - "fields":[{"name":"consumerIndex", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueProducerFields", - "fields":[{"name":"producerIndex", "allowUnsafeAccess":true}] -}, -{ - "name":"com.github.benmanes.caffeine.cache.CacheLoader", - "methods":[{"name":"loadAll","parameterTypes":["java.lang.Iterable"] }] -}, -{ - "name":"com.github.benmanes.caffeine.cache.FS", - "fields":[ - {"name":"key", "allowUnsafeAccess":true}, - {"name":"value", "allowUnsafeAccess":true} - ] -}, -{ - "name":"com.github.benmanes.caffeine.cache.FSMS", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.PS", - "allDeclaredConstructors" : true, - "fields":[ - {"name":"key", "allowUnsafeAccess":true}, - {"name":"value", "allowUnsafeAccess":true} - ] -}, -{ - "name":"com.github.benmanes.caffeine.cache.PSMS", - "allDeclaredConstructors" : true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.github.benmanes.caffeine.cache.PSMW", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.github.benmanes.caffeine.cache.SSMS", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.SSMW", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.WSMS", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.WSSMW", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.FSMW", - "allDeclaredConstructors" : true, - "allDeclaredMethods":true, - "allDeclaredFields":true -}, -{ - "name":"com.github.benmanes.caffeine.cache.StripedBuffer", - "fields":[{"name":"tableBusy", "allowUnsafeAccess":true}] -}, -{ - "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"de.atextor.owlcli.AbstractCommand", - "allDeclaredFields":true, - "allDeclaredMethods":true -}, -{ - "name":"de.atextor.owlcli.LoggingMixin", - "allDeclaredFields":true, - "allDeclaredMethods":true, - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"de.atextor.owlcli.OWLCLI", - "allDeclaredFields":true, - "allDeclaredMethods":true, - "allPublicMethods":true -}, -{ - "name":"de.atextor.owlcli.OWLCLIDiagramCommand", - "allDeclaredFields":true, - "allDeclaredMethods":true, - "allPublicMethods":true -}, -{ - "name":"de.atextor.owlcli.OWLCLIWriteCommand", - "allDeclaredFields":true, - "allDeclaredMethods":true -}, -{ - "name":"java.io.FilePermission" -}, -{ - "name":"java.lang.Object", - "allDeclaredFields":true, - "allDeclaredMethods":true -}, -{ - "name":"java.lang.RuntimePermission" -}, -{ - "name":"java.lang.Thread", - "fields":[{"name":"threadLocalRandomProbe", "allowUnsafeAccess":true}] -}, -{ - "name":"java.net.NetPermission" -}, -{ - "name":"java.net.SocketPermission" -}, -{ - "name":"java.net.URLPermission", - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] -}, -{ - "name":"java.nio.file.Path" -}, -{ - "name":"java.nio.file.Paths", - "methods":[{"name":"get","parameterTypes":["java.lang.String","java.lang.String[]"] }] -}, -{ - "name":"java.security.AllPermission" -}, -{ - "name":"java.security.SecurityPermission" -}, -{ - "name":"java.sql.Connection" -}, -{ - "name":"java.sql.Driver" -}, -{ - "name":"java.sql.DriverManager", - "methods":[ - {"name":"getConnection","parameterTypes":["java.lang.String"] }, - {"name":"getDriver","parameterTypes":["java.lang.String"] } - ] -}, -{ - "name":"java.sql.Time", - "methods":[{"name":"","parameterTypes":["long"] }] -}, -{ - "name":"java.sql.Timestamp", - "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.time.Duration", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.Instant", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.LocalDate", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.LocalDateTime", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.LocalTime", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.MonthDay", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.OffsetDateTime", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.OffsetTime", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.Period", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.Year", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.YearMonth", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.time.ZoneId", - "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.time.ZoneOffset", - "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.time.ZonedDateTime", - "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] -}, -{ - "name":"java.util.PropertyPermission" -}, -{ - "name":"org.apache.jena.ext.com.google.common.cache.Striped64", - "fields":[ - {"name":"base", "allowUnsafeAccess":true}, - {"name":"busy", "allowUnsafeAccess":true} - ] -}, -{ - "name":"org.apache.jena.rdfxml.xmlinput.JenaReader", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.apache.jena.ttl.turtle.TurtleReader", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.apache.jena.rdf.model.impl.NTripleReader", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.apache.jena.rdf.model.impl.NTripleWriter", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.semanticweb.owlapi.apibinding.OWLManager$InjectorConstants", - "fields":[ - {"name":"COMPRESSION_ENABLED"}, - {"name":"CONCURRENTBUILDER"}, - {"name":"CONFIG"}, - {"name":"NONCONCURRENTBUILDER"}, - {"name":"NOOP"}, - {"name":"REENTRANT"} - ] -}, -{ - "name":"org.apache.jena.rdfxml.xmloutput.impl.Basic", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.latex.renderer.LatexStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioBinaryRdfParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioBinaryRdfStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioJsonLDParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioJsonLDStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioJsonParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioJsonStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioN3ParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioN3StorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioNQuadsParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioNQuadsStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioNTriplesParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioNTriplesStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioRDFXMLParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioRDFXMLStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioRDFaParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTrigParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTrigStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTrixParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTrixStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTurtleParserFactory", - "allPublicConstructors":true -}, -{ - "name":"org.semanticweb.owlapi.rio.RioTurtleStorerFactory", - "allPublicConstructors":true -}, -{ - "name":"picocli.CommandLine$HelpCommand", - "allDeclaredFields":true, - "allDeclaredMethods":true, - "allPublicMethods":true -}, -{ - "name":"sun.misc.Unsafe", - "fields":[{"name":"theUnsafe"}] -}, -{ - "name":"uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl", - "allPublicConstructors":true -}, -{ - "name":"uk.ac.manchester.cs.owl.owlapi.OWLOntologyFactoryImpl", - "allPublicConstructors":true -}, -{ - "name":"uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl", - "allDeclaredMethods":true, - "allPublicConstructors":true -}, -{ - "name":"uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyBuilder", - "allPublicConstructors":true -}, -{ - "name":"uk.ac.manchester.cs.owl.owlapi.concurrent.NonConcurrentOWLOntologyBuilder", - "allPublicConstructors":true -} -] diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json deleted file mode 100644 index 31cbed26..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "resources":{ - "includes":[ - {"pattern":"\\QMETA-INF/services/org.apache.jena.sys.JenaSubsystemLifecycle\\E"}, - {"pattern":"\\Qorg/apache/jena/jena-properties.xml\\E"}, - {"pattern":"\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"} - ] - }, - "bundles": [ - {"name":"com.sun.org.apache.xerces.internal.impl.msg.XMLMessages"}, - {"name":"org.apache.jena.ext.xerces.impl.xpath.regex.message"} - ] -} diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json b/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json deleted file mode 100644 index 0d4f101c..00000000 --- a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java b/cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java deleted file mode 100644 index b9d9f39c..00000000 --- a/cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli; - -import java.security.Permission; - -public class CaptureSystemExitSecurityManager extends SecurityManager { - private final SecurityManager delegateSecurityManager; - private int exitCode = 0; - - CaptureSystemExitSecurityManager( final SecurityManager delegateSecurityManager ) { - this.delegateSecurityManager = delegateSecurityManager; - } - - int getExitCode() { - return exitCode; - } - - @Override - public void checkPermission( final Permission permission ) { - if ( delegateSecurityManager != null ) { - delegateSecurityManager.checkPermission( permission ); - } - } - - @Override - public void checkExit( final int i ) { - exitCode = i; - throw new SystemExitCapturedException(); - } -} diff --git a/cli/src/test/java/de/atextor/owlcli/CommandLineTest.java b/cli/src/test/java/de/atextor/owlcli/CommandLineTest.java deleted file mode 100644 index fa6fd05e..00000000 --- a/cli/src/test/java/de/atextor/owlcli/CommandLineTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli; - -import org.junit.jupiter.api.Test; - -import static de.atextor.owlcli.MainClassRunner.run; -import static org.assertj.core.api.Assertions.assertThat; - -public class CommandLineTest { - @Test - public void testNoArguments() { - final Runnable command = () -> OWLCLI.main( new String[]{} ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).contains( "Usage: " ); - assertThat( result.stdErr() ).isEmpty(); - } - - @Test - public void testHelp() { - final Runnable command = () -> OWLCLI.main( new String[]{ "--help" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).contains( "Usage: " ); - assertThat( result.stdErr() ).isEmpty(); - } - - @Test - public void testInvalidArguments() { - final Runnable command = () -> OWLCLI.main( new String[]{ "definitelynotavalidargument" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } -} diff --git a/cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java b/cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java deleted file mode 100644 index d0a511b8..00000000 --- a/cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli; - -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; - -import static de.atextor.owlcli.MainClassRunner.run; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -public class DiagramCommandTest { - - private byte[] fileContent( final File file ) { - try { - return FileUtils.readFileToByteArray( file ); - } catch ( final IOException exception ) { - fail( "", exception ); - } - return null; - } - - @Test - public void testWithoutParameters() { - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } - - @Test - public void testWithInvalidInput() { - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram", "definitelynotexistingfile" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } - - @ParameterizedTest - @ArgumentsSource( ResourceArgumentsProvider.class ) - public void testDiagramGeneration( final String testFileName ) throws IOException { - final Path tempDir = Files.createTempDirectory( "owldiagram" ); - - final URL input = DiagramCommandTest.class.getResource( "/" + testFileName + ".ttl" ); - final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); - - assertThat( input ).isNotNull(); - FileUtils.copyURLToFile( input, output ); - assertThat( output ).isFile(); - assertThat( fileContent( output ) ).isNotEmpty(); - - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram", output.getAbsolutePath() } ); - final MainClassRunner.ExecutionResult result = run( command ); - - System.out.println( result.stdOut() ); - System.out.println( result.stdErr() ); - - if ( result.exitStatus() != 0 ) { - System.out.println( "Something went wrong for diagram " + output.getAbsolutePath() ); - System.out.println( "=== stdout ===" ); - System.out.println( result.stdOut() ); - System.out.println( "=== stderr ===" ); - System.out.println( result.stdErr() ); - } - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).isEmpty(); - - final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); - assertThat( writtenFile ).isFile(); - assertThat( fileContent( writtenFile ) ).contains( " + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-cli + Cool RDF Command Line Interface + + + ${project.artifactId}-${project.version} + ${project.artifactId}-${project.version}-for-native + cool.rdf.cli.Cool + cool + jar + ${project.basedir}/src-gen + ${project.basedir}/src-buildtime + + + + + + cool.rdf + cool-rdf-core + + + cool.rdf + cool-rdf-diagram-owl + + + cool.rdf + cool-rdf-infer + + + cool.rdf + cool-rdf-formatter + + + cool.rdf + cool-rdf-write + + + + + com.github.ben-manes.caffeine + caffeine + + + commons-codec + commons-codec + + + commons-io + commons-io + + + com.google.guava + guava + + + com.fasterxml.jackson.core + jackson-databind + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + info.picocli + picocli + + + + + org.graalvm.nativeimage + svm + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.assertj + assertj-core + test + + + io.github.classgraph + classgraph + test + + + org.mockito + mockito-core + test + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-src-gen-source + initialize + + add-source + + + + ${generated.sources}/main/java + + + + + add-src-buildtime-source + initialize + + add-source + + + + ${build.time.sources}/main/java + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ${generated.sources} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + compile-build-time-code + process-sources + + compile + + + ${build.time.sources} + + + + default-compile + compile + + + + info.picocli + picocli-codegen + ${picocli.version} + + + + -Aproject=${project.groupId}/${project.artifactId} + --add-exports + java.desktop/sun.awt=ALL-UNNAMED + --add-exports + java.desktop/sun.font=ALL-UNNAMED + + true + + + + + + + org.codehaus.mojo + exec-maven-plugin + + + generate-static-cli-info-class + generate-resources + + java + + + cool.rdf.cli.buildtime.WriteStaticCliInfoClass + + + + + + + ${binary.name} + cool.rdf.cli.StaticCliInfo + ${generated.sources}/main/java/cool/rdf/cli/StaticCliInfo.java + ${project.developers} + ${project.parent.url} + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 1 + false + ${maven.surefire.skip} + + **/CoolTest.java + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + integration-test + + integration-test + + + + ${project.build.directory}/${regular.jar}.jar + ${project.build.directory}/${binary.name} + ${packaging.type} + + 1 + true + + **/ExecutableJarTest.java + **/BinaryTest.java + + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + + + cool/rdf/core/Prefixes + + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + + shade-for-native-image + package + + shade + + + ${native.image.jar} + false + ${maven.shade.skip} + + + + ${main.class} + + + + + + + + org.graalvm.sdk:graal-sdk + org.graalvm.nativeimage:svm + org.graalvm.truffle:truffle-api + org.graalvm.nativeimage:native-image-base + org.graalvm.nativeimage:pointsto + org.graalvm.nativeimage:objectfile + org.graalvm.compiler:compiler + + + + net.sourceforge.owlapi:owlapi-api + net.sourceforge.owlapi:owlapi-apibinding + net.sourceforge.owlapi:owlapi-compatibility + net.sourceforge.owlapi:owlapi-impl + net.sourceforge.owlapi:owlapi-parsers + net.sourceforge.owlapi:owlapi-oboformat + net.sourceforge.owlapi:owlapi-rio + net.sourceforge.owlapi:owlapi-tools + + + + + + *:* + + module-info.class + META-INF/* + META-INF/sisu/javax.inject.Named + META-INF/plexus/components.xml + META-INF.versions*/** + META-INF/versions*/** + META-INF/maven/** + plugin.xml + about.html + + + + + ${project.groupId}:${project.artifactId} + false + + ** + META-INF/** + git.properties + + + + cool/rdf/*/buildtime/** + + + + + + + + default-shade + package + + shade + + + ${regular.jar} + false + ${maven.shade.skip} + + + + ${main.class} + + + + + + + + + net.sourceforge.owlapi:owlapi-api + net.sourceforge.owlapi:owlapi-apibinding + net.sourceforge.owlapi:owlapi-compatibility + net.sourceforge.owlapi:owlapi-impl + net.sourceforge.owlapi:owlapi-parsers + net.sourceforge.owlapi:owlapi-oboformat + net.sourceforge.owlapi:owlapi-rio + net.sourceforge.owlapi:owlapi-tools + + + + + + *:* + + module-info.class + META-INF/* + META-INF/sisu/javax.inject.Named + META-INF/plexus/components.xml + META-INF.versions*/** + META-INF/versions*/** + META-INF/maven/** + plugin.xml + about.html + + + + + ${project.groupId}:${project.artifactId} + false + + ** + META-INF/** + git.properties + + + + cool/rdf/core/buildtime/** + + cool/rdf/cli/graal/** + + + + + + + + + + + + + native + + true + true + native + + + + + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin.version} + true + + + build-native + + compile + + pre-integration-test + + + + ${main.class} + ${native.build.skip} + true + + -H:Name=${project.build.directory}/${binary.name} + --verbose + --no-fallback + --report-unsupported-elements-at-runtime + -H:EnableURLProtocols=http,https + --enable-https + -H:-UseServiceLoaderFeature + -H:+AllowIncompleteClasspath + -H:+ReportExceptionStackTraces + -H:+PrintClassInitialization + -H:-DeadlockWatchdogExitOnTimeout + -H:DeadlockWatchdogInterval=0 + --features=cool.rdf.cli.graal.feature.CoolRdfFeature + -J-XX:MaxRAMPercentage=90.0 + -J-XX:GCTimeRatio=19 + -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED + -J--add-exports=java.desktop/sun.font=ALL-UNNAMED + + -J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jni=ALL-UNNAMED + + + true + + ${project.build.directory}/${native.image.jar}.jar + + + + + + + + diff --git a/cool-rdf-cli/src-buildtime/main/java/cool/rdf/cli/buildtime/WriteStaticCliInfoClass.java b/cool-rdf-cli/src-buildtime/main/java/cool/rdf/cli/buildtime/WriteStaticCliInfoClass.java new file mode 100644 index 00000000..a01a08f2 --- /dev/null +++ b/cool-rdf-cli/src-buildtime/main/java/cool/rdf/cli/buildtime/WriteStaticCliInfoClass.java @@ -0,0 +1,106 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.buildtime; + +import cool.rdf.core.util.StringTemplate; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +public class WriteStaticCliInfoClass { + private static final StringTemplate STATIC_CLI_INFO_CLASS_TEMPLATE = new StringTemplate( """ + /* + * Copyright ${year} ${copyrightHolder} + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package ${package}; + + /** + * Provides static information for the command line interface. + * Generated class, do not edit. + * Generated on ${buildDate}. + */ + public class ${className} { + /** + * The name of the CLI command + */ + public static final String COMMAND_NAME = "${commandName}"; + + /** + * The project URL + */ + public static final String PROJECT_URL = "${projectUrl}"; + } + """ ); + + /** + * args[0]: the name of the CLI command + * args[1]: fully qualified class name to generate + * args[2]: the path to the file to write + * args[3]: name of the copyright holder + * args[4]: the project URL + * + * @param args the arguments + */ + public static void main( final String[] args ) { + final String commandName = args[0]; + final String fullyQualifiedClassName = args[1]; + final String copyrightHolder = args[3]; + final int lastDot = fullyQualifiedClassName.lastIndexOf( "." ); + final String packageName = fullyQualifiedClassName.substring( 0, lastDot ); + final String className = fullyQualifiedClassName.substring( lastDot + 1 ); + final String projectUrl = args[4]; + + final File targetFile = new File( args[2] ); + targetFile.getParentFile().mkdirs(); + + final String content = STATIC_CLI_INFO_CLASS_TEMPLATE.apply( Map.of( + "year", new SimpleDateFormat( "yyyy" ).format( new Date() ), + "copyrightHolder", copyrightHolder, + "package", packageName, + "className", className, + "commandName", commandName, + "projectUrl", projectUrl, + "buildDate", new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) + ) ); + + try { + final BufferedWriter writer = new BufferedWriter( new FileWriter( targetFile ) ); + writer.write( content ); + writer.close(); + } catch ( final IOException exception ) { + throw new RuntimeException( exception ); + } + } +} diff --git a/cli/src/main/java/de/atextor/owlcli/AbstractCommand.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java similarity index 55% rename from cli/src/main/java/de/atextor/owlcli/AbstractCommand.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java index e277c314..5d40ef9d 100644 --- a/cli/src/main/java/de/atextor/owlcli/AbstractCommand.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,17 +14,35 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; import com.google.common.collect.ImmutableSet; import io.vavr.control.Try; +import org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory; +import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory; +import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory; +import org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory; +import org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory; import org.semanticweb.owlapi.io.OWLParserFactory; +import org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory; +import org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory; +import org.semanticweb.owlapi.latex.renderer.LatexStorerFactory; +import org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory; +import org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory; import org.semanticweb.owlapi.model.OWLDataFactory; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyFactory; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLStorerFactory; +import org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory; +import org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory; +import org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory; +import org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory; +import org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory; +import org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory; +import org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory; +import org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory; import org.slf4j.Logger; import picocli.CommandLine; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; @@ -39,34 +57,54 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.util.Optional; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -public class AbstractCommand { +/** + * Base class for commands that bundles common functionality + */ +public abstract class AbstractCommand { + protected final Runtime runtime; + + protected AbstractCommand( final Runtime runtime ) { + this.runtime = runtime; + } + /** + * Will exit the program with status code 1 + */ protected void commandFailed() { - System.exit( 1 ); + runtime.exit( 1 ); } - protected Try openOutput( final @Nonnull String input, final String output, - final String targetFileExtension ) { - if ( output != null ) { + /** + * Try to open an output stream + * + * @param input the original input: file path or "-" for stdin + * @param output the designated output: an absolute or relative path or "-" for stdout. If empty, determine the + * output from the input + * @param targetFileExtension the target file extension to use, if the output is empty + * @return if successful, the output stream + */ + protected Try openOutput( final @Nonnull String input, final Optional output, final String targetFileExtension ) { + if ( output.isPresent() ) { // Output is given as - --> write to stdout - if ( output.equals( "-" ) ) { + if ( output.get().equals( "-" ) ) { return Try.success( System.out ); } // Output is given as something else --> open as file try { - return Try.success( new FileOutputStream( output ) ); + return Try.success( new FileOutputStream( output.get() ) ); } catch ( final FileNotFoundException exception ) { return Try.failure( exception ); } } if ( input.equals( "-" ) ) { - // Input is stdin, outout is not given -> write to stdout + // Input is stdin, output is not given -> write to stdout return Try.success( System.out ); } @@ -85,6 +123,12 @@ protected Try openOutput( final @Nonnull String input, final Strin } } + /** + * Try to open a given input as input stream, either an absolute or relative file system path or "-" meaning stdin + * + * @param input the input + * @return an input stream on success + */ protected Try openInput( final String input ) { if ( input.equals( "-" ) ) { return Try.success( System.in ); @@ -100,33 +144,40 @@ protected Try openInput( final String input ) { } } + /** + * Since the service loader feature is disabled in the GraalVM config, instead set up the OWL-API OWL ontology + * manager programmatically. + * + * @return the OWL ontology manager + */ protected OWLOntologyManager createOWLOntologyManager() { final ImmutableSet parserFactories = ImmutableSet.builder() - .add( new org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory() ) - .add( new org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory() ) - .add( new org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory() ) - .add( new org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory() ) - .add( new org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory() ) - .add( new org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory() ) - .add( new org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory() ) + .add( new ManchesterOWLSyntaxOntologyParserFactory() ) + .add( new KRSS2OWLParserFactory() ) + .add( new TurtleOntologyParserFactory() ) + .add( new OWLFunctionalSyntaxOWLParserFactory() ) + .add( new OWLXMLParserFactory() ) + .add( new RDFXMLParserFactory() ) + .add( new DLSyntaxOWLParserFactory() ) + .add( new OBOFormatOWLAPIParserFactory() ) .build(); final Set ontologyFactories = ImmutableSet.builder() .add( new OWLOntologyFactoryImpl( new NonConcurrentOWLOntologyBuilder() ) ) .build(); + @SuppressWarnings( "SpellCheckingInspection" ) final Set storerFactories = ImmutableSet.builder() - .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory() ) - .add( new org.semanticweb.owlapi.latex.renderer.LatexStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory() ) + .add( new RDFXMLStorerFactory() ) + .add( new OWLXMLStorerFactory() ) + .add( new FunctionalSyntaxStorerFactory() ) + .add( new ManchesterSyntaxStorerFactory() ) + .add( new KRSS2OWLSyntaxStorerFactory() ) + .add( new TurtleStorerFactory() ) + .add( new LatexStorerFactory() ) + .add( new DLSyntaxHTMLStorerFactory() ) + .add( new DLSyntaxStorerFactory() ) + .add( new OBOFormatStorerFactory() ) .build(); final OWLDataFactory dataFactory = new OWLDataFactoryImpl(); @@ -158,8 +209,14 @@ public Try loadOntology( final InputStream inputStream ) { } } - protected void exitWithErrorMessage( final Logger logger, final LoggingMixin loggingMixin, - final Throwable throwable ) { + /** + * Bail out after a command failed with a throwable + * + * @param logger the logger to print a message + * @param loggingMixin the logging mixin of the respective command, to determine verbosity + * @param throwable the cause + */ + protected void exitWithErrorMessage( final Logger logger, final LoggingMixin loggingMixin, final Throwable throwable ) { if ( loggingMixin.getVerbosity().length == 0 ) { System.err.println( "Error: " + throwable.getMessage() ); } else if ( loggingMixin.getVerbosity().length == 1 ) { @@ -170,7 +227,19 @@ protected void exitWithErrorMessage( final Logger logger, final LoggingMixin log commandFailed(); } - public void registerTypeConverters( CommandLine commandLine ) { - + /** + * Provide a hook for subclasses to register custom {@link CommandLine.ITypeConverter}s + * + * @param commandLine the command line + */ + public void registerTypeConverters( final CommandLine commandLine ) { + // empty by default } + + /** + * Return the name of this command + * + * @return the command name + */ + public abstract String commandName(); } diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLI.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java similarity index 53% rename from cli/src/main/java/de/atextor/owlcli/OWLCLI.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java index 7e776b11..cb1a0748 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLI.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; import ch.qos.logback.classic.Level; +import cool.rdf.core.Version; import io.vavr.collection.List; -import org.apache.jena.sys.JenaSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; @@ -26,17 +26,28 @@ import java.io.PrintWriter; import java.util.logging.LogManager; -@CommandLine.Command( name = "owl", +import static cool.rdf.cli.StaticCliInfo.COMMAND_NAME; +import static cool.rdf.cli.StaticCliInfo.PROJECT_URL; + +/** + * The main class for the command line interface + */ +@CommandLine.Command( + name = COMMAND_NAME, description = "Command line tool for ontology engineering", subcommands = { CommandLine.HelpCommand.class }, headerHeading = "@|bold Usage|@:%n%n", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", - footer = "%nSee the online documentation: https://atextor.de/owl-cli/" -) -public class OWLCLI implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger( OWLCLI.class ); + footer = "%nSee the online documentation: " + PROJECT_URL ) +public class Cool implements Runnable { + /** + * The name of the top level command + */ + private static final Logger LOG = LoggerFactory.getLogger( Cool.class ); + @SuppressWarnings( "FieldMayBeFinal" ) + private static Runtime runtime = Runtime.getRuntime(); private static void printError( final CommandLine commandLine, final Exception exception ) { final Level logLevel = ( (LoggingMixin) commandLine.getMixins().values().iterator().next() ).calcLogLevel(); @@ -48,56 +59,81 @@ private static void printError( final CommandLine commandLine, final Exception e } } - private static final CommandLine.IParameterExceptionHandler PARAMETER_EXCEPTION_HANDLER = - ( exception, args ) -> { - final CommandLine cmd = exception.getCommandLine(); - printError( cmd, exception ); - cmd.getErr().println( cmd.getHelp().fullSynopsis() ); - return 1; - }; + private static final CommandLine.IParameterExceptionHandler PARAMETER_EXCEPTION_HANDLER = ( exception, args ) -> { + final CommandLine cmd = exception.getCommandLine(); + printError( cmd, exception ); + cmd.getErr().println( cmd.getHelp().fullSynopsis() ); + return 1; + }; - private static final CommandLine.IExecutionExceptionHandler EXECUTION_EXCEPTION_HANDLER = - ( exception, commandLine, parseResult ) -> { - printError( commandLine, exception ); - return 1; - }; + private static final CommandLine.IExecutionExceptionHandler EXECUTION_EXCEPTION_HANDLER = ( exception, commandLine, parseResult ) -> { + printError( commandLine, exception ); + return 1; + }; private final CommandLine commandLine = new CommandLine( this ); + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; + @SuppressWarnings( "unused" ) @CommandLine.Option( names = { "-h", "--help" }, usageHelp = true, description = "Show short help" ) private boolean helpRequested; + @SuppressWarnings( "unused" ) @CommandLine.Option( names = { "--version" }, description = "Show current version" ) private boolean version; + @SuppressWarnings( "unused" ) + @CommandLine.Option( names = { "--disable-color", "-D" }, description = "Disable colored output" ) + private boolean disableColor; + + /** + * The command's main function + * + * @param args the arguments + */ public static void main( final String[] args ) { + // Check disabling color switch before PicoCLI initialization + boolean disableColor = false; + for ( final String arg : args ) { + if ( arg.equals( "--disable-color" ) || arg.equals( "-D" ) ) { + disableColor = true; + break; + } + } + + if ( disableColor ) { + System.setProperty( "picocli.ansi", "false" ); + } + LogManager.getLogManager().reset(); final List commands = List.of( - new OWLCLIDiagramCommand(), - new OWLCLIWriteCommand(), - new OWLCLIInferCommand() - ); - final CommandLine cmd = commands.foldLeft( new OWLCLI().commandLine, CommandLine::addSubcommand ) + new CoolDiagram( runtime ), + new CoolWrite( runtime ), + new CoolInfer( runtime ) ); + final CommandLine cmd = commands.foldLeft( new Cool().commandLine, CommandLine::addSubcommand ) .setParameterExceptionHandler( PARAMETER_EXCEPTION_HANDLER ) .setExecutionExceptionHandler( EXECUTION_EXCEPTION_HANDLER ) .setCaseInsensitiveEnumValuesAllowed( true ) .setExecutionStrategy( LoggingMixin::executionStrategy ); commands.forEach( command -> command.registerTypeConverters( cmd ) ); - System.exit( cmd.execute( args ) ); + + final int resultCode = cmd.execute( args ); + runtime.exit( resultCode ); } @Override public void run() { if ( helpRequested ) { - System.exit( 0 ); + runtime.exit( 0 ); } if ( version ) { - System.out.printf( "owl-cli version: %s build date: %s%n", OWLCLIConfig.VERSION, OWLCLIConfig.BUILD_DATE ); - System.exit( 0 ); + System.out.printf( "%s %s%n commit: %s%n build date: %s%n", COMMAND_NAME, + Version.VERSION, Version.COMMIT_ID.substring( 0, 7 ), Version.BUILD_DATE ); + runtime.exit( 0 ); } System.out.println( commandLine.getHelp().fullSynopsis() ); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java new file mode 100644 index 00000000..d196febf --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java @@ -0,0 +1,197 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import cool.rdf.core.Version; +import cool.rdf.diagram.owl.Configuration; +import cool.rdf.diagram.owl.DiagramGenerator; +import cool.rdf.diagram.owl.GraphvizDocument; +import cool.rdf.diagram.owl.mappers.DefaultMappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static cool.rdf.cli.CoolDiagram.COMMAND_NAME; + +/** + * The 'diagram' subcommand + */ +@SuppressWarnings( "SpellCheckingInspection" ) +@CommandLine.Command( + name = COMMAND_NAME, + description = "Generate automatically-layouted diagrams for an ontology", + descriptionHeading = "%n@|bold Description|@:%n%n", + parameterListHeading = "%n@|bold Parameters|@:%n", + optionListHeading = "%n@|bold Options|@:%n", + footer = "%nSee the online documentation for details:%n" + + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#diagram-command" ) +public class CoolDiagram extends AbstractCommand implements Runnable { + /** + * The name of this subcommand + */ + public static final String COMMAND_NAME = "diagram"; + + private static final Logger LOG = LoggerFactory.getLogger( CoolDiagram.class ); + + private static final Configuration config = GraphvizDocument.DEFAULT_CONFIGURATION; + + @SuppressWarnings( "unused" ) + @CommandLine.Mixin + LoggingMixin loggingMixin; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--fontname" }, description = "The font to use (Default: ${DEFAULT-VALUE})" ) + private String fontname = config.fontname; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--fontsize" }, description = "Default font size (Default: ${DEFAULT-VALUE})" ) + private int fontsize = config.fontsize; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--nodefontname" }, description = "Font for nodes (Default: ${DEFAULT-VALUE})" ) + private String nodeFontName = config.nodeFontname; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--nodefontsize" }, description = "Font size for nodes (Default: ${DEFAULT-VALUE})" ) + private int nodeFontsize = config.nodeFontsize; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--nodeshape" }, description = "Node shape (Default: ${DEFAULT-VALUE})" ) + private String nodeShape = config.nodeShape; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--nodemargin" }, description = "Node margin (Default: ${DEFAULT-VALUE})" ) + private String nodeMargin = config.nodeMargin; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--nodestyle" }, description = "Node style (Default: ${DEFAULT-VALUE})" ) + private String nodeStyle = config.nodeStyle; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--format" }, + description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) + private Configuration.Format format = config.format; + + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--direction" }, + description = "Diagram layout direction, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) + private Configuration.LayoutDirection layoutDirection = config.layoutDirection; + + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--dotbinary" }, description = "Path to dot binary (Default: ${DEFAULT-VALUE})" ) + private String dotBinary = config.dotBinary; + + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--fgcolor" }, description = "Foreground color (Default: ${DEFAULT-VALUE})" ) + private String fgColor = config.fgColor; + + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( names = { "--bgcolor" }, description = "Background color (Default: ${DEFAULT-VALUE})" ) + private String bgColor = config.bgColor; + + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "INPUT", + description = "File name or - for stdin", + arity = "1", + index = "0" ) + private String input; + + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "OUTPUT", + description = "File name or - for stdout. If left out, the input file name is used, e.g. foo.ttl -> " + + "foo.svg or stdout if INPUT is -.", + arity = "0..1", + index = "1" ) + private String output; + + protected CoolDiagram( final Runtime runtime ) { + super( runtime ); + } + + @Override + public void run() { + final MappingConfiguration mappingConfig = DefaultMappingConfiguration.builder().build(); + openInput( input ).flatMap( inputStream -> { + try { + final Configuration.LayoutDirection configureLayoutdirection; + final InputStream configuredInput; + if ( layoutDirection == Configuration.LayoutDirection.DETECT ) { + final byte[] bytes = IOUtils.toByteArray( inputStream ); + configuredInput = new ByteArrayInputStream( bytes ); + final String ontologyString = new String( bytes ); + final Pattern pattern = Pattern.compile( Configuration.LayoutDirection.HINT_PREFIX + "([a-z_]*)" ); + final Matcher matcher = pattern.matcher( ontologyString ); + + if ( matcher.find() ) { + // Either we found a #pragma in the file + configureLayoutdirection = Configuration.LayoutDirection.valueOf( matcher.group( 1 ).toUpperCase() ); + if ( configureLayoutdirection == Configuration.LayoutDirection.DETECT ) { + throw new ErrorMessage( "pragma must not set layout direction to 'detect'" ); + } + } else { + // Or we use whatever was set via command line + configureLayoutdirection = layoutDirection; + } + } else { + configureLayoutdirection = layoutDirection; + configuredInput = inputStream; + } + + final Configuration configuration = Configuration.builder() + .fontname( fontname ) + .fontsize( fontsize ) + .nodeFontname( nodeFontName ) + .nodeFontsize( nodeFontsize ) + .nodeShape( nodeShape ) + .nodeMargin( nodeMargin ) + .nodeStyle( nodeStyle ) + .format( format ) + .layoutDirection( configureLayoutdirection ) + .dotBinary( dotBinary ) + .fgColor( fgColor ) + .bgColor( bgColor ) + .build(); + + return loadOntology( configuredInput ).flatMap( ontology -> openOutput( input, Optional.ofNullable( output ), format + .toString() ).flatMap( outputStream -> new DiagramGenerator( configuration, mappingConfig ) + .generate( ontology, outputStream, configuration ) ) ); + } catch ( final IOException exception ) { + throw new ErrorMessage( "Could not open input" ); + } catch ( final IllegalArgumentException exception ) { + throw new RuntimeException( "Illegal pragma" ); + } + } ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); + } + + @Override + public String commandName() { + return COMMAND_NAME; + } +} diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java similarity index 55% rename from cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java index c5511cee..0f2a04cd 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,54 +14,67 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; -import de.atextor.owlcli.infer.Configuration; -import de.atextor.owlcli.infer.Inferrer; -import de.atextor.turtle.formatter.FormattingStyle; -import org.apache.jena.rdf.model.Property; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.ResourceFactory; +import cool.rdf.core.Version; +import cool.rdf.infer.Configuration; +import cool.rdf.infer.Inferrer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.stream.Collectors; - -@CommandLine.Command( name = "infer", +import java.util.Optional; + +import static cool.rdf.cli.CoolInfer.COMMAND_NAME; + +/** + * The 'infer' subcommand + */ +@CommandLine.Command( + name = COMMAND_NAME, description = "Runs an OWL reasoner on an ontology", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#infer-command" -) -public class OWLCLIInferCommand extends AbstractCommand implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIInferCommand.class ); + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#infer-command" ) +public class CoolInfer extends AbstractCommand implements Runnable { + /** + * The name of this subcommand + */ + public static final String COMMAND_NAME = "infer"; + private static final Logger LOG = LoggerFactory.getLogger( CoolInfer.class ); + + @SuppressWarnings( "unused" ) private static final Configuration config = Inferrer.DEFAULT_CONFIGURATION; + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; - @CommandLine.Parameters( paramLabel = "INPUT", description = "File name, URL, or - for stdin", arity = "1", + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "INPUT", + description = "File name, URL, or - for stdin", + arity = "1", index = "0" ) private String input; - @CommandLine.Parameters( paramLabel = "OUTPUT", + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "OUTPUT", description = "File name or - for stdout. If left out, output is written to stdout.", - arity = "0..1", index = "1" ) + arity = "0..1", + index = "1" ) private String output; + protected CoolInfer( final Runtime runtime ) { + super( runtime ); + } + @Override public void run() { final Configuration.ConfigurationBuilder configurationBuilder = Configuration.builder(); @@ -72,7 +85,7 @@ public void run() { final Configuration configuration = configurationBuilder.build(); try { final URL inputUrl = new URL( input ); - openOutput( input, output != null ? output : "-", "ttl" ) + openOutput( input, output != null ? Optional.of( output ) : Optional.of( "-" ), "ttl" ) .map( outputStream -> inferrer.infer( inputUrl, outputStream, configuration ) ) .onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); return; @@ -82,10 +95,14 @@ public void run() { } openInput( input ).flatMap( inputStream -> { - final Configuration configuration = configurationBuilder.build(); - return openOutput( input, output != null ? output : "-", "ttl" ) - .flatMap( outputStream -> inferrer.infer( inputStream, outputStream, configuration ) ); - } - ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); + final Configuration configuration = configurationBuilder.build(); + return openOutput( input, output != null ? Optional.of( output ) : Optional.of( "-" ), "ttl" ) + .flatMap( outputStream -> inferrer.infer( inputStream, outputStream, configuration ) ); + } ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); + } + + @Override + public String commandName() { + return COMMAND_NAME; } } diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java similarity index 63% rename from cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java index 2570a2bb..23402bb7 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,16 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; -import de.atextor.owlcli.write.Configuration; -import de.atextor.owlcli.write.RdfWriter; -import de.atextor.turtle.formatter.FormattingStyle; +import cool.rdf.core.Prefixes; +import cool.rdf.core.Version; +import cool.rdf.core.model.RdfModel; +import cool.rdf.core.model.RdfPrefix; +import cool.rdf.core.model.impl.DefaultRdfPrefix; +import cool.rdf.formatter.FormattingStyle; +import cool.rdf.write.Configuration; +import cool.rdf.write.RdfWriter; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.rdf.model.Resource; @@ -32,143 +37,216 @@ import java.net.URL; import java.text.DecimalFormat; import java.text.NumberFormat; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.BiFunction; import java.util.stream.Collectors; -@CommandLine.Command( name = "write", +import static cool.rdf.cli.CoolWrite.COMMAND_NAME; + +/** + * The 'write' subcommand + */ +@CommandLine.Command( + name = COMMAND_NAME, description = "Read a given RDF document and write it out, possibly in a different format", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#write-command" -) -public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIWriteCommand.class ); + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#write-command" ) +public class CoolWrite extends AbstractCommand implements Runnable { + /** + * The name of this subcommand + */ + public static final String COMMAND_NAME = "write"; + + private static final Logger LOG = LoggerFactory.getLogger( CoolWrite.class ); private static final Configuration config = RdfWriter.DEFAULT_CONFIGURATION; private final String fallbackUri = "urn:owl-cli:empty"; + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; - @CommandLine.Option( names = { "-o", "--output" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "-o", "--output" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format outputFormat = config.outputFormat; - @CommandLine.Option( names = { "-i", "--input" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "-i", "--input" }, description = "Input file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format inputFormat = config.inputFormat; - @CommandLine.Option( names = { "-p", "--prefix" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "-p", "--prefix" }, description = "Prefix to add as @prefix when used.", mapFallbackValue = fallbackUri ) private Map prefixMap = new HashMap<>(); - @CommandLine.Option( names = { "--prefixAlign" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--prefixAlign" }, description = "Alignment of @prefix statements, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Alignment alignPrefixes = FormattingStyle.DEFAULT.alignPrefixes; - @CommandLine.Option( names = { "--encoding" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--encoding" }, description = "Output encoding, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Charset encoding = FormattingStyle.DEFAULT.charset; - @CommandLine.Option( names = { "--doubleFormat" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--doubleFormat" }, description = "Defines how double numbers are formatted (Default: ${DEFAULT-VALUE})" ) private String doubleFormatPattern = ( (DecimalFormat) FormattingStyle.DEFAULT.doubleFormat ).toPattern(); - @CommandLine.Option( names = { "--endOfLine" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--endOfLine" }, description = "End of line style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.EndOfLineStyle endOfLineStyle = FormattingStyle.DEFAULT.endOfLine; - @CommandLine.Option( names = { "--indent" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--indent" }, description = "Indent style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.IndentStyle indentStyle = FormattingStyle.DEFAULT.indentStyle; - @CommandLine.Option( names = { "--firstPredicateInNewLine" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--firstPredicateInNewLine" }, description = "Write first predicate in new line of block (Default: ${DEFAULT-VALUE})" ) private boolean firstPredicateInNewLine = FormattingStyle.DEFAULT.firstPredicateInNewLine; - @CommandLine.Option( names = { "--writeRdfType" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--writeRdfType" }, description = "Write 'rdf:type' instead of 'a' (Default: ${DEFAULT-VALUE})" ) private boolean writeRdfType = !FormattingStyle.DEFAULT.useAForRdfType; - @CommandLine.Option( names = { "--useCommaByDefault" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--useCommaByDefault" }, description = "Use commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private boolean useCommaByDefault = FormattingStyle.DEFAULT.useCommaByDefault; - @CommandLine.Option( names = { "--commaForPredicate" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--commaForPredicate" }, description = "A set of predicates that, when used multiple times, are separated by commas, even when " + "useCommaByDefault is false (Default: ${DEFAULT-VALUE})" ) private Set commaForPredicate = FormattingStyle.DEFAULT.commaForPredicate; - @CommandLine.Option( names = { "--noCommaForPredicate" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--noCommaForPredicate" }, description = "Use no commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private Set noCommaForPredicate = FormattingStyle.DEFAULT.noCommaForPredicate; - @CommandLine.Option( names = { "--useLongLiterals" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--useLongLiterals" }, description = "Use long form for literals where possible (Default: ${DEFAULT-VALUE})" ) private boolean useLongLiterals = !FormattingStyle.DEFAULT.useShortLiterals; - @CommandLine.Option( names = { "--alignObjects" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--alignObjects" }, description = "Align objects for same predicates (Default: ${DEFAULT-VALUE})" ) private boolean alignObjects = FormattingStyle.DEFAULT.alignObjects; - @CommandLine.Option( names = { "--alignPredicates" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--alignPredicates" }, description = "Align predicates for same subjects (Default: ${DEFAULT-VALUE})" ) private boolean alignPredicates = FormattingStyle.DEFAULT.alignPredicates; - @CommandLine.Option( names = { "--continuationIndentSize" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--continuationIndentSize" }, description = "Indentation size after forced line wraps (Default: ${DEFAULT-VALUE})" ) private int continuationIndentSize = FormattingStyle.DEFAULT.continuationIndentSize; - @CommandLine.Option( names = { "--doNotInsertFinalNewline" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--doNotInsertFinalNewline" }, description = "Do not insert newline at end of file (Default: ${DEFAULT-VALUE})" ) private boolean doNotInsertFinalNewline = !FormattingStyle.DEFAULT.insertFinalNewline; - @CommandLine.Option( names = { "--indentSize" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--indentSize" }, description = "Indentation size in spaces (Default: ${DEFAULT-VALUE})" ) private int indentSize = FormattingStyle.DEFAULT.indentSize; - @CommandLine.Option( names = { "--keepUnusedPrefixes" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--keepUnusedPrefixes" }, description = "Keeps prefixes that are not part of any statement (Default: ${DEFAULT-VALUE})" ) private boolean keepUnusedPrefixes = FormattingStyle.DEFAULT.keepUnusedPrefixes; - @CommandLine.Option( names = { "--prefixOrder" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--prefixOrder" }, description = "Sort order for prefixes (Default: ${DEFAULT-VALUE})" ) private List prefixOrder = FormattingStyle.DEFAULT.prefixOrder; - @CommandLine.Option( names = { "--subjectOrder" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--subjectOrder" }, description = "Sort order for subjects by type (Default: ${DEFAULT-VALUE})" ) private List subjectOrder = FormattingStyle.DEFAULT.subjectOrder; - @CommandLine.Option( names = { "--predicateOrder" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--predicateOrder" }, description = "Sort order for predicates (Default: ${DEFAULT-VALUE})" ) private List predicateOrder = FormattingStyle.DEFAULT.predicateOrder; - @CommandLine.Option( names = { "--objectOrder" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--objectOrder" }, description = "Sort order for objects (Default: ${DEFAULT-VALUE})" ) private List objectOrder = FormattingStyle.DEFAULT.objectOrder; - @CommandLine.Option( names = { "--anonymousNodeIdPattern" }, + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) + @CommandLine.Option( + names = { "--anonymousNodeIdPattern" }, description = "Name pattern for blank node IDs (Default: ${DEFAULT-VALUE})" ) - private String anonymousNodeIdPattern = - FormattingStyle.DEFAULT.anonymousNodeIdGenerator.apply( ResourceFactory.createResource(), 0 ); + private String anonymousNodeIdPattern = FormattingStyle.DEFAULT.anonymousNodeIdGenerator.apply( ResourceFactory.createResource(), 0 ); - @CommandLine.Parameters( paramLabel = "INPUT", description = "File name, URL, or - for stdin", arity = "1", + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "INPUT", + description = "File name, URL, or - for stdin", + arity = "1", index = "0" ) private String input; - @CommandLine.Parameters( paramLabel = "OUTPUT", + @SuppressWarnings( "unused" ) + @CommandLine.Parameters( + paramLabel = "OUTPUT", description = "File name or - for stdout. If left out, output is written to stdout.", - arity = "0..1", index = "1" ) + arity = "0..1", + index = "1" ) private String output; + protected CoolWrite( final Runtime runtime ) { + super( runtime ); + } + @Override public void run() { final FormattingStyle style = FormattingStyle.builder() @@ -195,7 +273,7 @@ public void run() { .objectOrder( objectOrder ) .anonymousNodeIdGenerator( buildAnonymousNodeIdGenerator( anonymousNodeIdPattern ) ) .knownPrefixes( buildKnownPrefixes( prefixMap ) ) - .emptyRdfBase( "https://github.com/atextor/owl-cli/internal" ) + .emptyRdfBase( RdfModel.DEFAULT_EMPTY_PREFIX ) .build(); final Configuration.ConfigurationBuilder configurationBuilder = Configuration.builder() @@ -209,7 +287,7 @@ public void run() { final Configuration configuration = configurationBuilder.build(); try { final URL inputUrl = new URL( input ); - openOutput( input, output != null ? output : "-", "ttl" ) + openOutput( input, output != null ? Optional.of( output ) : Optional.of( "-" ), "ttl" ) .map( outputStream -> writer.write( inputUrl, outputStream, configuration ) ) .onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); return; @@ -219,11 +297,13 @@ public void run() { } openInput( input ).flatMap( inputStream -> { - final Configuration configuration = configurationBuilder.build(); - return openOutput( input, output != null ? output : "-", "ttl" ) - .flatMap( outputStream -> writer.write( inputStream, outputStream, configuration ) ); - } - ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); + final Configuration configuration = configurationBuilder.build(); + return openOutput( input, output != null ? Optional.of( output ) : Optional.of( "-" ), "ttl" ) + .flatMap( outputStream -> { + LOG.debug( "Calling write command with config {}", configuration ); + return writer.write( inputStream, outputStream, configuration ); + } ); + } ).onFailure( throwable -> exitWithErrorMessage( LOG, loggingMixin, throwable ) ); } @Override @@ -234,23 +314,23 @@ public void registerTypeConverters( final CommandLine commandLine ) { commandLine.registerConverter( RDFNode.class, new RDFNodeConverter() ); } - private URI wellKnownUriByPrefixOrElse( final String prefix, final URI uri ) { - if ( !uri.toString().equals( fallbackUri ) ) { + private String wellKnownUriByPrefixOrElse( final String prefix, final String uri ) { + if ( !uri.equals( fallbackUri ) ) { return uri; } // When we end up here, a prefix was given without a URI, i.e., this is supposed to be a // "well known" prefix. - return FormattingStyle.DEFAULT.knownPrefixes.stream() + return Arrays.stream( Prefixes.values() ) .filter( knownPrefix -> knownPrefix.prefix().equals( prefix ) ) .findAny() - .map( FormattingStyle.KnownPrefix::iri ) + .map( RdfPrefix::uri ) .orElseThrow( () -> new RuntimeException( "Used prefix " + prefix + " is not well-known" ) ); } - private Set buildKnownPrefixes( final Map prefixes ) { - final Set result = prefixes.entrySet().stream().map( entry -> { - final URI uri = wellKnownUriByPrefixOrElse( entry.getKey(), entry.getValue() ); - return new FormattingStyle.KnownPrefix( entry.getKey(), uri ); + private Set buildKnownPrefixes( final Map prefixes ) { + final Set result = prefixes.entrySet().stream().map( entry -> { + final String uri = wellKnownUriByPrefixOrElse( entry.getKey(), entry.getValue().toString() ); + return new DefaultRdfPrefix( entry.getKey(), uri ); } ).collect( Collectors.toSet() ); LOG.debug( "Known prefixes: {}", result ); return result; @@ -262,17 +342,17 @@ private BiFunction buildAnonymousNodeIdGenerator( fin private static class NumberFormatConverter implements CommandLine.ITypeConverter { @Override - public NumberFormat convert( final String value ) throws Exception { + public NumberFormat convert( final String value ) { return new DecimalFormat( value ); } } private abstract class AbstractResourceConverter { - protected String buildResourceUri( final String resourceUri ) throws Exception { + protected String buildResourceUri( final String resourceUri ) { for ( final Map.Entry entry : prefixMap.entrySet() ) { - final URI uri = wellKnownUriByPrefixOrElse( entry.getKey(), entry.getValue() ); + final String uri = wellKnownUriByPrefixOrElse( entry.getKey(), entry.getValue().toString() ); if ( resourceUri.startsWith( entry.getKey() ) ) { - return uri.toString() + resourceUri.substring( ( entry.getKey() + ":" ).length() ); + return uri + resourceUri.substring( ( entry.getKey() + ":" ).length() ); } } LOG.debug( "No prefix declaration matched URI {}, keeping as-is", resourceUri ); @@ -282,7 +362,7 @@ protected String buildResourceUri( final String resourceUri ) throws Exception { private class PropertyConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public Property convert( final String value ) throws Exception { + public Property convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createProperty( propertyUri ); } @@ -290,7 +370,7 @@ public Property convert( final String value ) throws Exception { private class ResourceConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public Resource convert( final String value ) throws Exception { + public Resource convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createResource( propertyUri ); } @@ -298,10 +378,14 @@ public Resource convert( final String value ) throws Exception { private class RDFNodeConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public RDFNode convert( final String value ) throws Exception { + public RDFNode convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createResource( propertyUri ); } } + @Override + public String commandName() { + return COMMAND_NAME; + } } diff --git a/cli/src/main/java/de/atextor/owlcli/ErrorMessage.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/ErrorMessage.java similarity index 67% rename from cli/src/main/java/de/atextor/owlcli/ErrorMessage.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/ErrorMessage.java index 309accc2..7d37874a 100644 --- a/cli/src/main/java/de/atextor/owlcli/ErrorMessage.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/ErrorMessage.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,22 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; -public class ErrorMessage extends Exception { +import java.io.Serial; + +/** + * An error that can occur when loading/saving a file + */ +public class ErrorMessage extends RuntimeException { + @Serial private static final long serialVersionUID = 5086560337386407192L; + /** + * Default constructor + * + * @param message the message + */ public ErrorMessage( final String message ) { super( message ); } diff --git a/cli/src/main/java/de/atextor/owlcli/LoggingMixin.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/LoggingMixin.java similarity index 63% rename from cli/src/main/java/de/atextor/owlcli/LoggingMixin.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/LoggingMixin.java index b29cf63e..b94faadd 100644 --- a/cli/src/main/java/de/atextor/owlcli/LoggingMixin.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/LoggingMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -28,45 +28,72 @@ import static picocli.CommandLine.Spec.Target.MIXEE; +/** + * A mixin for logging functionality that + * is shared across commands. The mixin sets up and uses logback. + */ public class LoggingMixin { - private @CommandLine.Spec( MIXEE ) - CommandLine.Model.CommandSpec mixee; + @SuppressWarnings( { "unused", "SpellCheckingInspection" } ) + private @CommandLine.Spec( MIXEE ) CommandLine.Model.CommandSpec mixee; private boolean[] verbosity = new boolean[0]; private static LoggingMixin getTopLevelCommandLoggingMixin( final CommandLine.Model.CommandSpec commandSpec ) { - return ( (OWLCLI) commandSpec.root().userObject() ).loggingMixin; + return ( (Cool) commandSpec.root().userObject() ).loggingMixin; } + /** + * The method to set as the CLI execution strategy, to enable the logging mixin + * + * @param parseResult the result of the respective arguments parsing process + * @return the execution result + */ public static int executionStrategy( final CommandLine.ParseResult parseResult ) { getTopLevelCommandLoggingMixin( parseResult.commandSpec() ).configureLoggers(); return new CommandLine.RunLast().execute( parseResult ); } - @CommandLine.Option( names = { "-v", "--verbose" }, description = { - "Specify multiple -v options to increase verbosity,", - "e.g. use `-v`, `-vv` or `-vvv` for more details" } ) + /** + * The option that is injected into commands using this mixin + * + * @param verbosity the verbosity, one array entry for every stacked -v occurrence + */ + @SuppressWarnings( "unused" ) + @CommandLine.Option( + names = { "-v", "--verbose" }, + description = { + "Specify multiple -v options to increase verbosity,", + "e.g. use `-v`, `-vv` or `-vvv` for more details" } ) public void setVerbose( final boolean[] verbosity ) { getTopLevelCommandLoggingMixin( mixee ).verbosity = verbosity; } + /** + * Gets the configured logging verbosity in raw format, with one array entry for every stacked -v occurrence + * + * @return the verbosity + */ public boolean[] getVerbosity() { return getTopLevelCommandLoggingMixin( mixee ).verbosity; } + /** + * Determine the logback log level from the configured verbosity + * + * @return the log level + */ public Level calcLogLevel() { return switch ( getVerbosity().length ) { - case 0: - yield Level.WARN; - case 1: - yield Level.INFO; - case 2: - yield Level.DEBUG; - default: - yield Level.TRACE; + case 0 -> Level.WARN; + case 1 -> Level.INFO; + case 2 -> Level.DEBUG; + default -> Level.TRACE; }; } + /** + * Set up the logback logging structure + */ public void configureLoggers() { final Level level = getTopLevelCommandLoggingMixin( mixee ).calcLogLevel(); final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CaffeineFeature.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CaffeineFeature.java new file mode 100644 index 00000000..79a1bff9 --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CaffeineFeature.java @@ -0,0 +1,64 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class CaffeineFeature implements Feature { + @Override + public void beforeAnalysis( final BeforeAnalysisAccess access ) { + Native.forClass( "com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef" ) + .registerClass().registerFields( "writeCounter" ); + Native.forClass( "com.github.benmanes.caffeine.cache.BBHeader$ReadCounterRef" ) + .registerClass().registerFields( "readCounter" ); + Native.forClass( "com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef" ) + .registerClass().registerFields( "drainStatus" ); + Native.forClass( "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueColdProducerFields" ) + .registerClass().registerFields( "producerLimit" ); + Native.forClass( "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueConsumerFields" ) + .registerClass().registerFields( "consumerIndex" ); + Native.forClass( "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueProducerFields" ) + .registerClass().registerFields( "producerIndex" ); + Native.forClass( "com.github.benmanes.caffeine.cache.FS" ) + .registerClass().registerFields( "key", "value" ); + Native.forClass( "com.github.benmanes.caffeine.cache.FSMS" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.PS" ) + .registerClass().registerAllConstructors().registerFields( "key", "value" ); + Native.forClass( "com.github.benmanes.caffeine.cache.PSMS" ) + .registerClass().registerAllConstructors(); + Native.forClass( "com.github.benmanes.caffeine.cache.PSMW" ) + .registerClass().registerConstructor(); + Native.forClass( "com.github.benmanes.caffeine.cache.SSMS" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.SSMW" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.WSMS" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.WSSMW" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.FSMW" ) + .registerClass().registerAllConstructors().registerAllMethods().registerAllFields(); + Native.forClass( "com.github.benmanes.caffeine.cache.StripedBuffer" ) + .registerClass().registerFields( "tableBusy" ); + Native.forClass( "com.github.benmanes.caffeine.cache.CacheLoader" ) + .registerClass().registerMethod( "loadAll", Iterable.class ); + } +} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CoolRdfFeature.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CoolRdfFeature.java new file mode 100644 index 00000000..16997670 --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/CoolRdfFeature.java @@ -0,0 +1,69 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import cool.rdf.cli.AbstractCommand; +import cool.rdf.cli.Cool; +import cool.rdf.cli.CoolDiagram; +import cool.rdf.cli.CoolInfer; +import cool.rdf.cli.CoolWrite; +import cool.rdf.cli.LoggingMixin; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; +import picocli.CommandLine; + +import java.util.List; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class CoolRdfFeature implements Feature { + @Override + public void beforeAnalysis( final BeforeAnalysisAccess access ) { + Native.forClass( AbstractCommand.class ).registerClass().registerAllFields().registerAllMethods(); + Native.forClass( LoggingMixin.class ).registerClass().registerConstructor().registerAllFields().registerAllMethods(); + Native.forClass( Cool.class ).registerClass().registerAllFields().registerAllMethods(); + Native.forClass( CoolDiagram.class ).registerClass().registerAllFields().registerAllMethods(); + Native.forClass( CoolWrite.class ).registerClass().registerAllFields().registerAllMethods(); + Native.forClass( CoolInfer.class ).registerClass().registerAllFields().registerAllMethods(); + + Native.forClass( java.io.FilePermission.class ).registerClass(); + Native.forClass( java.lang.Object.class ).registerClass().registerAllFields().registerAllMethods(); + Native.forClass( java.lang.RuntimePermission.class ).registerClass(); + Native.forClass( java.lang.Thread.class ).registerClass().registerFields( "threadLocalRandomProbe" ); + Native.forClass( java.net.NetPermission.class ).registerClass(); + Native.forClass( java.net.SocketPermission.class ).registerClass(); + Native.forClass( java.util.PropertyPermission.class ).registerClass(); + Native.forClass( java.net.URLPermission.class ).registerClass().registerConstructor( String.class, String.class ); + Native.forClass( java.nio.file.Path.class ).registerClass(); + Native.forClass( java.nio.file.Paths.class ).registerClass().registerMethod( "get", String.class, String.class.arrayType() ); + Native.forClass( java.security.AllPermission.class ).registerClass(); + Native.forClass( java.security.SecurityPermission.class ).registerClass(); + Native.forClass( CommandLine.HelpCommand.class ).registerClass().registerAllFields().registerAllMethods(); + + Native.forClass( "sun.misc.Unsafe" ).registerClass().registerFields( "theUnsafe" ); + + Native.forClass( ClassNotFoundException.class ).registerClassForJni(); + Native.forClass( NoSuchMethodError.class ).registerClassForJni(); + Native.forClass( ClassLoader.class ).registerMethodForJni( "getPlatformClassLoader" ); + Native.forClass( ClassLoader.class ).registerMethodForJni( "loadClass", String.class ); + } + + @Override + public List> getRequiredFeatures() { + return List.of( JenaFeature.class, LogbackFeature.class, OwlApiFeature.class ); + } +} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/JenaFeature.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/JenaFeature.java new file mode 100644 index 00000000..c0233e7e --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/JenaFeature.java @@ -0,0 +1,68 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class JenaFeature implements Feature { + @Override + public void beforeAnalysis( final BeforeAnalysisAccess access ) { + Native.forClass( org.apache.jena.base.module.SubsystemRegistryServiceLoader.class ).initializeAtBuildTime(); + Native.forClass( org.apache.jena.util.LocationMapper.class ).initializeAtBuildTime(); + Native.forClass( org.apache.jena.riot.system.stream.JenaIOEnvironment.class ).initializeAtBuildTime(); + + Native.forClass( "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl" ).registerClass().registerConstructor(); + Native.forClass( "com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl" ).registerClass().registerConstructor(); + Native.forClass( org.apache.jena.rdf.model.impl.NTripleReader.class ).registerClass().registerAllMethods(); + Native.forClass( org.apache.jena.rdf.model.impl.NTripleWriter.class ).registerClass().registerAllMethods(); + + Native.forClass( "com.github.jsonldjava.shaded.com.google.common.cache.Striped64" ) + .registerClass().registerFields( "base", "busy" ); + + Native.forClass( java.sql.Connection.class ).registerClass(); + Native.forClass( java.sql.Driver.class ).registerClass(); + Native.forClass( java.sql.DriverManager.class ) + .registerClass().registerMethod( "getConnection", String.class ).registerMethod( "getDriver", String.class ); + Native.forClass( java.sql.Time.class ).registerClass().registerConstructor( long.class ); + Native.forClass( java.sql.Timestamp.class ).registerClass().registerMethod( "valueOf", String.class ); + Native.forClass( java.time.Duration.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.Instant.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.LocalDate.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.LocalDateTime.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.LocalTime.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.MonthDay.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.OffsetDateTime.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.OffsetTime.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.Period.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.Year.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.YearMonth.class ).registerClass().registerMethod( "parse", CharSequence.class ); + Native.forClass( java.time.ZoneId.class ).registerClass().registerMethod( "of", String.class ); + Native.forClass( java.time.ZoneOffset.class ).registerClass().registerMethod( "of", String.class ); + Native.forClass( java.time.ZonedDateTime.class ).registerClass().registerMethod( "parse", CharSequence.class ); + + Native.withModule( org.apache.jena.Jena.class.getModule() ) + .addResource( "META-INF/services/org.apache.jena.sys.JenaSubSystemLifeCycle" ) + .addResource( "org/apache/jena/jena-properties.xml" ) + .addResourceBundle( "org.apache.jena.ext.xerces.impl.xpath.regex.message" ); + + Native.withModule( "java.xml" ) + .addResourceBundle( "com.sun.org.apache.xerces.internal.impl.msg.XMLMessages" ); + } +} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/LogbackFeature.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/LogbackFeature.java new file mode 100644 index 00000000..de4618c2 --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/LogbackFeature.java @@ -0,0 +1,82 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class LogbackFeature implements Feature { + @Override + public void beforeAnalysis( final BeforeAnalysisAccess access ) { + Native.forClass( org.slf4j.LoggerFactory.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.classic.Level.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.classic.Logger.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.classic.PatternLayout.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.util.Loader.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.util.StatusPrinter.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.status.InfoStatus.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.status.StatusBase.class ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.spi.AppenderAttachableImpl.class ).initializeAtBuildTime(); + Native.forClass( "ch.qos.logback.core.pattern.parser.TokenStream$1" ).initializeAtBuildTime(); + Native.forClass( ch.qos.logback.core.pattern.parser.Parser.class ).initializeAtBuildTime(); + + Native.forClass( ch.qos.logback.classic.pattern.ClassOfCallerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.ContextNameConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.DateConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.FileOfCallerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.LevelConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.LineOfCallerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.LineSeparatorConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.LocalSequenceNumberConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.LoggerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.MDCConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.MarkerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.MessageConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.MethodOfCallerConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.NopThrowableInformationConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.PropertyConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.RelativeTimeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.ThreadConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.ThrowableProxyConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.IdentityCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.ReplacingCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BlackCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldRedCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.CyanCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.GrayCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.GreenCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.MagentaCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.RedCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.WhiteCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.pattern.color.YellowCompositeConverter.class ).registerClass(); + Native.forClass( ch.qos.logback.core.util.StatusPrinter.class ).registerClass(); + + Native.withModule( LogbackFeature.class.getClassLoader().getUnnamedModule() ) + .addResource( "org/slf4j/impl/StaticLoggerBinder.class" ); + } +} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/Native.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/Native.java new file mode 100644 index 00000000..fa78ea9e --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/Native.java @@ -0,0 +1,155 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import com.oracle.svm.core.jni.JNIRuntimeAccess; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.RuntimeReflection; +import org.graalvm.nativeimage.hosted.RuntimeResourceAccess; + +import javax.annotation.Nonnull; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class Native { + private final Class clazz; + + Native( final Class clazz ) { + this.clazz = clazz; + } + + public static Native forClass( final Class clazz ) { + return new Native( clazz ); + } + + public static Native forClass( final String fullyQualifiedJavaClass ) { + final Class clazz; + try { + clazz = Class.forName( fullyQualifiedJavaClass, false, Native.class.getClassLoader() ); + } catch ( final ClassNotFoundException exception ) { + throw new RuntimeException( exception ); + } + return forClass( clazz ); + } + + public Native initializeAtBuildTime() { + org.graalvm.nativeimage.hosted.RuntimeClassInitialization.initializeAtBuildTime( clazz ); + return this; + } + + public Native registerClass() { + RuntimeReflection.register( clazz ); + return this; + } + + public Native registerAllFields() { + for ( final Field field : clazz.getDeclaredFields() ) { + RuntimeReflection.register( field ); + } + return this; + } + + public Native registerFields( @Nonnull final String... fieldNames ) { + for ( final Field field : clazz.getDeclaredFields() ) { + for ( final String targetField : fieldNames ) { + if ( field.getName().equals( targetField ) ) { + RuntimeReflection.register( field ); + } + } + } + return this; + } + + public Native registerAllConstructors() { + for ( final Constructor constructor : clazz.getDeclaredConstructors() ) { + RuntimeReflection.register( constructor ); + } + return this; + } + + public Native registerConstructor( final Class... args ) { + try { + RuntimeReflection.register( clazz.getDeclaredConstructor( args ) ); + } catch ( final NoSuchMethodException exception ) { + throw new RuntimeException( exception ); + } + return this; + } + + public Native registerAllMethods() { + for ( final Method method : clazz.getDeclaredMethods() ) { + RuntimeReflection.register( method ); + } + return this; + } + + public Native registerMethod( final String name, final Class... args ) { + try { + RuntimeReflection.register( clazz.getDeclaredMethod( name, args ) ); + } catch ( final NoSuchMethodException exception ) { + throw new RuntimeException( exception ); + } + return this; + } + + public Native registerClassForJni() { + JNIRuntimeAccess.register( clazz ); + return this; + } + + public Native registerMethodForJni( final String name, final Class... args ) { + try { + JNIRuntimeAccess.register( clazz.getDeclaredMethod( name, args ) ); + } catch ( final NoSuchMethodException exception ) { + throw new RuntimeException( exception ); + } + return this; + } + + public static WithModule withModule( final Module module ) { + return new WithModule( module ); + } + + public static WithModule withModule( final String moduleName ) { + return new WithModule( moduleName ); + } + + static class WithModule { + private final Module module; + + WithModule( final Module module ) { + this.module = module; + } + + WithModule( final String moduleName ) { + this( ModuleLayer.boot().findModule( moduleName ).orElseThrow( RuntimeException::new ) ); + } + + public WithModule addResource( final String resource ) { + RuntimeResourceAccess.addResource( module, resource ); + return this; + } + + public WithModule addResourceBundle( final String resourceBundle ) { + RuntimeResourceAccess.addResourceBundle( module, resourceBundle ); + return this; + } + } +} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/OwlApiFeature.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/OwlApiFeature.java new file mode 100644 index 00000000..1a09a336 --- /dev/null +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/feature/OwlApiFeature.java @@ -0,0 +1,84 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli.graal.feature; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; + +import java.util.List; + +@Platforms( Platform.HOSTED_ONLY.class ) +public class OwlApiFeature implements Feature { + @Override + public void beforeAnalysis( final BeforeAnalysisAccess access ) { + Native.forClass( uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.class ).initializeAtBuildTime(); + + Native.forClass( "uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl" ).registerClass(); + Native.forClass( "uk.ac.manchester.cs.owl.owlapi.OWLOntologyFactoryImpl" ).registerClass(); + Native.forClass( "uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyBuilder" ).registerClass(); + Native.forClass( "uk.ac.manchester.cs.owl.owlapi.concurrent.NonConcurrentOWLOntologyBuilder" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.latex.renderer.LatexStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioBinaryRdfParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioBinaryRdfStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioJsonLDParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioJsonLDStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioJsonParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioJsonStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioN3ParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioN3StorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioNQuadsParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioNQuadsStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioNTriplesParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioNTriplesStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioRDFXMLParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioRDFXMLStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioRDFaParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTrigParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTrigStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTrixParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTrixStorerFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTurtleParserFactory" ).registerClass(); + Native.forClass( "org.semanticweb.owlapi.rio.RioTurtleStorerFactory" ).registerClass(); + + Native.forClass( "org.semanticweb.owlapi.apibinding.OWLManager$InjectorConstants" ) + .registerClass() + .registerFields( "COMPRESSION_ENABLED", "CONCURRENTBUILDER", "CONFIG", "NONCONCURRENTBUILDER", "NOOP", "REENTRANT" ); + } + + @Override + public List> getRequiredFeatures() { + return List.of( CaffeineFeature.class ); + } +} diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java similarity index 84% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java index 7b6bed2e..7ffea1be 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package cool.rdf.cli.graal.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Substitute; @@ -29,9 +29,15 @@ import java.util.List; +/** + * Substitution class for {@link SubsystemRegistryServiceLoader} + * + * @param the type argument + */ +@SuppressWarnings( { "unused" } ) @TargetClass( SubsystemRegistryServiceLoader.class ) -@SuppressWarnings( "unused" ) -public final class Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader implements SubsystemRegistry { +public final class Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader implements + SubsystemRegistry { @Override @Substitute @SuppressWarnings( "unchecked" ) diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java similarity index 87% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java index f88ef7fa..a22d5cfc 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package cool.rdf.cli.graal.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; @@ -25,6 +25,9 @@ import java.io.Serial; +/** + * Substitution class for {@link JenaIOEnvironment} + */ @SuppressWarnings( "unused" ) @TargetClass( JenaIOEnvironment.class ) public final class Target_org_apache_jena_riot_system_stream_JenaIOEnvironment { diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_FileManagerImpl.java similarity index 66% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_FileManagerImpl.java index 41886592..00801664 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_FileManagerImpl.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package cool.rdf.cli.graal.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Substitute; @@ -24,13 +24,27 @@ import java.util.List; +/** + * Substitution class for {@link FileManagerImpl} + */ +@SuppressWarnings( { "unused", "allJavadoc" } ) @TargetClass( FileManagerImpl.class ) public final class Target_org_apache_jena_util_FileManagerImpl { + /** + * See fmHandlers field in original FileManagerImpl + */ + @SuppressWarnings( { "unused", "ProtectedMemberInFinalClass" } ) @Alias protected List fmHandlers; + /** + * See addLocator() method in original FileManagerImpl + * + * @param loc see original method + */ + @SuppressWarnings( "unused" ) @Substitute public void addLocator( final Locator loc ) { fmHandlers.add( loc ); } -} \ No newline at end of file +} diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_LocationMapper.java similarity index 82% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java rename to cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_LocationMapper.java index 5565add4..788362a5 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/graal/substitution/Target_org_apache_jena_util_LocationMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package cool.rdf.cli.graal.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; @@ -25,6 +25,9 @@ import java.io.Serial; +/** + * Substitution for {@link LocationMapper}. This will silence Jena's "can't find location-mapping.rdf" complaints. + */ @SuppressWarnings( "unused" ) @TargetClass( LocationMapper.class ) public final class Target_org_apache_jena_util_LocationMapper { diff --git a/cool-rdf-cli/src/main/resources/logback.xml b/cool-rdf-cli/src/main/resources/logback.xml new file mode 100644 index 00000000..e34d9f52 --- /dev/null +++ b/cool-rdf-cli/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + System.out + + %m%n + + + + + + + + + + + diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/BinaryTest.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/BinaryTest.java new file mode 100644 index 00000000..7b36ac8b --- /dev/null +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/BinaryTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.File; + +import static org.assertj.core.api.Assumptions.assumeThat; + +@ExtendWith( TestExecutionLogger.class ) +public class BinaryTest extends CoolTest { + private static File binary; + + @BeforeAll + static void beforeMethod() { + final String binaryPath = System.getProperty( "binary" ); + assumeThat( binaryPath ).isNotNull(); + binary = new File( binaryPath ); + assumeThat( binary ).isFile(); + assumeThat( binary ).exists(); + + final String packaging = System.getProperty( "packaging.type" ); + assumeThat( packaging ).isEqualTo( "native" ); + } + + @Override + protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { + return CliRunner.runBinary( binary, arguments ); + } +} diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java new file mode 100644 index 00000000..5676f8db --- /dev/null +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java @@ -0,0 +1,237 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.spy; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.Serial; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Convenient test runner to execute a command line interface either via main class, executable jar or native binary. + * Arguments and stdin can be provided, return code, stderr and stdout are captured. This class uses Mockito to capture + * calls to {@link Runtime#exit(int)}: It relies on the tested class having a non-final field "java.lang.Runtime + * runtime" which is used to calling exit(). + */ +public class CliRunner { + private static final Logger LOG = LoggerFactory.getLogger( CliRunner.class ); + + /** + * Represents the content of a stream (stdin/stdout/stderr) + * + * @param raw the raw byte content + */ + public record StreamContent( byte[] raw ) { + /** + * Returns the stream content as UTF-8 string + * + * @return the stream content as string + */ + public String asString() { + return new String( raw, StandardCharsets.UTF_8 ); + } + + /** + * Returns the stream content as string with all non-printable non-ASCII characters removed + * + * @return the stream without non-printable non-ASCII characters + */ + public String cleaned() { + return asString().replaceAll( "\\P{Print}", "" ); + } + } + + public record ExecArguments( List arguments, StreamContent stdin, File workingDirectory ) { + public ExecArguments( final List arguments, final StreamContent stdin ) { + this( arguments, stdin, new File( "." ).getAbsoluteFile() ); + } + + public ExecArguments( final List arguments ) { + this( arguments, new StreamContent( new byte[0] ) ); + } + + public ExecArguments( final String... arguments ) { + this( List.of( arguments ) ); + } + } + + public record Result( int exitStatus, StreamContent stdOut, StreamContent stdErr ) { + } + + private static class SystemExitCapturedException extends RuntimeException { + @Serial + private static final long serialVersionUID = 6080552325336609875L; + + private final int returnCode; + + private SystemExitCapturedException( final int returnCode ) { + this.returnCode = returnCode; + } + } + + private record StreamCollector( InputStream in ) implements Callable { + @Override + public ByteArrayOutputStream call() throws Exception { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + in.transferTo( buffer ); + return buffer; + } + } + + /** + * Executes a command line tool via its main class. This also captures any System.exit() calls that might be done. + * + * @param clazz the class + * @param execArguments the arguments + * @return the execution result + */ + public static Result runMainClass( final Class clazz, final ExecArguments execArguments ) { + final PrintStream originalStdout = System.out; + final PrintStream originalStderr = System.err; + final InputStream originalStdin = System.in; + final String originalUserDir = System.getProperty( "user.dir" ); + + try ( + final ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); + final ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); + final PrintStream outStream = new PrintStream( stdoutBuffer ); + final PrintStream errStream = new PrintStream( stderrBuffer ) ) { + System.setOut( outStream ); + System.setErr( errStream ); + + if ( execArguments.stdin().raw().length > 0 ) { + System.setIn( new ByteArrayInputStream( execArguments.stdin().raw() ) ); + } + + System.setProperty( "user.dir", execArguments.workingDirectory().getAbsolutePath() ); + final Method method = clazz.getMethod( "main", String[].class ); + + // Mock runtime for the tested class, in order to capture + // calls to System.exit() + try { + final Runtime spyRuntime = spy( Runtime.getRuntime() ); + final Field runtime = clazz.getDeclaredField( "runtime" ); + runtime.setAccessible( true ); + runtime.set( null, spyRuntime ); + doThrow( new SystemExitCapturedException( -1 ) ).when( spyRuntime ).exit( anyInt() ); + doThrow( new SystemExitCapturedException( 1 ) ).when( spyRuntime ).exit( 1 ); + doThrow( new SystemExitCapturedException( 0 ) ).when( spyRuntime ).exit( 0 ); + } catch ( final NoSuchFieldException exception ) { + throw new RuntimeException( exception ); + } + + int returnCode = 0; + try { + method.invoke( null, (Object) execArguments.arguments().toArray( new String[0] ) ); + } catch ( final InvocationTargetException exception ) { + // Ignore System.exit, throw everything else + if ( exception.getCause() instanceof SystemExitCapturedException systemExitCapturedException ) { + returnCode = systemExitCapturedException.returnCode; + } else { + throw new RuntimeException( exception ); + } + } + return new Result( returnCode, + new StreamContent( stdoutBuffer.toByteArray() ), + new StreamContent( stderrBuffer.toByteArray() ) ); + } catch ( final NoSuchMethodException | IllegalAccessException | IOException exception ) { + throw new RuntimeException( exception ); + } finally { + System.setOut( originalStdout ); + System.setErr( originalStderr ); + if ( execArguments.stdin().raw().length > 0 ) { + System.setIn( originalStdin ); + } + System.setProperty( "user.dir", originalUserDir ); + } + } + + /** + * Executes a command line interface via its executable jar + * + * @param jarFile the jar file + * @param execArguments the arguments + * @param jvmArguments additional arguments that should be passed to the Java call + * @return the execution result + */ + public static Result runJar( final File jarFile, final ExecArguments execArguments, final List jvmArguments ) { + final File javaBinary = new File( ProcessHandle.current().info().command().orElse( "java" ) ); + + final List javaExecArguments = Stream.of( + jvmArguments.stream(), + Stream.of( "-jar", jarFile.toString() ), + execArguments.arguments().stream() ).flatMap( Function.identity() ).toList(); + + return runBinary( javaBinary, new ExecArguments( javaExecArguments, execArguments.stdin(), execArguments.workingDirectory() ) ); + } + + /** + * Executes a command line interface via its native executable + * + * @param binary the executable file + * @param executionArgument the arguments + * @return the execution result + */ + public static Result runBinary( final File binary, final ExecArguments executionArgument ) { + LOG.debug( "Executing command (in {}): \"{}\" {}", + executionArgument.workingDirectory(), binary, executionArgument.arguments().stream() + .map( argument -> '"' + argument + '"' ) + .collect( Collectors.joining( " " ) ) ); + try { + final List commandWithAllArguments = Stream.concat( Stream.of( binary.toString() ), executionArgument.arguments() + .stream() ).toList(); + final Process process = Runtime.getRuntime() + .exec( commandWithAllArguments.toArray( new String[0] ), null, executionArgument.workingDirectory() ); + if ( executionArgument.stdin().raw().length > 0 ) { + process.getOutputStream().write( executionArgument.stdin().raw() ); + } + process.getOutputStream().close(); + final ExecutorService executor = Executors.newFixedThreadPool( 2 ); + final Future stdout = executor.submit( new StreamCollector( process.getInputStream() ) ); + final Future stderr = executor.submit( new StreamCollector( process.getErrorStream() ) ); + process.waitFor(); + + return new Result( process.exitValue(), new StreamContent( stdout.get().toByteArray() ), + new StreamContent( stderr.get().toByteArray() ) ); + } catch ( final IOException | InterruptedException | ExecutionException exception ) { + throw new RuntimeException( exception ); + } + } +} diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/CoolTest.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/CoolTest.java new file mode 100644 index 00000000..8edaea44 --- /dev/null +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/CoolTest.java @@ -0,0 +1,283 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import cool.rdf.core.model.RdfModel; +import org.apache.commons.io.FileUtils; +import org.apache.jena.riot.Lang; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +@ExtendWith( TestExecutionLogger.class ) +public class CoolTest { + protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { + return CliRunner.runMainClass( Cool.class, arguments ); + } + + private static Path tempDir; + + // Process return codes + private final int OK = 0; + + private final int ERROR = 1; + + @BeforeEach + void beforeEach() throws IOException { + tempDir = Files.createTempDirectory( "junit" ); + } + + @AfterEach + void afterEach() { + try { + FileUtils.deleteDirectory( tempDir.toFile() ); + } catch ( final IOException exception ) { + // ignore + } + } + + @AfterAll + static void afterAll() { + if ( tempDir != null && tempDir.toFile().exists() ) { + try { + FileUtils.deleteDirectory( tempDir.toFile() ); + } catch ( final IOException exception ) { + // ignore + } + } + } + + @Test + void testNoArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( List.of( "--disable-color" ) ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().cleaned() ).as( "stdout" ).contains( "Usage:" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testHelp() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--disable-color", "--help" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().cleaned() ).as( "stdout" ).contains( "Usage:" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testInvalidArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--disable-color", "invalid_argument" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().cleaned() ).as( "stderr" ).contains( "Error:" ); + } + + @Test + void testHelpDiagram() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--disable-color", "help", CoolDiagram.COMMAND_NAME ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().cleaned() ).as( "stdout" ) + .contains( "Usage: " + StaticCliInfo.COMMAND_NAME + " " + CoolDiagram.COMMAND_NAME ); + assertThat( result.stdOut().cleaned() ).as( "stdout" ).contains( "--direction=" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testDiagramWithoutArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--disable-color", CoolDiagram.COMMAND_NAME ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().cleaned() ).as( "stderr" ).contains( "Error:" ); + assertThat( result.stdErr().cleaned() ).as( "stderr" ) + .contains( "Usage: " + StaticCliInfo.COMMAND_NAME + " " + CoolDiagram.COMMAND_NAME ); + } + + @Test + void testDiagramWithInvalidArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--disable-color", CoolDiagram.COMMAND_NAME, + "invalid_argument" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().cleaned() ).as( "stderr" ).contains( "Error:" ); + } + + @ParameterizedTest + @ArgumentsSource( ResourceArgumentsProvider.class ) + void testDiagramGeneration( final String testFileName ) throws IOException { + final URL input = CoolTest.class.getResource( "/" + testFileName + ".ttl" ); + final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); + + assertThat( input ).isNotNull(); + FileUtils.copyURLToFile( input, output ); + assertThat( output ).isFile(); + assertThat( output ).content().isNotEmpty(); + + final List arguments = List.of( "--disable-color", CoolDiagram.COMMAND_NAME, output.getAbsolutePath() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments ) ); + if ( result.stdErr().raw().length > 0 || result.exitStatus() != OK ) { + System.out.println( "stderr:" ); + System.out.println( result.stdErr().asString() ); + } + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); + assertThat( writtenFile ).isFile(); + assertThat( writtenFile ).content().contains( " . + @prefix rdfs: . + + :Person a rdfs:Class . + :name a rdfs:Property . + :address a rdfs:Property . + :city a rdfs:Property . + :Max a :Person ; + :name "Max" ; + :address [ + :city "City Z" + ] . + """; + final List arguments = List.of( "--disable-color", CoolWrite.COMMAND_NAME, "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> RdfModel.fromTurtle( result.stdOut().cleaned() ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteRdfXml() { + final String rdfXmlDocument = """ + + + + + +
+ Max + + + + City Z + + + + + + + + + + + + """; + final List arguments = List.of( "--disable-color", CoolWrite.COMMAND_NAME, "-i", "rdfxml", "-o", "rdfxml", "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( rdfXmlDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> RdfModel.fromDocument( result.stdOut().cleaned(), Lang.RDFXML ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteNTriple() { + final String ntripleDocument = """ + . + . + . + _:gen0 "City Z"^^ . + _:gen0 . + "Max"^^ . + . + . + """; + final List arguments = List.of( "--disable-color", CoolWrite.COMMAND_NAME, "-i", "ntriple", "-o", "ntriple", "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( ntripleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> RdfModel.fromDocument( result.stdOut().cleaned(), Lang.NTRIPLES ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteTurtleWithEmptyBase() { + final String turtleDocument = """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """; + final List arguments = List.of( "--disable-color", CoolWrite.COMMAND_NAME, "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> RdfModel.fromTurtle( result.stdOut().cleaned() ) ).doesNotThrowAnyException(); + assertThat( result.stdOut().cleaned() ).isEqualToIgnoringWhitespace( turtleDocument ); + } +} diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/ExecutableJarTest.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/ExecutableJarTest.java new file mode 100644 index 00000000..c4d927b7 --- /dev/null +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/ExecutableJarTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.File; +import java.util.List; + +import static org.assertj.core.api.Assumptions.assumeThat; + +@ExtendWith( TestExecutionLogger.class ) +public class ExecutableJarTest extends CoolTest { + private static File executableJar; + + @BeforeAll + static void beforeMethod() { + final String executableJarPath = System.getProperty( "executableJar" ); + assumeThat( executableJarPath ).isNotNull(); + executableJar = new File( executableJarPath ); + assumeThat( executableJar ).isFile(); + assumeThat( executableJar ).exists(); + + final String packaging = System.getProperty( "packaging.type" ); + assumeThat( packaging ).isEqualTo( "jar" ); + } + + @Override + protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { + return CliRunner.runJar( executableJar, arguments, List.of() ); + } +} diff --git a/cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/ResourceArgumentsProvider.java similarity index 70% rename from cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java rename to cool-rdf-cli/src/test/java/cool/rdf/cli/ResourceArgumentsProvider.java index 9e8972d6..a181448e 100644 --- a/cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/ResourceArgumentsProvider.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.cli; import io.github.classgraph.ClassGraph; +import io.github.classgraph.ScanResult; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; @@ -29,15 +30,17 @@ public class ResourceArgumentsProvider implements ArgumentsProvider { @Override public Stream provideArguments( final ExtensionContext context ) { - return new ClassGraph().scan().getResourcesWithExtension( ".ttl" ).getPaths().stream() - .map( filename -> filename.replace( ".ttl", "" ) ) - .filter( filename -> !filename.contains( "/" ) ) - .sorted() - .map( FilenameArguments::new ); + try ( final ScanResult scanResult = new ClassGraph().scan() ) { + return scanResult.getResourcesWithExtension( ".ttl" ).getPaths().stream() + .map( filename -> filename.replace( ".ttl", "" ) ) + .filter( filename -> !filename.contains( "/" ) ) + .sorted() + .map( FilenameArguments::new ); + } } public static class FilenameArguments implements Arguments { - String filename; + final String filename; public FilenameArguments( final String filename ) { this.filename = filename; diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/TestExecutionLogger.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/TestExecutionLogger.java new file mode 100644 index 00000000..c5231c84 --- /dev/null +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/TestExecutionLogger.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.cli; + +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Optional; + +public class TestExecutionLogger implements BeforeTestExecutionCallback, AfterTestExecutionCallback { + private static final Logger LOG = LoggerFactory.getLogger( TestExecutionLogger.class ); + + @Override + public void beforeTestExecution( final ExtensionContext context ) throws Exception { + LOG.info( "Run test " + context.getDisplayName() ); + } + + @Override + public void afterTestExecution( final ExtensionContext context ) { + final Optional executionException = context.getExecutionException(); + if ( executionException.isPresent() ) { + LOG.info( "Exception in test {}:", context.getDisplayName(), executionException.get() ); + } else { + LOG.info( " {}: success", context.getDisplayName() ); + } + } +} diff --git a/cli/src/test/resources/asymmetric-objectproperty.ttl b/cool-rdf-cli/src/test/resources/asymmetric-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/asymmetric-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/asymmetric-objectproperty.ttl diff --git a/cli/src/test/resources/class-assertion.ttl b/cool-rdf-cli/src/test/resources/class-assertion.ttl similarity index 100% rename from cli/src/test/resources/class-assertion.ttl rename to cool-rdf-cli/src/test/resources/class-assertion.ttl diff --git a/cli/src/test/resources/data-intersection.ttl b/cool-rdf-cli/src/test/resources/data-intersection.ttl similarity index 100% rename from cli/src/test/resources/data-intersection.ttl rename to cool-rdf-cli/src/test/resources/data-intersection.ttl diff --git a/cli/src/test/resources/dataproperty-assertion.ttl b/cool-rdf-cli/src/test/resources/dataproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-assertion.ttl rename to cool-rdf-cli/src/test/resources/dataproperty-assertion.ttl diff --git a/cli/src/test/resources/dataproperty-domain.ttl b/cool-rdf-cli/src/test/resources/dataproperty-domain.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-domain.ttl rename to cool-rdf-cli/src/test/resources/dataproperty-domain.ttl diff --git a/cli/src/test/resources/dataproperty-range.ttl b/cool-rdf-cli/src/test/resources/dataproperty-range.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-range.ttl rename to cool-rdf-cli/src/test/resources/dataproperty-range.ttl diff --git a/cli/src/test/resources/datarange-expression.ttl b/cool-rdf-cli/src/test/resources/datarange-expression.ttl similarity index 100% rename from cli/src/test/resources/datarange-expression.ttl rename to cool-rdf-cli/src/test/resources/datarange-expression.ttl diff --git a/cli/src/test/resources/datatype-definition.ttl b/cool-rdf-cli/src/test/resources/datatype-definition.ttl similarity index 100% rename from cli/src/test/resources/datatype-definition.ttl rename to cool-rdf-cli/src/test/resources/datatype-definition.ttl diff --git a/cli/src/test/resources/different-individuals.ttl b/cool-rdf-cli/src/test/resources/different-individuals.ttl similarity index 100% rename from cli/src/test/resources/different-individuals.ttl rename to cool-rdf-cli/src/test/resources/different-individuals.ttl diff --git a/cli/src/test/resources/disjoint-classes.ttl b/cool-rdf-cli/src/test/resources/disjoint-classes.ttl similarity index 100% rename from cli/src/test/resources/disjoint-classes.ttl rename to cool-rdf-cli/src/test/resources/disjoint-classes.ttl diff --git a/cli/src/test/resources/disjoint-dataproperties.ttl b/cool-rdf-cli/src/test/resources/disjoint-dataproperties.ttl similarity index 100% rename from cli/src/test/resources/disjoint-dataproperties.ttl rename to cool-rdf-cli/src/test/resources/disjoint-dataproperties.ttl diff --git a/cli/src/test/resources/disjoint-objectproperties.ttl b/cool-rdf-cli/src/test/resources/disjoint-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/disjoint-objectproperties.ttl rename to cool-rdf-cli/src/test/resources/disjoint-objectproperties.ttl diff --git a/cli/src/test/resources/disjoint-union.ttl b/cool-rdf-cli/src/test/resources/disjoint-union.ttl similarity index 100% rename from cli/src/test/resources/disjoint-union.ttl rename to cool-rdf-cli/src/test/resources/disjoint-union.ttl diff --git a/cli/src/test/resources/equivalent-classes.ttl b/cool-rdf-cli/src/test/resources/equivalent-classes.ttl similarity index 100% rename from cli/src/test/resources/equivalent-classes.ttl rename to cool-rdf-cli/src/test/resources/equivalent-classes.ttl diff --git a/cli/src/test/resources/equivalent-dataproperties.ttl b/cool-rdf-cli/src/test/resources/equivalent-dataproperties.ttl similarity index 100% rename from cli/src/test/resources/equivalent-dataproperties.ttl rename to cool-rdf-cli/src/test/resources/equivalent-dataproperties.ttl diff --git a/cli/src/test/resources/equivalent-objectproperties.ttl b/cool-rdf-cli/src/test/resources/equivalent-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/equivalent-objectproperties.ttl rename to cool-rdf-cli/src/test/resources/equivalent-objectproperties.ttl diff --git a/cli/src/test/resources/functional-dataproperty.ttl b/cool-rdf-cli/src/test/resources/functional-dataproperty.ttl similarity index 100% rename from cli/src/test/resources/functional-dataproperty.ttl rename to cool-rdf-cli/src/test/resources/functional-dataproperty.ttl diff --git a/cli/src/test/resources/functional-objectproperty.ttl b/cool-rdf-cli/src/test/resources/functional-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/functional-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/functional-objectproperty.ttl diff --git a/cli/src/test/resources/has-key.ttl b/cool-rdf-cli/src/test/resources/has-key.ttl similarity index 100% rename from cli/src/test/resources/has-key.ttl rename to cool-rdf-cli/src/test/resources/has-key.ttl diff --git a/cli/src/test/resources/inverse-functional-objectproperty.ttl b/cool-rdf-cli/src/test/resources/inverse-functional-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/inverse-functional-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/inverse-functional-objectproperty.ttl diff --git a/cli/src/test/resources/inverse-objectproperties.ttl b/cool-rdf-cli/src/test/resources/inverse-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/inverse-objectproperties.ttl rename to cool-rdf-cli/src/test/resources/inverse-objectproperties.ttl diff --git a/cli/src/test/resources/irreflexive-objectproperty.ttl b/cool-rdf-cli/src/test/resources/irreflexive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/irreflexive-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/irreflexive-objectproperty.ttl diff --git a/cli/src/test/resources/negative-dataproperty-assertion.ttl b/cool-rdf-cli/src/test/resources/negative-dataproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/negative-dataproperty-assertion.ttl rename to cool-rdf-cli/src/test/resources/negative-dataproperty-assertion.ttl diff --git a/cli/src/test/resources/negative-objectproperty-assertion.ttl b/cool-rdf-cli/src/test/resources/negative-objectproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/negative-objectproperty-assertion.ttl rename to cool-rdf-cli/src/test/resources/negative-objectproperty-assertion.ttl diff --git a/cli/src/test/resources/object-complement.ttl b/cool-rdf-cli/src/test/resources/object-complement.ttl similarity index 100% rename from cli/src/test/resources/object-complement.ttl rename to cool-rdf-cli/src/test/resources/object-complement.ttl diff --git a/cli/src/test/resources/object-intersection.ttl b/cool-rdf-cli/src/test/resources/object-intersection.ttl similarity index 100% rename from cli/src/test/resources/object-intersection.ttl rename to cool-rdf-cli/src/test/resources/object-intersection.ttl diff --git a/cli/src/test/resources/object-oneof.ttl b/cool-rdf-cli/src/test/resources/object-oneof.ttl similarity index 100% rename from cli/src/test/resources/object-oneof.ttl rename to cool-rdf-cli/src/test/resources/object-oneof.ttl diff --git a/cli/src/test/resources/object-union.ttl b/cool-rdf-cli/src/test/resources/object-union.ttl similarity index 100% rename from cli/src/test/resources/object-union.ttl rename to cool-rdf-cli/src/test/resources/object-union.ttl diff --git a/cli/src/test/resources/objectproperty-assertion.ttl b/cool-rdf-cli/src/test/resources/objectproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-assertion.ttl rename to cool-rdf-cli/src/test/resources/objectproperty-assertion.ttl diff --git a/cli/src/test/resources/objectproperty-domain.ttl b/cool-rdf-cli/src/test/resources/objectproperty-domain.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-domain.ttl rename to cool-rdf-cli/src/test/resources/objectproperty-domain.ttl diff --git a/cli/src/test/resources/objectproperty-range.ttl b/cool-rdf-cli/src/test/resources/objectproperty-range.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-range.ttl rename to cool-rdf-cli/src/test/resources/objectproperty-range.ttl diff --git a/cli/src/test/resources/property-chain.ttl b/cool-rdf-cli/src/test/resources/property-chain.ttl similarity index 100% rename from cli/src/test/resources/property-chain.ttl rename to cool-rdf-cli/src/test/resources/property-chain.ttl diff --git a/cli/src/test/resources/reflexive-objectproperty.ttl b/cool-rdf-cli/src/test/resources/reflexive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/reflexive-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/reflexive-objectproperty.ttl diff --git a/cli/src/test/resources/restriction-allvaluesfrom.ttl b/cool-rdf-cli/src/test/resources/restriction-allvaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-allvaluesfrom.ttl rename to cool-rdf-cli/src/test/resources/restriction-allvaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-data-allvaluesfrom.ttl b/cool-rdf-cli/src/test/resources/restriction-data-allvaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-allvaluesfrom.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-allvaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-data-exact-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-data-exact-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-exact-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-exact-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-hasvalue.ttl b/cool-rdf-cli/src/test/resources/restriction-data-hasvalue.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-hasvalue.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-hasvalue.ttl diff --git a/cli/src/test/resources/restriction-data-max-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-data-max-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-max-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-max-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-min-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-data-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-min-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-somevaluesfrom.ttl b/cool-rdf-cli/src/test/resources/restriction-data-somevaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-somevaluesfrom.ttl rename to cool-rdf-cli/src/test/resources/restriction-data-somevaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-has-self.ttl b/cool-rdf-cli/src/test/resources/restriction-has-self.ttl similarity index 100% rename from cli/src/test/resources/restriction-has-self.ttl rename to cool-rdf-cli/src/test/resources/restriction-has-self.ttl diff --git a/cli/src/test/resources/restriction-object-exact-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-object-exact-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-exact-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-object-exact-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-hasvalue.ttl b/cool-rdf-cli/src/test/resources/restriction-object-hasvalue.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-hasvalue.ttl rename to cool-rdf-cli/src/test/resources/restriction-object-hasvalue.ttl diff --git a/cli/src/test/resources/restriction-object-max-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-object-max-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-max-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-object-max-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl b/cool-rdf-cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl rename to cool-rdf-cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-somevaluesfrom.ttl b/cool-rdf-cli/src/test/resources/restriction-somevaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-somevaluesfrom.ttl rename to cool-rdf-cli/src/test/resources/restriction-somevaluesfrom.ttl diff --git a/cli/src/test/resources/same-individuals.ttl b/cool-rdf-cli/src/test/resources/same-individuals.ttl similarity index 100% rename from cli/src/test/resources/same-individuals.ttl rename to cool-rdf-cli/src/test/resources/same-individuals.ttl diff --git a/cli/src/test/resources/subannotationproperty.ttl b/cool-rdf-cli/src/test/resources/subannotationproperty.ttl similarity index 100% rename from cli/src/test/resources/subannotationproperty.ttl rename to cool-rdf-cli/src/test/resources/subannotationproperty.ttl diff --git a/cli/src/test/resources/subclass.ttl b/cool-rdf-cli/src/test/resources/subclass.ttl similarity index 100% rename from cli/src/test/resources/subclass.ttl rename to cool-rdf-cli/src/test/resources/subclass.ttl diff --git a/cli/src/test/resources/subdataproperty.ttl b/cool-rdf-cli/src/test/resources/subdataproperty.ttl similarity index 100% rename from cli/src/test/resources/subdataproperty.ttl rename to cool-rdf-cli/src/test/resources/subdataproperty.ttl diff --git a/cli/src/test/resources/subobjectproperty.ttl b/cool-rdf-cli/src/test/resources/subobjectproperty.ttl similarity index 100% rename from cli/src/test/resources/subobjectproperty.ttl rename to cool-rdf-cli/src/test/resources/subobjectproperty.ttl diff --git a/cli/src/test/resources/swrl-rule-builtin-atom.ttl b/cool-rdf-cli/src/test/resources/swrl-rule-builtin-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-builtin-atom.ttl rename to cool-rdf-cli/src/test/resources/swrl-rule-builtin-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl b/cool-rdf-cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl rename to cool-rdf-cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl diff --git a/cli/src/test/resources/swrl-rule-class-atom.ttl b/cool-rdf-cli/src/test/resources/swrl-rule-class-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-class-atom.ttl rename to cool-rdf-cli/src/test/resources/swrl-rule-class-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-data-range-atom.ttl b/cool-rdf-cli/src/test/resources/swrl-rule-data-range-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-data-range-atom.ttl rename to cool-rdf-cli/src/test/resources/swrl-rule-data-range-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-object-property-atom.ttl b/cool-rdf-cli/src/test/resources/swrl-rule-object-property-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-object-property-atom.ttl rename to cool-rdf-cli/src/test/resources/swrl-rule-object-property-atom.ttl diff --git a/cli/src/test/resources/symmetric-objectproperty.ttl b/cool-rdf-cli/src/test/resources/symmetric-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/symmetric-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/symmetric-objectproperty.ttl diff --git a/cli/src/test/resources/transitive-objectproperty.ttl b/cool-rdf-cli/src/test/resources/transitive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/transitive-objectproperty.ttl rename to cool-rdf-cli/src/test/resources/transitive-objectproperty.ttl diff --git a/cool-rdf-core/pom.xml b/cool-rdf-core/pom.xml new file mode 100644 index 00000000..575e2d78 --- /dev/null +++ b/cool-rdf-core/pom.xml @@ -0,0 +1,220 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-core + Cool RDF Core + + + ${project.basedir}/src-gen/main/resources/git.properties + ${project.basedir}/src-gen + ${project.basedir}/src-buildtime + + + + + + org.apache.jena + jena-arq + + + + + org.projectlombok + lombok + compile + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-src-gen-source + initialize + + add-source + + + + ${generated.sources}/main/java + + + + + add-src-gen-resource + initialize + + add-resource + + + + + ${generated.sources}/main/resources + + + + + + add-src-buildtime-source + initialize + + add-source + + + + ${build.time.sources}/main/java + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ${generated.sources} + + + + + + + io.github.git-commit-id + git-commit-id-maven-plugin + + + get-the-git-infos + generate-sources + + revision + + + + + ${project.basedir}/../.git + true + ${git-properties-filename} + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile-build-time-code + process-sources + + compile + + + ${build.time.sources},${basedir}/src + + + + + + + org.codehaus.gmaven + groovy-maven-plugin + + + determine-project-developers + initialize + + execute + + + + + + def developers = project.developers.collect { it.name }.join(', ') + project.properties.setProperty('developersString', developers) + + + + + + org.codehaus.mojo + exec-maven-plugin + + + generate-version-class + generate-resources + + java + + + cool.rdf.core.buildtime.WriteVersionClass + + + + + + ${git-properties-filename} + cool.rdf.core.Version + ${generated.sources}/main/java/cool/rdf/core/Version.java + + ${developersString} + + + + + generate-prefixes-class + generate-resources + + java + + + cool.rdf.core.buildtime.WritePrefixesClass + + + + + + ${build.time.sources}/main/resources + cool.rdf.core.Prefixes + ${generated.sources}/main/java/cool/rdf/core/Prefixes.java + + ${developersString} + + + + + + + + + + diff --git a/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/DateFormats.java b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/DateFormats.java new file mode 100644 index 00000000..46139f50 --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/DateFormats.java @@ -0,0 +1,31 @@ +/* + * Copyright 2025 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.buildtime; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * Date format constants for build time code generation. + */ +public class DateFormats { + public static final DateFormat ISO_8601_FORMAT = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSX" ); + + public static final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd" ); + + public static final DateFormat YEAR_FORMAT = new SimpleDateFormat( "yyyy" ); +} diff --git a/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WritePrefixesClass.java b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WritePrefixesClass.java new file mode 100644 index 00000000..a6708289 --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WritePrefixesClass.java @@ -0,0 +1,164 @@ +/* + * Copyright 2025 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.buildtime; + +import cool.rdf.core.util.StringTemplate; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * This class is executed at build time and will write the Java file containing static RDF prefix information. + */ +public class WritePrefixesClass { + private static final StringTemplate PREFIXES_CLASS_TEMPLATE = new StringTemplate( """ + /* + * Copyright ${year} ${copyrightHolder} + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package ${package}; + + import javax.annotation.processing.Generated; + + import cool.rdf.core.model.RdfPrefix; + + /** + * Provides information about well-known RDF prefixes and namespaces. + * Generated class, do not edit. + */ + @Generated( value = "${generatorClass}", date = "${isoBuildDate}" ) + public enum ${className} implements RdfPrefix { + ${entries}; + + private final String prefix; + private final String uri; + + ${className}( final String uri ) { + this.prefix = null; + this.uri = uri; + } + + ${className}( final String prefix, final String uri ) { + this.prefix = prefix; + this.uri = uri; + } + + @Override + public String prefix() { + return this.prefix == null + ? this.toString().toLowerCase() + : this.prefix; + } + + @Override + public String uri() { + return uri; + } + } + """ ); + + private record PrefixEntry( String enumName, String prefix, String uri ) { + } + + /** + * args[0]: the path to resources directory containing prefix definitions + * args[1]: fully qualified class name to generate + * args[2]: the path to the file to write + * args[3]: name of the copyright holder + * + * @param args the arguments + */ + public static void main( final String[] args ) { + final Path resourcesDirectory = Path.of( args[0] ); + final String fullyQualifiedClassName = args[1]; + final String copyrightHolder = args[3]; + final int lastDot = fullyQualifiedClassName.lastIndexOf( "." ); + final String packageName = fullyQualifiedClassName.substring( 0, lastDot ); + final String className = fullyQualifiedClassName.substring( lastDot + 1 ); + + final List prefixes = Stream.of( + entriesFromFile( resourcesDirectory.resolve( "prefix.cc.txt" ), entry -> + new PrefixEntry( entry[0].toUpperCase(), entry[0], entry[1] ) ), + entriesFromFile( resourcesDirectory.resolve( "other-prefixes.txt" ), entry -> + new PrefixEntry( entry[0], entry[1], entry[2] ) ) ) + .flatMap( Function.identity() ) + .toList(); + + final File targetFile = new File( args[2] ); + targetFile.getParentFile().mkdirs(); + + final String entries = prefixes.stream().sorted( Comparator.comparing( PrefixEntry::enumName ) ).map( entry -> + entry.enumName().toLowerCase().equals( entry.prefix() ) + ? " %s( \"%s\" )".formatted( entry.enumName(), entry.uri() ) + : " %s( \"%s\", \"%s\" )".formatted( entry.enumName(), entry.prefix(), entry.uri() ) ) + .collect( Collectors.joining( ",\n" ) ); + + final Date currentDate = new Date(); + final String content = PREFIXES_CLASS_TEMPLATE.apply( Map.of( + "generatorClass", WritePrefixesClass.class.getCanonicalName(), + "year", DateFormats.YEAR_FORMAT.format( currentDate ), + "buildDate", DateFormats.SIMPLE_DATE_FORMAT.format( currentDate ), + "isoBuildDate", DateFormats.ISO_8601_FORMAT.format( currentDate ), + "copyrightHolder", copyrightHolder, + "package", packageName, + "className", className, + "entries", entries + ) ); + + try { + final BufferedWriter writer = new BufferedWriter( new FileWriter( targetFile ) ); + writer.write( content ); + writer.close(); + } catch ( final IOException exception ) { + throw new RuntimeException( exception ); + } + } + + private static Stream entriesFromFile( final Path prefixFile, final Function lineParser ) { + try { + return Files.readAllLines( prefixFile ).stream().map( line -> lineParser.apply( line.split( "\t" ) ) ); + } catch ( final IOException | NullPointerException exception ) { + exception.printStackTrace(); + System.err.println( "Could not open " + prefixFile ); + System.exit( 1 ); + return null; + } + } +} diff --git a/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WriteVersionClass.java b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WriteVersionClass.java new file mode 100644 index 00000000..185f77ab --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/java/cool/rdf/core/buildtime/WriteVersionClass.java @@ -0,0 +1,130 @@ +/* + * Copyright 2025 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.buildtime; + +import cool.rdf.core.util.StringTemplate; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Map; +import java.util.Properties; + +/** + * This class is executed at build time and will write the Java file containing static build version information. + */ +public class WriteVersionClass { + private static final StringTemplate VERSION_CLASS_TEMPLATE = new StringTemplate( """ + /* + * Copyright ${year} ${copyrightHolder} + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package ${package}; + + import javax.annotation.processing.Generated; + + /** + * Provides static build version information. + * Generated class, do not edit. + */ + @Generated( value = "${generatorClass}", date = "${isoBuildDate}" ) + public class ${className} { + /** + * The version of the package + */ + public static final String VERSION = "${version}"; + + /** + * The commit id of the package + */ + public static final String COMMIT_ID = "${commitId}"; + + /** + * The build date + */ + public static final String BUILD_DATE = "${buildDate}"; + } + """ ); + + /** + * args[0]: the path to git.properties + * args[1]: fully qualified class name to generate + * args[2]: the path to the file to write + * args[3]: name of the copyright holder + * + * @param args the arguments + */ + public static void main( final String[] args ) { + final String gitPropertiesFile = args[0]; + final String fullyQualifiedClassName = args[1]; + final String copyrightHolder = args[3]; + final int lastDot = fullyQualifiedClassName.lastIndexOf( "." ); + final String packageName = fullyQualifiedClassName.substring( 0, lastDot ); + final String className = fullyQualifiedClassName.substring( lastDot + 1 ); + + final Properties gitProperties; + try ( final InputStream gitPropertiesInputStream = new FileInputStream( gitPropertiesFile ) ) { + gitProperties = new Properties(); + gitProperties.load( gitPropertiesInputStream ); + } catch ( final IOException exception ) { + System.err.println( "Could not open git.properties" ); + System.exit( 1 ); + return; + } + + final File targetFile = new File( args[2] ); + targetFile.getParentFile().mkdirs(); + + final Date currentDate = new Date(); + + final String content = VERSION_CLASS_TEMPLATE.apply( Map.of( + "generatorClass", WriteVersionClass.class.getCanonicalName(), + "year", DateFormats.YEAR_FORMAT.format( currentDate ), + "copyrightHolder", copyrightHolder, + "package", packageName, + "className", className, + "version", gitProperties.getProperty( "git.build.version" ), + "commitId", gitProperties.getProperty( "git.commit.id" ), + "buildDate", DateFormats.SIMPLE_DATE_FORMAT.format( currentDate ), + "isoBuildDate", DateFormats.ISO_8601_FORMAT.format( currentDate ) + ) ); + + try { + final BufferedWriter writer = new BufferedWriter( new FileWriter( targetFile ) ); + writer.write( content ); + writer.close(); + } catch ( final IOException exception ) { + throw new RuntimeException( exception ); + } + } +} diff --git a/cool-rdf-core/src-buildtime/main/resources/README.md b/cool-rdf-core/src-buildtime/main/resources/README.md new file mode 100644 index 00000000..dce9b589 --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/resources/README.md @@ -0,0 +1 @@ +Source of the file prefix.cc.txt is http://prefix.cc/popular/all.file.txt \ No newline at end of file diff --git a/cool-rdf-core/src-buildtime/main/resources/other-prefixes.txt b/cool-rdf-core/src-buildtime/main/resources/other-prefixes.txt new file mode 100644 index 00000000..72c7e397 --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/resources/other-prefixes.txt @@ -0,0 +1,4 @@ +SAMM_2_1_0 samm urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0# +SAMM_C_2_1_0 samm-c urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0# +SAMM_E_2_1_0 samm-e urn:samm:org.eclipse.esmf.samm:entity:2.1.0# +SAMM_UNIT_2_1_0 unit urn:samm:org.eclipse.esmf.samm:unit:2.1.0# diff --git a/cool-rdf-core/src-buildtime/main/resources/prefix.cc.txt b/cool-rdf-core/src-buildtime/main/resources/prefix.cc.txt new file mode 100644 index 00000000..a7f36359 --- /dev/null +++ b/cool-rdf-core/src-buildtime/main/resources/prefix.cc.txt @@ -0,0 +1,3152 @@ +madsrdf http://www.loc.gov/mads/rdf/v1# +bflc http://id.loc.gov/ontologies/bflc/ +foaf http://xmlns.com/foaf/0.1/ +rdf http://www.w3.org/1999/02/22-rdf-syntax-ns# +dbo http://dbpedia.org/ontology/ +rdfs http://www.w3.org/2000/01/rdf-schema# +yago http://yago-knowledge.org/resource/ +dc http://purl.org/dc/elements/1.1/ +dbp http://dbpedia.org/property/ +owl http://www.w3.org/2002/07/owl# +ex http://example.org/ +gr http://purl.org/goodrelations/v1# +skos http://www.w3.org/2004/02/skos/core# +spacerel http://data.ordnancesurvey.co.uk/ontology/spatialrelations/ +geo http://www.opengis.net/ont/geosparql# +xsd http://www.w3.org/2001/XMLSchema# +dcat http://www.w3.org/ns/dcat# +org http://www.w3.org/ns/org# +dct http://purl.org/dc/terms/ +qb http://purl.org/linked-data/cube# +dcterms http://purl.org/dc/terms/ +prov http://www.w3.org/ns/prov# +sioc http://rdfs.org/sioc/ns# +xtypes http://purl.org/xtypes/ +schema http://schema.org/ +dbpedia http://dbpedia.org/resource/ +ont http://purl.org/net/ns/ontology-annot# +void http://rdfs.org/ns/void# +onto http://www.ontotext.com/ +sio http://semanticscience.org/resource/ +bf http://id.loc.gov/ontologies/bibframe/ +search http://sindice.com/vocab/search# +sd http://www.w3.org/ns/sparql-service-description# +obo http://purl.obolibrary.org/obo/ +dcterm http://purl.org/dc/terms/ +frbr http://purl.org/vocab/frbr/core# +stat http://www.w3.org/ns/posix/stat# +vcard http://www.w3.org/2006/vcard/ns# +commerce http://search.yahoo.com/searchmonkey/commerce/ +bibo http://purl.org/ontology/bibo/ +rss http://purl.org/rss/1.0/ +dbr http://dbpedia.org/resource/ +gldp http://www.w3.org/ns/people# +pto http://www.productontology.org/id/ +geonames http://www.geonames.org/ontology# +fb http://rdf.freebase.com/ns/ +event http://purl.org/NET/c4dm/event.owl# +wd http://www.wikidata.org/entity/ +oo http://purl.org/openorg/ +dcmit http://purl.org/dc/dcmitype/ +content http://purl.org/rss/1.0/modules/content/ +cc http://creativecommons.org/ns# +gen http://purl.org/gen/0.1# +doap http://usefulinc.com/ns/doap# +http http://www.w3.org/2011/http# +dbpprop http://dbpedia.org/property/ +vann http://purl.org/vocab/vann/ +rr http://www.w3.org/ns/r2rml# +swrc http://swrc.ontoware.org/ontology# +drugbank http://www4.wiwiss.fu-berlin.de/drugbank/resource/drugbank/ +md http://www.w3.org/ns/md# +sc http://purl.org/science/owl/sciencecommons/ +nie http://www.semanticdesktop.org/ontologies/2007/01/19/nie# +prog http://purl.org/prog/ +wot http://xmlns.com/wot/0.1/ +ma http://www.w3.org/ns/ma-ont# +akt http://www.aktors.org/ontology/portal# +fn http://www.w3.org/2005/xpath-functions# +cv http://rdfs.org/resume-rdf/ +aiiso http://purl.org/vocab/aiiso/schema# +tl http://purl.org/NET/c4dm/timeline.owl# +swc http://data.semanticweb.org/ns/swc/ontology# +ov http://open.vocab.org/terms/ +as https://www.w3.org/ns/activitystreams# +crm http://www.cidoc-crm.org/cidoc-crm/ +ical http://www.w3.org/2002/12/cal/ical# +daia http://purl.org/ontology/daia/ +vs http://www.w3.org/2003/06/sw-vocab-status/ns# +earl http://www.w3.org/ns/earl# +rel http://purl.org/vocab/relationship/ +xhtml http://www.w3.org/1999/xhtml# +bio http://purl.org/vocab/bio/0.1/ +rdfg http://www.w3.org/2004/03/trix/rdfg-1/ +marcrel http://id.loc.gov/vocabulary/relators/ +mo http://purl.org/ontology/mo/ +leaks https://cuzin.com/ +dv http://rdf.data-vocabulary.org/# +cs http://purl.org/vocab/changeset/schema# +ad http://schemas.talis.com/2005/address/schema# +xhv http://www.w3.org/1999/xhtml/vocab# +dc11 http://purl.org/dc/elements/1.1/ +prop http://dbpedia.org/property/ +co http://purl.org/ontology/co/core# +bill http://www.rdfabout.com/rdf/schema/usbill/ +og http://opengraphprotocol.org/schema/ +factbook http://wifo5-04.informatik.uni-mannheim.de/factbook/ns# +afn http://jena.apache.org/ARQ/function# +dbowl http://ontology.cybershare.utep.edu/dbowl/relational-to-ontology-mapping-primitive.owl# +air http://dig.csail.mit.edu/TAMI/2007/amord/air# +test2 http://this.invalid/test2# +musim http://purl.org/ontology/similarity/ +unit http://qudt.org/vocab/unit/ +log http://www.w3.org/2000/10/swap/log# +book http://purl.org/NET/book/vocab# +xs http://www.w3.org/2001/XMLSchema# +mu http://mu.semte.ch/vocabularies/core/ +ir http://www.ontologydesignpatterns.org/cp/owl/informationrealization.owl# +media http://search.yahoo.com/searchmonkey/media/ +d2rq http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1# +dcq http://purl.org/dc/qualifiers/1.0/ +xfn http://gmpg.org/xfn/11# +biblio http://purl.org/net/biblio# +tag http://www.holygoat.co.uk/owl/redwood/0.1/tags/ +reco http://purl.org/reco# +xf http://www.w3.org/2002/xforms/ +cld http://purl.org/cld/terms/ +cal http://www.w3.org/2002/12/cal/ical# +ome http://purl.org/ontomedia/core/expression# +botany http://purl.org/NET/biol/botany# +ctag http://commontag.org/ns# +dir http://schemas.talis.com/2005/dir/schema# +sism http://purl.oclc.org/NET/sism/0.1/ +admin http://webns.net/mvcb/ +xmp http://ns.adobe.com/xap/1.0/ +days http://ontologi.es/days# +dcam http://purl.org/dc/dcam/ +rif http://www.w3.org/2007/rif# +tzont http://www.w3.org/2006/timezone# +af http://purl.org/ontology/af/ +osag http://www.ordnancesurvey.co.uk/ontology/AdministrativeGeography/v2.0/AdministrativeGeography.rdf# +rev http://purl.org/stuff/rev# +qudt http://qudt.org/schema/qudt/ +time http://www.w3.org/2006/time# +sr http://www.openrdf.org/config/repository/sail# +pc http://purl.org/procurement/public-contracts# +myspace http://purl.org/ontology/myspace# +math http://www.w3.org/2000/10/swap/math# +cmp http://www.ontologydesignpatterns.org/cp/owl/componency.owl# +memo http://ontologies.smile.deri.ie/2009/02/27/memo# +ok http://okkam.org/terms# +giving http://ontologi.es/giving# +jdbc http://d2rq.org/terms/jdbc/ +lomvoc http://ltsc.ieee.org/rdf/lomv1p0/vocabulary# +swanq http://purl.org/swan/1.2/qualifiers/ +dcn http://www.w3.org/2007/uwa/context/deliverycontext.owl# +sdmx http://purl.org/linked-data/sdmx# +cfp http://sw.deri.org/2005/08/conf/cfp.owl# +swande http://purl.org/swan/1.2/discourse-elements/ +omn http://open-multinet.info/ontology/omn# +owlim http://www.ontotext.com/trree/owlim# +cyc http://sw.opencyc.org/concept/ +gn http://www.geonames.org/ontology# +con http://www.w3.org/2000/10/swap/pim/contact# +lyou http://purl.org/linkingyou/ +skosxl http://www.w3.org/2008/05/skos-xl# +oa http://www.w3.org/ns/oa# +openlinks http://www.openlinksw.com/schemas/virtrdf# +cdm http://publications.europa.eu/ontology/cdm# +sdmxdim http://purl.org/linked-data/sdmx/2009/dimension# +adms http://www.w3.org/ns/adms# +type https://webiomed.ai/blog/obzor-rossiiskikh-sistem-podderzhki-priniatiia-vrachebnykh-reshenii/ +ontology http://dbpedia.org/ontology/ +om http://opendata.caceres.es/def/ontomunicipio# +nif http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core# +photoshop http://ns.adobe.com/photoshop/1.0/ +db http://dbpedia.org/ +wfs http://schemas.opengis.net/wfs/ +lemon http://lemon-model.net/lemon# +exif http://www.w3.org/2003/12/exif/ns# +gvp http://vocab.getty.edu/ontology# +ac http://umbel.org/umbel/ac/ +isbd http://iflastandards.info/ns/isbd/elements/ +sdmxa http://purl.org/linked-data/sdmx/2009/attribute# +xsi http://www.w3.org/2001/XMLSchema-instance# +aat http://vocab.getty.edu/aat/ +fabio http://purl.org/spar/fabio/ +cert http://www.w3.org/ns/auth/cert# +sh http://www.w3.org/ns/shacl# +dul http://www.ontologydesignpatterns.org/ont/dul/DUL.owl# +prism http://prismstandard.org/namespaces/basic/2.0/ +wdt http://www.wikidata.org/prop/direct/ +swrl http://www.w3.org/2003/11/swrl# +test https://test4.example.com/ +eat http://www.eat.rl.ac.uk/# +cnt http://www.w3.org/2011/content# +tgn http://vocab.getty.edu/tgn/ +ulan http://vocab.getty.edu/ulan/ +edm http://www.europeana.eu/schemas/edm/ +sf http://www.opengis.net/ont/sf# +ore http://www.openarchives.org/ore/terms/ +swrcfe http://www.morelab.deusto.es/ontologies/swrcfe# +gtfs http://vocab.gtfs.org/terms# +voaf http://purl.org/vocommons/voaf# +uniprot http://purl.uniprot.org/uniprot/ +swrlb http://www.w3.org/2003/11/swrlb# +core http://vivoweb.org/ontology/core# +eg http://www.example.org/ +nfo http://www.semanticdesktop.org/ontologies/2007/03/22/nfo# +room http://vocab.deri.ie/rooms# +ssn http://www.w3.org/ns/ssn/ +dbc http://dbpedia.org/resource/Category: +go http://purl.obolibrary.org/obo/GO_ +scovo http://purl.org/NET/scovo# +lv http://purl.org/lobid/lv# +ceo https://linkeddata.cultureelerfgoed.nl/def/ceo# +music http://musicontology.com/ +dbprop http://dbpedia.org/property/ +bif http://www.openlinksw.com/schemas/bif# +ldp http://www.w3.org/ns/ldp# +sioct http://rdfs.org/sioc/types# +movie http://data.linkedmdb.org/resource/movie/ +xml http://www.w3.org/XML/1998/namespace/ +fise http://fise.iks-project.eu/ontology/ +wikidata http://www.wikidata.org/entity/ +siocserv http://rdfs.org/sioc/services# +lexinfo http://www.lexinfo.net/ontology/3.0/lexinfo# +geoes http://geo.linkeddata.es/ontology/ +itsrdf http://www.w3.org/2005/11/its/rdf# +ro http://purl.org/wf4ever/ro# +am http://vocab.deri.ie/am# +ping https://namso-gen.com/ +coref http://www.rkbexplorer.com/ontologies/coref# +gndo http://d-nb.info/standards/elementset/gnd# +pat http://purl.org/hpi/patchr# +ptr http://www.w3.org/2009/pointers# +cco http://www.ontologyrepository.com/CommonCoreOntologies/ +nmo http://www.semanticdesktop.org/ontologies/2007/03/22/nmo# +mods http://www.loc.gov/mods/v3# +dblp http://dblp.uni-trier.de/rdf/schema-2015-01-26# +loc http://purl.org/ontomedia/core/space# +nao http://www.semanticdesktop.org/ontologies/2007/08/15/nao# +acc http://purl.org/NET/acc# +gnd http://d-nb.info/gnd/ +pmlj http://inference-web.org/2.0/pml-justification.owl# +nsogi http://prefix.cc/nsogi: +dce http://purl.org/dc/elements/1.1/ +chebi http://purl.obolibrary.org/obo/CHEBI_ +wp http://vocabularies.wikipathways.org/wp# +product http://purl.org/commerce/product# +whois http://www.kanzaki.com/ns/whois# +bd http://www.bigdata.com/rdf# +imm http://schemas.microsoft.com/imm/ +doc http://www.w3.org/2000/10/swap/pim/doc# +sparql http://www.w3.org/ns/sparql# +gold http://purl.org/linguistics/gold/ +up http://purl.uniprot.org/core/ +cerif http://spi-fm.uca.es/neologism/cerif# +leak http://data.ontotext.com/resource/leak/ +rec http://purl.org/ontology/rec/core# +gd http://rdf.data-vocabulary.org/# +georss http://www.georss.org/georss/ +list http://www.w3.org/2000/10/swap/list# +sdo https://schema.org/ +java http://www.w3.org/2007/uwa/context/java.owl# +sec https://w3id.org/security# +meta https://krr.triply.cc/krr/sameas-meta/def/ +rsa http://www.w3.org/ns/auth/rsa# +space http://purl.org/net/schemas/space/ +ti http://www.ontologydesignpatterns.org/cp/owl/timeinterval.owl# +example http://www.example.org/rdf# +opm https://w3id.org/opm# +xlink https://es.scribd.com/doc/79794476/05-Ejercicios-Resueltos-Caja-Negra-y-Recapitulacion/ +lgd http://linkedgeodata.org/triplify/ +akts http://www.aktors.org/ontology/support# +cube https://cube.link/ +geosparql http://www.opengis.net/ont/geosparql# +ms http://purl.org/obo/owl/MS# +bp http://www.biopax.org/release/biopax-level3.owl# +acl http://www.w3.org/ns/auth/acl# +wiki http://en.wikipedia.org/wiki/ +iot http://iotschema.org/ +penn http://purl.org/olia/penn.owl# +geof http://www.opengis.net/def/function/geosparql/ +mf http://www.w3.org/2001/sw/DataAccess/tests/test-manifest# +hg http://rdf.histograph.io/ +video http://purl.org/ontology/video# +pext http://www.ontotext.com/proton/protonext# +cito http://purl.org/spar/cito/ +rdfsharp https://rdfsharp.codeplex.com/ +st http://ns.inria.fr/sparql-template/ +cro http://rhizomik.net/ontologies/copyrightonto.owl# +sim http://www.w3id.org/simulation/ontology/ +httph http://www.w3.org/2007/ont/httph# +vivo http://vivoweb.org/ontology/core# +kb http://deductions.sf.net/ontology/knowledge_base.owl# +api http://purl.org/linked-data/api/vocab# +dbpediaowl http://dbpedia.org/owl/ +sp http://spinrdf.org/sp# +nt http://ns.inria.fr/nicetag/2010/09/09/voc# +wn http://xmlns.com/wordnet/1.6/ +nco http://www.semanticdesktop.org/ontologies/2007/03/22/nco# +acm http://www.rkbexplorer.com/ontologies/acm# +xl http://langegger.at/xlwrap/vocab# +pim http://www.w3.org/ns/pim/space# +exterms http://www.example.org/terms/ +web http://www.w3.org/2007/uwa/context/web.owl# +dcatapit http://dati.gov.it/onto/dcatapit# +atom http://www.w3.org/2005/Atom/ +wgs http://www.w3.org/2003/01/geo/wgs84_pos# +bag https://bag2.basisregistraties.overheid.nl/bag/def/ +cgov http://reference.data.gov.uk/def/central-government/ +olia http://purl.org/olia/olia.owl# +po http://purl.org/ontology/po/ +lode http://linkedevents.org/ontology/ +sider http://www4.wiwiss.fu-berlin.de/sider/resource/sider/ +overheid http://standaarden.overheid.nl/owms/ +urn http://fliqz.com/ +ocd http://dati.camera.it/ocd/ +postcode http://data.ordnancesurvey.co.uk/id/postcodeunit/ +abc http://www.metadata.net/harmony/ABCSchemaV5Commented.rdf# +pgterms http://www.gutenberg.org/2009/pgterms/ +cidoc http://www.cidoc-crm.org/cidoc-crm/ +dbnary http://kaiko.getalp.org/dbnary# +pav http://purl.org/pav/ +wdrs http://www.w3.org/2007/05/powder-s# +formats http://www.w3.org/ns/formats/ +dco http://info.deepcarbon.net/schema# +sirext http://t.me/sirextt/247: +zoology http://purl.org/NET/biol/zoology# +service http://purl.org/ontology/service# +eu http://eulersharp.sourceforge.net/2003/03swap/log-rules# +dbkwik http://dbkwik.webdatacommons.org/ +seas https://w3id.org/seas/ +ean http://openean.kaufkauf.net/id/ +cpa http://www.ontologydesignpatterns.org/schemas/cpannotationschema.owl# +ass http://uptheasset.org/ontology# +admingeo http://data.ordnancesurvey.co.uk/ontology/admingeo/ +ecs http://rdf.ecs.soton.ac.uk/ontology/ecs# +purl http://www.purl.org/ +wn20schema http://www.w3.org/2006/03/wn/wn20/schema/ +smf http://topbraid.org/sparqlmotionfunctions# +prv http://purl.org/net/provenance/ns# +rdfdf http://www.openlinksw.com/virtrdf-data-formats# +daml http://www.daml.org/2001/03/daml+oil# +lime http://www.w3.org/ns/lemon/lime# +ontolex http://www.w3.org/ns/lemon/ontolex# +dcm http://purl.org/dc/dcmitype/ +gsp http://www.opengis.net/ont/geosparql# +swid http://semanticweb.org/id/ +edam http://edamontology.org/ +ya http://blogs.yandex.ru/schema/foaf/ +pr http://purl.org/ontology/prv/core# +role https://w3id.org/role/ +irw http://www.ontologydesignpatterns.org/ont/web/irw.owl# +resource http://dbpedia.org/resource/ +hydra http://www.w3.org/ns/hydra/core# +greg http://kasei.us/about/foaf.xrdf# +name http://example.org/name# +ignf http://data.ign.fr/def/ignf# +spin http://spinrdf.org/spin# +omt http://purl.org/ontomedia/ext/common/trait# +user http://schemas.talis.com/2005/user/schema# +ndl http://schemas.ogf.org/nml/2013/05/base# +wo http://purl.org/ontology/wo/ +pmt http://tipsy.googlecode.com/svn/trunk/vocab/pmt# +scot http://rdfs.org/scot/ns# +xkos http://rdf-vocabulary.ddialliance.org/xkos# +myspo http://purl.org/ontology/myspace# +umbelrc http://umbel.org/umbel/rc/ +organism http://eulersharp.sourceforge.net/2003/03swap/organism# +agg http://purl.org/twc/health/vocab/aggregate/ +site http://ns.ontowiki.net/SysOnt/Site/ +wikipedia https://en.wikipedia.org/wiki/ +res http://dbpedia.org/resource/ +euvoc http://publications.europa.eu/ontology/euvoc# +sdl http://purl.org/vocab/riro/sdl# +bmo http://collection.britishmuseum.org/id/ontology/ +sesame http://www.openrdf.org/schema/sesame# +faldo http://biohackathon.org/resource/faldo# +inno http://purl.org/innovation/ns# +blt http://www.bl.uk/schemas/bibliographic/blterms# +resist http://www.rkbexplorer.com/ontologies/resist# +label http://purl.org/net/vocab/2004/03/label# +npg http://ns.nature.com/terms/ +fresnel http://www.w3.org/2004/09/fresnel# +iao http://purl.obolibrary.org/obo/IAO_ +prj http://purl.org/stuff/project/ +omb http://purl.org/ontomedia/ext/common/being# +bing http://bing.com/schema/media/ +rov http://www.w3.org/ns/regorg# +biol http://purl.org/NET/biol/ns# +saref https://saref.etsi.org/core/ +link http://www.w3.org/2007/ont/link# +bibframe http://id.loc.gov/ontologies/bibframe/ +premis http://www.loc.gov/premis/rdf/v3/ +audio http://purl.org/media/audio# +won https://w3id.org/won/core# +sit http://www.ontologydesignpatterns.org/cp/owl/situation.owl# +tmo http://www.semanticdesktop.org/ontologies/2008/05/20/tmo# +iso http://purl.org/iso25964/skos-thes# +biocore http://bio2rdf.org/core# +fed http://www.openrdf.org/config/sail/federation# +uco http://purl.org/uco/ns# +mm http://linkedmultimedia.org/sparql-mm/ns/2.0.0/function# +swp http://www.w3.org/2004/03/trix/swp-2/ +food http://purl.org/foodontology# +phil http://philosurfical.open.ac.uk/ontology/philosurfical.owl# +cordis http://cordis.europa.eu/projects/ +wgs84 http://www.w3.org/2003/01/geo/wgs84_pos# +umbel http://umbel.org/umbel# +wv http://vocab.org/waiver/terms/ +rdau http://rdaregistry.info/Elements/u/ +ref http://purl.org/vocab/relationship/ +spl http://spinrdf.org/spl# +lx http://purl.org/NET/lx# +conv http://purl.org/twc/vocab/conversion/ +oad http://lod.xdams.org/reload/oad/ +acco http://purl.org/acco/ns# +es http://eulersharp.sourceforge.net/2003/03swap/log-rules# +sco http://purl.org/ontology/sco# +code http://telegraphis.net/ontology/measurement/code# +ps https://w3id.org/payswarm# +sml https://w3id.org/sml/def# +rnews http://iptc.org/std/rNews/2011-10-07# +ub http://www.lehigh.edu/~zhp2/2004/0401/univ-bench.owl# +lgdo http://linkedgeodata.org/ontology/ +oc http://opencoinage.org/rdf/ +protege http://protege.stanford.edu/system# +ero http://purl.obolibrary.org/obo/ +doac http://ramonantonio.net/doac/0.1/# +opensearch http://a9.com/-/spec/opensearch/1.1/ +rail http://ontologi.es/rail/vocab# +taxo http://purl.org/rss/1.0/modules/taxonomy/ +cpm http://catalogus-professorum.org/cpm/2/ +ludo http://ns.inria.fr/ludo/v1# +airport http://www.daml.org/2001/10/html/airport-ont# +gist https://ontologies.semanticarts.com/o/gistCore/ +bio2rdf http://bio2rdf.org/ +efo http://www.ebi.ac.uk/efo/ +dctype http://purl.org/dc/dcmitype/ +meteo http://purl.org/ns/meteo# +granatum http://chem.deri.ie/granatum/ +linkedmdb http://data.linkedmdb.org/ +so http://schema.org/ +spc http://purl.org/ontomedia/core/space# +bne http://datos.bne.es/resource/ +dwc http://rs.tdwg.org/dwc/terms/ +awol http://bblfish.net/work/atom-owl/2006-06-06/# +lom http://ltsc.ieee.org/rdf/lomv1p0/lom# +disco http://rdf-vocabulary.ddialliance.org/discovery# +act http://www.w3.org/2007/rif-builtin-action# +omp http://purl.org/ontomedia/ext/common/profession# +gpt http://purl.org/vocab/riro/gpt# +isothes http://purl.org/iso25964/skos-thes# +net http://www.w3.org/2007/uwa/context/network.owl# +mit http://purl.org/ontology/mo/mit# +lu http://www.ontologydesignpatterns.org/ont/framenet/abox/lu/ +ao http://purl.org/ontology/ao/core# +powder http://www.w3.org/2007/05/powder# +taxon http://purl.org/biodiversity/taxon/ +xhe http://buzzword.org.uk/rdf/xhtml-elements# +sport http://purl.org/ontology/sport/ +frir http://purl.org/twc/ontology/frir.owl# +bibtex http://purl.org/net/nknouf/ns/bibtex# +hp http://purl.org/voc/hp/ +gso http://www.w3.org/2006/gen/ont# +omm http://purl.org/ontomedia/core/media# +asn http://purl.org/ASN/schema/core/ +atomix http://buzzword.org.uk/rdf/atomix# +tdb http://jena.hpl.hp.com/2008/tdb# +fec http://www.rdfabout.com/rdf/schema/usfec/ +wordnet http://wordnet-rdf.princeton.edu/ontology# +compass http://purl.org/net/compass# +library http://purl.org/library/ +pbo http://purl.org/ontology/pbo/core# +rep http://www.openrdf.org/config/repository# +obj http://www.openrdf.org/rdf/2009/object# +doclist http://www.junkwork.net/xml/DocumentList# +orges http://datos.gob.es/def/sector-publico/organizacion# +os http://www.w3.org/2000/10/swap/os# +lfm http://purl.org/ontology/last-fm/ +rdrel http://rdvocab.info/RDARelationshipsWEMI/ +crypto http://www.w3.org/2000/10/swap/crypto# +oauth http://demiblog.org/vocab/oauth# +rei http://www.w3.org/2004/06/rei# +lang http://ontologi.es/lang/core# +fbgeo http://rdf.freebase.com/ns/location/geocode/ +mime https://www.iana.org/assignments/media-types/ +ddc http://purl.org/NET/decimalised# +vra http://purl.org/vra/ +muto http://purl.org/muto/core# +money http://purl.org/net/rdf-money/ +affy http://www.affymetrix.com/community/publications/affymetrix/tmsplice# +pom http://maven.apache.org/POM/4.0.0# +cheminf http://www.semanticweb.org/ontologies/cheminf.owl# +ire http://www.ontologydesignpatterns.org/cpont/ire.owl# +txn http://lod.taxonconcept.org/ontology/txn.owl# +custom http://www.openrdf.org/config/sail/custom# +game http://data.totl.net/game/ +ngeo http://geovocab.org/geometry# +contact http://www.w3.org/2000/10/swap/pim/contact# +soft http://www.w3.org/2007/uwa/context/software.owl# +conversion http://purl.org/twc/vocab/conversion/ +hard http://www.w3.org/2007/uwa/context/hardware.owl# +dailymed http://www4.wiwiss.fu-berlin.de/dailymed/resource/dailymed/ +lfn http://www.dotnetrdf.org/leviathan# +xen http://buzzword.org.uk/rdf/xen# +swh http://plugin.org.uk/swh-plugins/ +politico http://www.rdfabout.com/rdf/schema/politico/ +string http://www.w3.org/2000/10/swap/string# +bib http://zeitkunst.org/bibtex/0.1/bibtex.owl# +nrl http://www.semanticdesktop.org/ontologies/2007/08/15/nrl# +vocab http://rdf.ontology2.com/vocab# +climb http://climb.dataincubator.org/vocabs/climb/ +usgov http://www.rdfabout.com/rdf/schema/usgovt/ +ct http://data.linkedct.org/resource/linkedct/ +sede http://eventography.org/sede/0.1/ +omc http://purl.org/ontomedia/ext/common/bestiary# +vsr http://purl.org/twc/vocab/vsr# +eco http://www.ebusiness-unibw.org/ontologies/eclass/5.1.4/# +interval http://reference.data.gov.uk/def/intervals/ +cycann http://sw.cyc.com/CycAnnotations_v1# +soc http://purl.org/net/hdlipcores/ontology/soc# +bbc http://www.bbc.co.uk/ontologies/news/ +locn http://www.w3.org/ns/locn# +aos http://rdf.muninn-project.org/ontologies/appearances# +apivc http://purl.org/linked-data/api/vocab# +ui http://www.w3.org/ns/ui# +aifb http://www.aifb.kit.edu/id/ +person http://www.w3.org/ns/person# +isq http://purl.org/ontology/is/quality/ +coo http://purl.org/coo/ns# +stanford http://purl.org/olia/stanford.owl# +deo http://purl.org/spar/deo/ +bfo http://purl.obolibrary.org/obo/ +scv http://purl.org/NET/scovo# +bsb http://opacplus.bsb-muenchen.de/title/ +dnr http://www.dotnetrdf.org/configuration# +biopax http://www.biopax.org/release/biopax-level3.owl# +rdac http://rdaregistry.info/Elements/c/ +coin http://purl.org/court/def/2009/coin# +eli http://data.europa.eu/eli/ontology# +is http://purl.org/ontology/is/core# +mysql http://web-semantics.org/ns/mysql/ +chord http://purl.org/ontology/chord/ +sv http://schemas.talis.com/2005/service/schema# +pro http://purl.org/hpi/patchr# +lvont http://lexvo.org/ontology# +com http://purl.org/commerce# +cex http://purl.org/weso/ontology/computex# +xro http://purl.org/xro/ns# +vso http://purl.org/vso/ns# +arch http://purl.org/archival/vocab/arch# +arg http://rdfs.org/sioc/argument# +gob http://purl.org/ontology/last-fm/ +zem http://s.zemanta.com/ns# +ic http://imi.go.jp/ns/core/rdf# +push http://www.w3.org/2007/uwa/context/push.owl# +isi http://purl.org/ontology/is/inst/ +xds http://www.w3.org/2001/XMLSchema# +yoda http://purl.org/NET/yoda# +states http://www.w3.org/2005/07/aaa# +pdo http://ontologies.smile.deri.ie/pdo# +rs http://rightsstatements.org/vocab/ +courseware http://courseware.rkbexplorer.com/ontologies/courseware# +gml http://www.opengis.net/ont/gml# +worldbank http://worldbank.270a.info/dataset/ +uri http://purl.org/NET/uri# +ttl http://www.w3.org/2008/turtle# +dso http://purl.org/ontology/dso# +dbpp http://dbpedia.org/property/ +moat http://moat-project.org/ns# +prot http://www.proteinontology.info/po.owl# +muo http://purl.oclc.org/NET/muo/muo# +cpv http://purl.org/weso/cpv/ +conserv http://conserv.deri.ie/ontology# +dady http://purl.org/NET/dady# +pmlr http://inference-web.org/2.0/pml-relation.owl# +dt http://w3id.org/dt# +cogs http://vocab.deri.ie/cogs# +pos http://www.w3.org/2003/01/geo/wgs84_pos# +swanco http://purl.org/swan/1.2/swan-commons/ +city http://datos.localidata.com/def/City# +wdr http://www.w3.org/2007/05/powder# +fea http://vocab.data.gov/def/fea# +odrl http://www.w3.org/ns/odrl/2/ +ist http://purl.org/ontology/is/types/ +lex http://purl.org/lex# +freebase http://rdf.freebase.com/ns/ +profiling http://ontologi.es/profiling# +dcmitype http://purl.org/dc/dcmitype/ +resex http://resex.rkbexplorer.com/ontologies/resex# +nexif http://www.semanticdesktop.org/ontologies/2007/05/10/nexif# +payment http://reference.data.gov.uk/def/payment# +article http://ogp.me/ns/article# +xforms http://www.w3.org/2002/xforms/ +nsa http://multimedialab.elis.ugent.be/organon/ontologies/ninsuna# +address http://schemas.talis.com/2005/address/schema# +lotico http://www.lotico.com/resource/ +voag http://voag.linkedmodel.org/schema/voag# +hlisting http://sindice.com/hlisting/0.1/ +sosa http://www.w3.org/ns/sosa/ +swivt http://semantic-mediawiki.org/swivt/1.0# +opo http://online-presence.net/opo/ns# +tio http://purl.org/tio/ns# +viaf http://viaf.org/viaf/ +posh http://poshrdf.org/ns/posh/ +evset http://dsnotify.org/vocab/eventset/0.1/ +rlog http://persistence.uni-leipzig.org/nlp2rdf/ontologies/rlog# +cos http://www.inria.fr/acacia/corese# +toby http://tobyinkster.co.uk/# +vote http://www.rdfabout.com/rdf/schema/vote/ +meetup http://www.lotico.com/meetup/ +lifecycle http://purl.org/vocab/lifecycle/schema# +psys http://proton.semanticweb.org/protonsys# +puc http://purl.org/NET/puc# +bsbm http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/ +anca http://users.utcluj.ro/~raluca/rdf_ontologies_ralu/ralu_modified_ontology_pizzas2_0# +teach http://linkedscience.org/teach/ns# +sail http://www.openrdf.org/config/sail# +datafaqs http://purl.org/twc/vocab/datafaqs# +common http://www.w3.org/2007/uwa/context/common.owl# +pay http://reference.data.gov.uk/def/payment# +ldap http://purl.org/net/ldap/ +lp http://launchpad.net/rdf/launchpad# +p3p http://www.w3.org/2002/01/p3prdfv1# +lingvoj http://www.lingvoj.org/ontology# +rooms http://vocab.deri.ie/rooms# +sysont http://ns.ontowiki.net/SysOnt/ +rdfa http://www.w3.org/ns/rdfa# +wlp http://weblab-project.org/core/model/property/processing/ +tags http://www.holygoat.co.uk/owl/redwood/0.1/tags/ +like http://ontologi.es/like# +rda http://www.rdaregistry.info/ +swanqs http://purl.org/swan/1.2/qualifiers/ +eclap http://www.eclap.eu/schema/eclap/ +ddl http://purl.org/vocab/riro/ddl# +fab http://purl.org/fab/ns# +wi http://purl.org/ontology/wi/core# +ann http://www.w3.org/2000/10/annotation-ns# +nuts http://dd.eionet.europa.eu/vocabulary/common/nuts/ +dcr http://www.isocat.org/ns/dcr.rdf# +sem http://semanticweb.cs.vu.nl/2009/11/sem/ +bte http://purl.org/twc/vocab/between-the-edges/ +enc http://www.w3.org/2001/04/xmlenc# +psych http://purl.org/vocab/psychometric-profile/ +oboinowl http://www.geneontology.org/formats/oboInOwl# +wai http://purl.org/wai# +wnschema http://www.cogsci.princeton.edu/~wn/schema/ +pobo http://purl.obolibrary.org/obo/ +eztag http://ontologies.ezweb.morfeo-project.org/eztag/ns# +kwijibo http://kwijibo.talis.com/ +care http://eulersharp.sourceforge.net/2003/03swap/care# +br http://vocab.deri.ie/br# +algo http://securitytoolbox.appspot.com/securityAlgorithms# +drug http://www.agfa.com/w3c/2009/drugTherapy# +cdt https://w3id.org/cdt/ +vitro http://vitro.mannlib.cornell.edu/ns/vitro/public# +prissma http://ns.inria.fr/prissma/v1# +play http://uriplay.org/spec/ontology/# +oslc http://open-services.net/ns/core# +oboe http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl# +irrl http://www.ontologydesignpatterns.org/cp/owl/informationobjectsandrepresentationlanguages.owl# +lastfm http://purl.org/ontology/last-fm/ +mygrid http://www.mygrid.org.uk/ontology# +mei http://www.music-encoding.org/ns/mei/ +bridge http://purl.org/vocommons/bridge# +fo http://www.w3.org/1999/XSL/Format# +grddl http://www.w3.org/2003/g/data-view# +sl http://www.semanlink.net/2001/00/semanlink-schema# +oat http://openlinksw.com/schemas/oat/ +esd http://def.esd.org.uk/ +pol http://escience.rpi.edu/ontology/semanteco/2/0/pollution.owl# +h5 http://buzzword.org.uk/rdf/h5# +fls http://lukasblaho.sk/football_league_schema# +r2rml http://www.w3.org/ns/r2rml# +ogp http://ogp.me/ns# +cmo http://purl.org/twc/ontologies/cmo.owl# +b2bo http://purl.org/b2bo# +olo http://purl.org/ontology/olo/core# +iswc http://annotation.semanticweb.org/2004/iswc# +phss http://ns.poundhill.com/phss/1.0/ +wordmap http://purl.org/net/ns/wordmap# +tarot http://data.totl.net/tarot/card/ +sm http://topbraid.org/sparqlmotion# +hospital http://www.agfa.com/w3c/2009/hospital# +uni http://purl.org/weso/uni/uni.html# +remus http://www.semanticweb.org/ontologies/2010/6/Ontology1279614123500.owl# +swandr http://purl.org/swan/1.2/discourse-relationships/ +osn http://spatial.ucd.ie/lod/osn/ +smiley http://www.smileyontology.com/ns# +ezcontext http://ontologies.ezweb.morfeo-project.org/ezcontext/ns# +calli http://callimachusproject.org/rdf/2009/framework# +hcterms http://purl.org/uF/hCard/terms/ +lt http://diplomski.nelakolundzija.org/LTontology.rdf# +ne http://umbel.org/umbel/ne/ +geom http://data.ign.fr/def/geometrie# +ibis http://purl.org/ibis# +human http://eulersharp.sourceforge.net/2003/03swap/human# +sioca http://rdfs.org/sioc/actions# +places http://purl.org/ontology/places# +rulz http://purl.org/NET/rulz# +httpvoc http://www.w3.org/2006/http# +countries http://eulersharp.sourceforge.net/2003/03swap/countries# +pimo http://www.semanticdesktop.org/ontologies/2007/11/01/pimo# +recipe http://linkedrecipes.org/schema/ +cdc https://w3id.org/cdc# +rdagr1 http://rdvocab.info/Elements/ +status http://www.w3.org/2003/06/sw-vocab-status/ns# +np http://www.nanopub.org/nschema# +data http://data.odw.tw/ +omv http://omv.ontoware.org/2005/05/ontology# +aapi http://rdf.alchemyapi.com/rdf/v1/s/aapi-schema# +session http://redfoot.net/2005/session# +icaltzd http://www.w3.org/2002/12/cal/icaltzd# +ppo http://vocab.deri.ie/ppo# +tr http://www.thomsonreuters.com/ +card http://www.ashutosh.com/test/ +san http://www.irit.fr/recherches/MELODI/ontologies/SAN# +webtlab http://webtlab.it.uc3m.es/ +dnb http://d-nb.info/gnd/ +sql http://ns.inria.fr/ast/sql# +okkam http://models.okkam.org/ENS-core-vocabulary# +oac https://w3id.org/oac# +rdaa http://rdaregistry.info/Elements/a/ +osoc http://web-semantics.org/ns/opensocial# +reve http://data.eurecom.fr/ontology/reve# +wbc http://worldbank.270a.info/classification/ +cao http://purl.org/makolab/caont/ +wfm http://purl.org/net/wf-motifs# +arpfo http://vocab.ouls.ox.ac.uk/projectfunding# +geospecies http://rdf.geospecies.org/ont/geospecies# +csvw http://www.w3.org/ns/csvw# +wgspos http://www.w3.org/2003/01/geo/wgs84_pos# +dbt http://dbpedia.org/resource/Template: +ebucore http://www.ebu.ch/metadata/ontologies/ebucore/ebucore# +units http://eulersharp.sourceforge.net/2003/03swap/units# +pml http://provenanceweb.org/ns/pml# +zbwext http://zbw.eu/namespaces/zbw-extensions/ +esdir http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/direccion-postal# +xmls http://www.w3.org/2001/XMLSchema# +wisski http://wiss-ki.eu/ +derecho http://purl.org/derecho# +ple http://pleiades.stoa.org/places/ +elog http://eulersharp.sourceforge.net/2003/03swap/log-rules# +agents http://eulersharp.sourceforge.net/2003/03swap/agent# +wsc http://www.openk.org/wscaim.owl# +infosys http://www.infosys.com/ +opwn http://www.ontologyportal.org/WordNet.owl# +agent http://eulersharp.sourceforge.net/2003/03swap/agent# +wl http://www.wsmo.org/ns/wsmo-lite# +span http://www.ifomis.org/bfo/1.1/span# +prf http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212# +geofla http://data.ign.fr/ontologies/geofla# +scsv http://purl.org/NET/schema-org-csv# +gridworks http://purl.org/net/opmv/types/gridworks# +imreg http://www.w3.org/2004/02/image-regions# +geographis http://telegraphis.net/ontology/geography/geography# +cb http://cbasewrap.ontologycentral.com/vocab# +pmlt http://inference-web.org/2.0/pml-trust.owl# +pccz http://purl.org/procurement/public-contracts-czech# +agro http://purl.obolibrary.org/obo/agro.owl# +wbp http://worldbank.270a.info/property/ +marl http://www.gsi.dit.upm.es/ontologies/marl/ns# +dita http://purl.org/dita/ns# +pmlp http://inference-web.org/2.0/pml-provenance.owl# +rdo http://purl.org/rdo/ns# +qdoslf http://foaf.qdos.com/lastfm/schema/ +osgb http://data.ordnancesurvey.co.uk/id/ +kontakt http://richard.cyganiak.de/ +qa http://www.mit.jyu.fi/ai/TRUST_Ontologies/QA.owl# +ncal http://www.semanticdesktop.org/ontologies/2007/04/02/ncal# +plink http://buzzword.org.uk/rdf/personal-link-types# +html http://www.w3.org/1999/xhtml/ +opus http://lsdis.cs.uga.edu/projects/semdis/opus# +provenir http://knoesis.wright.edu/provenir/provenir.owl# +c4n http://vocab.deri.ie/c4n# +shv http://ns.aksw.org/spatialHierarchy/ +sindice http://vocab.sindice.net/ +mp http://jicamaro.info/mp# +open http://open.vocab.org/terms/ +dsp http://purl.org/metainfo/terms/dsp# +prefix http://prefix.cc/ +r2r http://www4.wiwiss.fu-berlin.de/bizer/r2r/ +dis http://stanbol.apache.org/ontology/disambiguation/disambiguation# +nid3 http://www.semanticdesktop.org/ontologies/2007/05/10/nid3# +timeline http://purl.org/NET/c4dm/timeline.owl# +organiz http://eulersharp.sourceforge.net/2003/03swap/organization# +visit http://purl.org/net/vocab/2004/07/visit# +pns http://data.press.net/ontology/stuff/ +dummy http://hello.com/ +muni http://vocab.linkeddata.es/urbanismo-infraestructuras/territorio# +hxl http://hxl.humanitarianresponse.info/ns/# +swanpav http://purl.org/swan/1.2/pav/ +life http://life.deri.ie/schema/ +wairole http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy# +dgtwc http://data-gov.tw.rpi.edu/2009/data-gov-twc.rdf# +prvtypes http://purl.org/net/provenance/types# +req http://purl.org/req/ +agetec http://www.agetec.org/ +frbre http://purl.org/vocab/frbr/extended# +aair http://xmlns.notu.be/aair# +lr http://linkedrecipes.org/schema/ +hemogram http://www.agfa.com/w3c/2009/hemogram# +gv http://rdf.data-vocabulary.org/# +osr http://dati.senato.it/osr/ +ncbitaxon http://purl.org/obo/owl/NCBITaxon# +ens http://models.okkam.org/ENS-core-vocabulary.owl# +set http://www.w3.org/2000/10/swap/set# +odp http://ontologydesignpatterns.org/ +aims http://aims.fao.org/aos/common/ +copyright http://rhizomik.net/ontologies/copyrightonto.owl# +out http://ontologies.hypios.com/out# +vaem http://www.linkedmodel.org/schema/vaem# +nex http://www.nexml.org/2009/ +xsl http://www.w3.org/1999/XSL/Transform# +visko http://trust.utep.edu/visko/ontology/visko-operator-v3.owl# +ecb http://ecb.270a.info/class/1.0/ +xt http://purl.org/twc/vocab/cross-topix# +un http://www.w3.org/2007/ont/unit# +xhtmlvocab http://www.w3.org/1999/xhtml/vocab/ +lark1 http://users.utcluj.ro/~raluca/ontology/Ontology1279614123500.owl# +meb http://rdf.myexperiment.org/ontologies/base/ +tripfs http://purl.org/tripfs/2010/02# +fowl http://www.w3.org/TR/2003/PR-owl-guide-20031209/food# +pubmed http://bio2rdf.org/pubmed_vocabulary: +parl https://id.parliament.uk/schema/ +eprints http://eprints.org/ontology/ +trackback http://madskills.com/public/xml/rss/module/trackback/ +geodata http://sws.geonames.org/ +wao http://webtlab.it.uc3m.es/2010/10/WebAppsOntology# +pna http://data.press.net/ontology/asset/ +carfo http://purl.org/carfo# +rdapo http://rdaregistry.info/Elements/p/object/ +skip http://skipforward.net/skipforward/resource/ +swanci http://purl.org/swan/1.2/citations/ +spatial http://geovocab.org/spatial# +grel http://users.ugent.be/~bjdmeest/function/grel.ttl# +aneo http://akonadi-project.org/ontologies/aneo# +eye http://jena.hpl.hp.com/Eyeball# +wapp http://ns.rww.io/wapp# +admssw http://purl.org/adms/sw/ +archdesc http://archdesc.info/archEvent# +emotion http://ns.inria.fr/emoca# +sdm https://w3id.org/okn/o/sdm# +emp http://purl.org/ctic/empleo/oferta# +fl http://eulersharp.sourceforge.net/2003/03swap/fl-rules# +oper http://sweet.jpl.nasa.gov/2.0/mathOperation.owl# +ops https://w3id.org/ops# +rdam http://rdaregistry.info/Elements/m/ +ospost http://data.ordnancesurvey.co.uk/ontology/postcode/ +kdo http://kdo.render-project.eu/kdo# +fd http://foodable.co/ns/ +metalex http://www.metalex.eu/schema/1.0# +xesam http://freedesktop.org/standards/xesam/1.0/core# +commons http://commons.psi.enakting.org/def/ +gelo http://krauthammerlab.med.yale.edu/ontologies/gelo# +doco http://purl.org/spar/doco/ +dayta http://dayta.me/resource# +prolog http://eulersharp.sourceforge.net/2003/03swap/prolog# +pne http://data.press.net/ontology/event/ +hgnc http://bio2rdf.org/hgnc: +evopat http://ns.aksw.org/Evolution/ +languages http://eulersharp.sourceforge.net/2003/03swap/languages# +sawsdl http://www.w3.org/ns/sawsdl# +nsl http://purl.org/ontology/storyline/ +rv https://data.elsevier.com/research/schema/rv/ +atomowl http://bblfish.net/work/atom-owl/2006-06-06/# +dtype http://www.linkedmodel.org/schema/dtype# +ipad http://www.padinthecity.com/ +fno https://w3id.org/function/ontology# +re http://www.w3.org/2000/10/swap/reason# +ccom http://purl.org/ontology/cco/mappings# +pam http://prismstandard.org/namespaces/pam/2.0/ +dive http://scubadive.networld.to/dive.rdf# +bioskos http://eulersharp.sourceforge.net/2003/03swap/bioSKOSSchemes# +xfnv http://vocab.sindice.com/xfn# +sdgp http://stats.data-gov.ie/property/ +semtweet http://semantictweet.com/ +tcga http://purl.org/tcga/core# +soap http://www.w3.org/2003/05/soap-envelope/ +rad http://www.w3.org/ns/rad# +sig http://purl.org/signature# +aigp http://swat.cse.lehigh.edu/resources/onto/aigp.owl# +comm http://vocab.resc.info/communication# +oj http://ontojob.at/ +tei http://www.tei-c.org/ns/1.0/ +gc http://www.oegov.org/core/owl/gc# +func http://www.w3.org/2007/rif-builtin-function# +dgfoaf http://west.uni-koblenz.de/ontologies/2010/07/dgfoaf.owl# +oboro http://obofoundry.org/ro/ro.owl# +ecpo http://purl.org/ontology/ecpo# +orca http://geni-orca.renci.org/owl/topology.owl# +decl http://www.linkedmodel.org/1.0/schema/decl# +dssn http://purl.org/net/dssn/ +agrelon http://d-nb.info/standards/elementset/agrelon# +fc http://www.freeclass.eu/freeclass_v1# +linkedct http://data.linkedct.org/vocab/ +nndsr http://semanticdiet.com/schema/usda/nndsr/ +opmv http://purl.org/net/opmv/ns# +psh http://ns.inria.fr/probabilistic-shacl/ +frame http://www.ontologydesignpatterns.org/ont/framenet/abox/frame/ +geop http://aims.fao.org/aos/geopolitical.owl# +quak http://dev.w3.org/cvsweb/2000/quacken/vocab# +tvc http://www.essepuntato.it/2012/04/tvc/ +igeo http://rdf.insee.fr/def/geo# +coeus http://bioinformatics.ua.pt/coeus/ +fcm http://eulersharp.sourceforge.net/2006/02swap/fcm# +bookmark http://www.w3.org/2002/01/bookmark# +theatre http://purl.org/theatre# +xch http://oanda2rdf.appspot.com/xch/ +swpo http://sw-portal.deri.org/ontologies/swportal# +oboso http://purl.org/obo/owl/SO# +nxp http://purl.org/nxp/schema/v1/ +aersv http://aers.data2semantics.org/vocab/ +rso http://www.researchspace.org/ontology/ +spif http://spinrdf.org/spif# +sad http://vocab.deri.ie/sad# +enhancer http://stanbol.apache.org/ontology/enhancer/enhancer# +tripfs2 http://purl.org/tripfs/2010/06# +nyt http://data.nytimes.com/ +eseduc http://www.purl.org/ontologia/eseduc# +xbrli http://www.xbrl.org/2003/instance# +gxa http://www.ebi.ac.uk/gxa/ +ling http://purl.org/voc/ling/ +iron http://purl.org/ontology/iron# +dbpo http://dbpedia.org/ontology/ +mte http://nl.ijs.si/ME/owl/ +protons http://proton.semanticweb.org/2005/04/protons# +tp https://triplydb.com/Triply/tp/def/ +cidoccrm http://purl.org/NET/cidoc-crm/core# +transit http://vocab.org/transit/terms/ +httpm http://www.w3.org/2011/http-methods# +rlno http://rdflivenews.aksw.org/ontology/ +prvr http://purl.org/ontology/prv/rules# +events http://eulersharp.sourceforge.net/2003/03swap/event# +td https://www.w3.org/2019/wot/td# +w3p http://prov4j.org/w3p/ +dl http://ontology.ip.rm.cnr.it/ontologies/DOLCE-Lite# +rich http://rdf.data-vocabulary.org/ +qu http://purl.oclc.org/NET/ssnx/qu/qu# +c4o http://purl.org/spar/c4o/ +gazetteer http://data.ordnancesurvey.co.uk/ontology/50kGazetteer/ +htir http://www.w3.org/2011/http# +no http://km.aifb.kit.edu/projects/numbers/number# +myprefix http://myprefix.org/ +telix http://purl.org/telix# +frapo http://purl.org/cerif/frapo/ +scowt http://purl.org/weso/ontologies/scowt# +estrn http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/transporte# +oax http://www.w3.org/ns/openannotation/extensions/ +json https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf# +fct http://openlinksw.com/services/facets/1.0/ +coun http://www.daml.org/2001/09/countries/iso-3166-ont# +ecc https://ns.eccenca.com/ +moby http://www.mygrid.org.uk/mygrid-moby-service# +rpubl http://rinfo.lagrummet.se/ns/2008/11/rinfo/publ# +sgv http://www.w3.org/TR/SVG/ +kw http://kwantu.net/kw/ +frad http://iflastandards.info/ns/fr/frad/ +humanbody http://eulersharp.sourceforge.net/2003/03swap/humanBody# +govtrackus http://www.rdfabout.com/rdf/usgov/geo/us/ +arecipe http://purl.org/amicroformat/arecipe/ +tmpl http://purl.org/restdesc/http-template# +artstor http://simile.mit.edu/2003/10/ontologies/artstor# +jita http://aims.fao.org/aos/jita/ +owls http://www.daml.org/services/owl-s/1.2/Service.owl# +rdaw http://rdaregistry.info/Elements/w/ +gbv http://purl.org/ontology/gbv/ +fingal http://vocab.deri.ie/fingal# +wf http://www.w3.org/2005/01/wf/flow# +lgv http://linkedgeodata.org/ontology/ +mesh http://id.nlm.nih.gov/mesh/ +wm http://ns.inria.fr/webmarks# +oecd http://oecd.270a.info/dataset/ +swanag http://purl.org/swan/1.2/agents/ +pf http://jena.hpl.hp.com/ARQ/property# +ec http://eulergui.sourceforge.net/contacts.owl.n3# +ccard http://purl.org/commerce/creditcard# +bm http://bio2rdf.org/ +clineva http://www.agfa.com/w3c/2009/clinicalEvaluation# +ru http://purl.org/imbi/ru-meta.owl# +goef http://purl.org/twc/vocab/goef# +owltime http://www.w3.org/TR/owl-time# +grs http://www.georss.org/georss/ +intervals http://reference.data.gov.uk/def/intervals/ +flow http://www.w3.org/2005/01/wf/flow# +ext http://mu.semte.ch/vocabularies/ext/ +vcardx http://buzzword.org.uk/rdf/vcardx# +ends http://labs.mondeca.com/vocab/endpointStatus# +rating http://www.tvblob.com/ratings/# +luc http://www.ontotext.com/owlim/lucene# +fe http://www.ontologydesignpatterns.org/ont/framenet/abox/fe/ +genab http://eulersharp.sourceforge.net/2003/03swap/genomeAbnormality# +d2r http://sites.wiwiss.fu-berlin.de/suhl/bizer/d2r-server/config.rdf# +osp http://data.lirmm.fr/ontologies/osp# +abs http://abs.270a.info/dataset/ +health http://purl.org/twc/health/vocab/ +identity http://purl.org/twc/ontologies/identity.owl# +nytimes http://data.nytimes.com/elements/ +lod2 http://lod2.eu/schema/ +italy http://data.kasabi.com/dataset/italy/schema/ +wfdesc http://purl.org/wf4ever/wfdesc# +penis http://penis.to/# +govwild http://govwild.org/0.6/GWOntology.rdf/ +osmsemnet http://spatial.ucd.ie/2012/08/osmsemnet/ +frbrcore http://purl.org/vocab/frbr/core# +dbpedia2 http://dbpedia.org/property/ +sor http://purl.org/net/soron/ +quantity http://qudt.org/schema/quantity# +ql http://www.w3.org/2004/ql# +kupkb http://www.e-lico.eu/data/kupkb/ +environ http://eulersharp.sourceforge.net/2003/03swap/environment# +crtv http://open-services.net/ns/crtv# +hcard http://purl.org/uF/hCard/terms/ +p20 http://zbw.eu/beta/p20/vocab/ +vf https://w3id.org/valueflows/ont/vf# +s4ac http://ns.inria.fr/s4ac/v2# +dossier https://data.omgeving.vlaanderen.be/ns/dossier# +ecos http://purl.org/ecos# +npgd http://ns.nature.com/datasets/ +sro http://salt.semanticauthoring.org/ontologies/sro# +daiaserv http://purl.org/ontology/daia/Service/ +transmed http://www.w3.org/2001/sw/hcls/ns/transmed/ +itsmo http://ontology.it/itsmo/v1# +loticoowl http://www.lotico.com/ontology/ +cold http://purl.org/configurationontology# +gfo http://www.onto-med.de/ontologies/gfo.owl# +idemo http://rdf.insee.fr/def/demo# +ufmedia http://purl.org/microformat/hmedia/ +genea http://www.owl-ontologies.com/generations.owl# +ogorg http://opengraph.org/schema/ +shex http://www.w3.org/ns/shex# +nocal http://vocab.deri.ie/nocal# +poder http://poderopedia.com/vocab/ +cmd https://w3id.org/cmd# +wikibase http://wikiba.se/ontology# +skiresort http://www.openlinksw.com/ski_resorts/schema# +npgg http://ns.nature.com/graphs/ +bcncon http://datos.bcn.cl/ontologies/bcn-congress# +crmdig http://www.ics.forth.gr/isl/CRMdig/ +bl https://w3id.org/biolink/vocab/ +va http://code-research.eu/ontology/visual-analytics# +cf http://mmisw.org/ont/cf/parameter/ +dpd http://www.kanzaki.com/ns/dpd# +gesis http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf# +lindt http://purl.org/NET/lindt# +hartigprov http://purl.org/net/provenance/ns# +wscaim http://www.openk.org/wscaim.owl# +cdtype http://purl.org/cld/cdtype/ +str http://nlp2rdf.lod2.eu/schema/string/ +sw http://linkedwidgets.org/statisticalwidget/ontology/ +provone http://purl.org/provone# +diseasome http://www4.wiwiss.fu-berlin.de/diseasome/resource/diseasome/ +rkd http://data.rkd.nl/def# +protegedc http://protege.stanford.edu/plugins/owl/dc/protege-dc.owl# +sci http://data.scientology.org/ns/ +steel https://w3id.org/steel/ProcessOntology/ +s2s http://escience.rpi.edu/ontology/sesf/s2s/4/0/ +cis http://purl.org/NET/cloudisus# +healthcare http://www.agfa.com/w3c/2009/healthCare# +cl http://advene.org/ns/cinelab/ +ls http://linkedspending.aksw.org/instance/ +atomrdf http://atomowl.org/ontologies/atomrdf# +stac http://securitytoolbox.appspot.com/stac# +mohammad http://manesht.ir/ +kbp http://tackbp.org/2013/ontology# +dctypes http://purl.org/dc/dcmitype/ +centrifuge http://purl.org/twc/vocab/centrifuge# +rankrage https://rankrage.de/ +saxon http://saxon.sf.net/ +skos08 http://www.w3.org/2008/05/skos# +marshall http://sites.google.com/site/xgmaitc/ +ngeoi http://vocab.lenka.no/geo-deling# +ipo http://purl.org/ipo/core# +atlas http://rdf.ebi.ac.uk/resource/atlas/ +l4a http://labels4all.info/ns/ +occult http://data.totl.net/occult/ +curr https://w3id.org/cc# +l4lod http://ns.inria.fr/l4lod/v2/ +openskos http://openskos.org/xmlns# +paia http://purl.org/ontology/paia# +mtecore http://purl.org/olia/mte/multext-east.owl# +lctr http://data.linkedct.org/vocab/resource/ +vsto http://escience.rpi.edu/ontology/vsto/2/0/vsto.owl# +foo http://filmontology.org/ontology/1.0/ +osukdt http://www.ordnancesurvey.co.uk/ontology/Datatypes.owl# +category http://dbpedia.org/resource/Category: +gs1 https://gs1.org/voc/ +solid http://www.w3.org/ns/solid/terms# +ianarel https://www.w3.org/ns/iana/link-relations/relation# +harrisons http://harrisons.cc/ +rec54 http://www.w3.org/2001/02pd/rec54.rdf# +gov http://gov.genealogy.net/ontology.owl# +clinproc http://www.agfa.com/w3c/2009/clinicalProcedure# +pizza http://www.co-ode.org/ontologies/pizza/pizza.owl# +opmw http://www.opmw.org/ontology/ +biordf http://purl.org/net/biordfmicroarray/ns# +aerols http://xmlns.com/aerols/0.1/ +daq http://purl.org/eis/vocab/daq# +campsite http://www.openlinksw.com/campsites/schema# +wfprov http://purl.org/wf4ever/wfprov# +prism21 http://prismstandard.org/namespaces/basic/2.1/ +rml http://w3id.org/rml/ +laposte http://data.lirmm.fr/ontologies/laposte# +pkmn http://pokedex.dataincubator.org/pkm/ +b2rpubchem http://bio2rdf.org/ns/ns/ns/pubchem# +mpeg7 http://rhizomik.net/ontologies/2005/03/Mpeg7-2001.owl# +dbyago http://dbpedia.org/class/yago/ +malignneo http://www.agfa.com/w3c/2009/malignantNeoplasm# +pronom http://reference.data.gov.uk/technical-registry/ +lh http://vocab.inf.ed.ac.uk/library/holdings# +hasco http://hadatac.org/ont/hasco/ +okg http://openknowledgegraph.org/ontology/ +refe http://orion.tw.rpi.edu/~xgmatwc/refe/ +opl http://openlinksw.com/schema/attribution# +odcs http://opendata.cz/infrastructure/odcleanstore/ +wno http://wordnet-rdf.princeton.edu/ontology# +camelot http://vocab.ox.ac.uk/camelot# +ldr http://purl.oclc.org/NET/ldr/ns# +bv http://purl.org/vocommons/bv# +ifc http://ifcowl.openbimstandards.org/IFC2X3_Final# +sam http://def.seegrid.csiro.au/isotc211/iso19156/2011/sampling# +c4dm http://purl.org/NET/c4dm/event.owl# +te http://www.w3.org/2006/time-entry# +dpl http://dbpedialite.org/things/ +wkd http://schema.wolterskluwer.de/ +oslo http://purl.org/oslo/ns/localgov# +verb https://w3id.org/verb/ +crv http://purl.org/twc/vocab/datacarver# +germplasm http://purl.org/germplasm/terms# +doas http://deductions.github.io/doas.owl.ttl# +mads http://www.loc.gov/mads/rdf/v1# +cart http://purl.org/net/cartCoord# +pod https://project-open-data.cio.gov/v1.1/schema/# +lc http://semweb.mmlab.be/ns/linkedconnections# +dannet http://www.wordnet.dk/owl/instance/2009/03/instances/ +odo http://ocean-data.org/schema/ +lio http://purl.org/net/lio# +date http://contextus.net/ontology/ontomedia/misc/date# +bcnnorms http://datos.bcn.cl/ontologies/bcn-norms# +geovocab http://geovocab.org/ +ekaw http://data.semanticweb.org/conference/ekaw/2012/complete/ +scms http://ns.aksw.org/scms/annotations/ +alchemy http://rdf.alchemyapi.com/rdf/v1/s/aapi-schema# +lso http://linkedspending.aksw.org/ontology/ +dqv http://www.w3.org/ns/dqv# +ds http://purl.org/ctic/dcat# +of http://owlrep.eu01.aws.af.cm/fridge# +ebu http://semantic.eurobau.com/eurobau-utility.owl# +sso http://nlp2rdf.lod2.eu/schema/sso/ +vgo http://purl.org/net/VideoGameOntology# +puelia http://kwijibo.talis.com/vocabs/puelia# +shoah http://dati.cdec.it/lod/shoah/ +prvt http://purl.org/net/provenance/types# +omnlife http://open-multinet.info/ontology/omn-lifecycle# +dawgt http://www.w3.org/2001/sw/DataAccess/tests/test-dawg# +tisc http://observedchange.com/tisc/ns# +yo http://yovisto.com/ +plo http://purl.org/net/po# +hifm http://purl.org/net/hifm/data# +tac http://ns.bergnet.org/tac/0.1/triple-access-control# +shw http://paul.staroch.name/thesis/SmartHomeWeather.owl# +pattern http://www.essepuntato.it/2008/12/pattern# +namespaces https://vg.no/ +hints2005 http://purl.org/twc/cabig/model/HINTS2005-1.owl# +dvia http://data.eurecom.fr/ontology/dvia# +bdd https://api.bloomberg.com/eap/catalogs/bbg/fields/ +daisy http://www.daisy.org/z3998/2012/vocab/ +strdf http://strdf.di.uoa.gr/ontology# +ottr http://ns.ottr.xyz/templates# +dcndl http://ndl.go.jp/dcndl/terms/ +mmo http://purl.org/momayo/mmo/ +esco http://data.europa.eu/esco/model# +insdc http://ddbj.nig.ac.jp/ontologies/sequence# +vin http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine# +rdacarrier http://rdvocab.info/termList/RDACarrierType/ +csm http://purl.org/csm/1.0# +antenne https://data.zendantennes.omgeving.vlaanderen.be/ns/zendantenne# +smg http://ns.cerise-project.nl/energy/def/cim-smartgrid# +opllic http://www.openlinksw.com/ontology/licenses# +dn http://purl.org/datanode/ns/ +part http://purl.org/vocab/participation/schema# +cts2 http://schema.omg.org/spec/CTS2/1.0/ +adr http://kg.artsdata.ca/resource/ +bn http://babelnet.org/rdf/ +iol http://www.ontologydesignpatterns.org/ont/dul/IOLite.owl# +cpsv http://purl.org/vocab/cpsv# +rssynd http://web.resource.org/rss/1.0/modules/syndication/ +latitude https://www.w3.org/2006/vcard/ns# +quantities http://eulersharp.sourceforge.net/2003/03swap/quantitiesExtension# +gastro http://www.ebsemantics.net/gastro# +chembl http://rdf.ebi.ac.uk/terms/chembl# +ssso http://purl.org/ontology/ssso# +wsl http://www.wsmo.org/ns/wsmo-lite# +sbench http://swat.cse.lehigh.edu/onto/univ-bench.owl# +dpc http://hospee.org/ontologies/dpc/ +fos http://futurios.org/fos/spec/ +bihap http://bihap.kb.gov.tr/ontology/ +clinic http://example.com/clinic# +art http://w3id.org/art/terms/1.0/ +rmo http://eatld.et.tu-dresden.de/rmo# +turismo http://idi.fundacionctic.org/cruzar/turismo# +rdae http://rdaregistry.info/Elements/e/ +goog http://schema.googleapis.com/ +rdamt http://rdaregistry.info/termList/RDAMediaType/ +wro http://purl.org/net/wf4ever/ro# +ptop http://www.ontotext.com/proton/protontop# +ccrel http://creativecommons.org/ns# +semio http://www.lingvoj.org/semio# +trait http://contextus.net/ontology/ontomedia/ext/common/trait# +cpant http://purl.org/NET/cpan-uri/terms# +qrl http://www.aifb.kit.edu/project/ld-retriever/qrl# +sioctypes http://rdfs.org/sioc/types# +scor http://purl.org/eis/vocab/scor# +oan http://data.lirmm.fr/ontologies/oan/ +bk http://www.provbook.org/ns/# +mico http://www.mico-project.eu/ns/platform/1.0/schema# +decision https://decision-ontology.googlecode.com/svn/trunk/decision.owl# +webbox http://webbox.ecs.soton.ac.uk/ns# +guo http://purl.org/hpi/guo# +property http://fr.dbpedia.org/property/ +ep http://eprints.org/ontology/ +stream http://dbpedia.org/ontology/Stream/ +cosmo http://purl.org/ontology/cosmo# +who http://www.who.int/vocab/ontology# +emtr http://purl.org/NET/ssnext/electricmeters# +ost http://w3id.org/ost/ns# +obsm http://rdf.geospecies.org/methods/observationMethod# +gf http://def.seegrid.csiro.au/isotc211/iso19109/2005/feature# +omapi http://purl.org/omapi/0.2/# +xlime http://xlime-project.org/vocab/ +place http://purl.org/ontology/places/ +fma http://sig.uw.edu/fma# +pso http://purl.org/spar/pso/ +conf http://richard.cyganiak.de/2007/pubby/config.rdf# +thors http://resource.geosciml.org/ontology/timescale/thors# +lldr http://purl.oclc.org/NET/lldr/ns# +zoomaterms http://rdf.ebi.ac.uk/vocabulary/zooma/ +onc http://www.ics.forth.gr/isl/oncm/core# +kai http://kai.uni-kiel.de/ +opencyc http://sw.opencyc.org/concept/ +op http://environment.data.gov.au/def/op# +rdarel2 http://metadataregistry.org/uri/schema/RDARelationshipsGR2/ +shacl http://www.w3.org/ns/shacl# +bgcat http://bg.dbpedia.org/resource/Категория: +my http://www.mobile.com/model/ +rdamedia http://rdvocab.info/termList/RDAMediaType/ +oarj http://opendepot.org/reference/linked/1.0/ +ecrm http://erlangen-crm.org/current/ +mmd http://musicbrainz.org/ns/mmd-1.0# +ljkl http://teste.com/ +cvbase http://purl.org/captsolo/resume-rdf/0.2/base# +wikterms http://wiktionary.dbpedia.org/terms/ +ses http://lod.taxonconcept.org/ses/ +vsso http://automotive.eurecom.fr/vsso# +msr http://www.telegraphis.net/ontology/measurement/measurement# +spt http://spitfire-project.eu/ontology/ns/ +mged http://mged.sourceforge.net/ontologies/MGEDOntology.owl# +tblcard http://www.w3.org/People/Berners-Lee/card# +rdafnm http://rdaregistry.info/termList/FormNoteMus/ +security http://securitytoolbox.appspot.com/securityMain# +moac http://observedchange.com/moac/ns# +sao http://salt.semanticauthoring.org/ontologies/sao# +poste http://data.lirmm.fr/ontologies/poste# +eumida http://data.kasabi.com/dataset/eumida/terms/ +dr http://purl.org/swan/2.0/discourse-relationships/ +faq http://www.openlinksw.com/ontology/faq# +bgn http://bibliograph.net/schemas/ +telmap http://purl.org/telmap/ +aers http://aers.data2semantics.org/resource/ +lodac http://lod.ac/ns/lodac# +w3con http://www.w3.org/2000/10/swap/pim/contact# +icane http://www.icane.es/opendata/vocab# +bcnbio http://datos.bcn.cl/ontologies/bcn-biographies# +rdafr http://rdaregistry.info/termList/frequency/ +qud http://qudt.org/1.1/schema/qudt# +dqm http://purl.org/dqm-vocabulary/v1/dqm# +sdmxd http://purl.org/linked-data/sdmx/2009/dimension# +wlo http://purl.org/ontology/wo/ +jpo http://rdf.jpostdb.org/ontology/jpost.owl# +seq http://www.ontologydesignpatterns.org/cp/owl/sequence.owl# +mil http://rdf.muninn-project.org/ontologies/military# +scoro http://purl.org/spar/scoro/ +qvoc http://mlode.nlp2rdf.org/quranvocab# +finlaw http://purl.org/finlex/schema/laki/ +rdasoi http://rdaregistry.info/termList/statIdentification/ +disease http://www.agfa.com/w3c/2009/humanDisorder# +biro http://purl.org/spar/biro/ +rdarel http://rdvocab.info/RDARelationshipsWEMI/ +gl http://schema.geolink.org/ +twaapi http://purl.org/twc/vocab/aapi-schema# +kbv https://id.kb.se/vocab/ +mv http://schema.mobivoc.org/ +tw http://tw.rpi.edu/schema/ +ctorg http://purl.org/ctic/infraestructuras/organizacion# +oplcert http://www.openlinksw.com/schemas/cert# +accom http://purl.org/acco/ns# +onyx http://www.gsi.dit.upm.es/ontologies/onyx/ns# +xcql http://docs.oasis-open.org/ns/search-ws/xcql# +osspr http://data.ordnancesurvey.co.uk/ontology/spatialrelations/ +li http://def.seegrid.csiro.au/isotc211/iso19115/2003/lineage# +infor http://www.ontologydesignpatterns.org/cp/owl/informationrealization.owl# +delta http://www.w3.org/2004/delta# +nerd http://nerd.eurecom.fr/ontology# +oss http://opendata.caceres.es/def/ontosemanasanta# +holding http://purl.org/ontology/holding# +auto http://auto.schema.org/ +dcs http://ontologi.es/doap-changeset# +xapi https://w3id.org/xapi/ontology# +ll http://lodlaundromat.org/resource/ +lsc http://linkedscience.org/lsc/ns# +eui http://institutions.publicdata.eu/# +coll http://purl.org/co/ +od http://purl.org/twc/vocab/opendap# +dbcat http://dbpedia.org/resource/Category: +affymetrix http://bio2rdf.org/affymetrix_vocabulary: +rdacontent http://rdvocab.info/termList/RDAContentType/ +odrs http://schema.theodi.org/odrs# +esequip http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/equipamiento# +cbo http://comicmeta.org/cbo/ +swperson http://data.semanticweb.org/person/ +vsws http://verticalsearchworks.com/ontology/synset# +mb http://dbtune.org/musicbrainz/resource/instrument/ +gawd http://gawd.atlantides.org/terms/ +fam http://vocab.fusepool.info/fam# +raul http://vocab.deri.ie/raul# +tsioc http://rdfs.org/sioc/types# +wb http://data.worldbank.org/ +mrel http://id.loc.gov/vocabulary/relators/ +osgeom http://data.ordnancesurvey.co.uk/ontology/geometry/ +exo https://w3id.org/example# +drm http://vocab.data.gov/def/drm# +app http://jmvanel.free.fr/ontology/software_applications.n3# +call http://webofcode.org/wfn/call: +ogc http://www.opengis.net/def/ +npgx http://ns.nature.com/extensions/ +dogont http://elite.polito.it/ontologies/dogont.owl# +onssprel http://www.ordnancesurvey.co.uk/ontology/SpatialRelations/v0.2/SpatialRelations.owl# +emoca http://ns.inria.fr/emoca# +pnc http://data.press.net/ontology/classification/ +dash http://datashapes.org/dash# +lsmap http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-data.owl# +stats http://purl.org/rdfstats/stats# +dbpr http://dbpedia.org/resource/ +tao http://pubannotation.org/ontology/tao.owl# +geocontext http://www.geocontext.org/publ/2013/vocab# +esaloj http://vocab.linkeddata.es/datosabiertos/def/turismo/alojamiento# +nidm http://nidm.nidash.org/ +pnt http://data.press.net/ontology/tag/ +elec http://purl.org/ctic/sector-publico/elecciones# +lcy http://purl.org/vocab/lifecycle/schema# +llo http://lodlaundromat.org/ontology/ +mvco http://purl.oclc.org/NET/mvco.owl# +pni http://data.press.net/ontology/identifier/ +isocat http://www.isocat.org/datcat/ +pois http://purl.oclc.org/POIS/vcblr# +graffle http://purl.org/twc/vocab/vsr/graffle# +vapour http://vapour.sourceforge.net/vocab.rdf# +water http://escience.rpi.edu/ontology/semanteco/2/0/water.owl# +stories http://purl.org/ontology/stories/ +ox http://vocab.ox.ac.uk/projectfunding# +dbtont http://dbtropes.org/ont/ +bwb http://doc.metalex.eu/bwb/ontology/ +fao http://fao.270a.info/dataset/ +gadm http://gadm.geovocab.org/ontology# +wn31 http://wordnet-rdf.princeton.edu/wn31/ +xrd http://docs.oasis-open.org/ns/xri/xrd-1.0# +rdacct http://rdaregistry.info/termList/CollTitle/ +allot https://w3id.org/akn/ontology/allot# +sg http://name.scigraph.com/ontologies/core/ +viskov http://trust.utep.edu/visko/ontology/visko-view-v3.owl# +particip http://purl.org/vocab/participation/schema# +oml http://def.seegrid.csiro.au/ontology/om/om-lite# +dcite http://purl.org/spar/datacite/ +doi https://doi.org/ +bgt https://bgt.basisregistraties.overheid.nl/bgt/def/ +evident http://purl.org/net/evident# +deps http://ontologi.es/doap-deps# +odapp http://vocab.deri.ie/odapp# +snarm http://rdf.myexperiment.org/ontologies/snarm/ +kees http://linkeddata.center/kees/v1# +pingback http://purl.org/net/pingback/ +frb http://frb.270a.info/dataset/ +viso http://purl.org/viso/ +pvcs http://purl.org/twc/vocab/pvcs# +seokoeln http://rankrage.de/ +s3db http://www.s3db.org/core# +cbase http://ontologycentral.com/2010/05/cb/vocab# +mt http://www.w3.org/2001/sw/DataAccess/tests/test-manifest# +rdami http://rdaregistry.info/termList/modeIssue/ +scip http://lod.taxonconcept.org/ontology/sci_people.owl# +ramon http://rdfdata.eionet.europa.eu/ramon/ontology/ +ev http://www.w3.org/2001/xml-events/ +pic http://www.ipaw.info/ns/picaso# +saif http://wwwiti.cs.uni-magdeburg.de/~srahman/ +spfood http://kmi.open.ac.uk/projects/smartproducts/ontologies/food.owl# +oh http://semweb.mmlab.be/ns/oh# +c9d http://purl.org/twc/vocab/conversion/ +biotop http://purl.org/biotop/biotop.owl# +fincaselaw http://purl.org/finlex/schema/oikeus/ +dcoid http://dx.deepcarbon.net/ +brick https://brickschema.org/schema/Brick# +d2d http://rdfns.org/d2d/ +ostop http://www.ordnancesurvey.co.uk/ontology/Topography/v0.1/Topography.owl# +quty http://www.telegraphis.net/ontology/measurement/quantity# +voidp http://www.enakting.org/provenance/voidp/ +prviv http://purl.org/net/provenance/integrity# +rdatc http://rdaregistry.info/termList/trackConfig/ +eunis http://eunis.eea.europa.eu/rdf/species-schema.rdf# +viskoo http://trust.utep.edu/visko/ontology/visko-operator-v3.owl# +vag http://www.essepuntato.it/2013/10/vagueness/ +rdl http://data.posccaesar.org/rdl/ +fcp http://www.newmedialab.at/fcp/ +swo http://www.ebi.ac.uk/swo/ +vvo http://purl.org/vvo/ns# +w3po http://purl.org/provenance/w3p/w3po# +bner http://datos.bne.es/resource/ +rvdata http://data.rvdata.us/ +lexcz http://purl.org/lex/cz# +ncit https://ncit.nci.nih.gov/ncitbrowser/ConceptReport.jsp?dictionary=NCI_Thesaurus&ns=ncit&code= +mmf http://linkedmultimedia.org/sparql-mm/ns/1.0.0/function# +company http://intellimind.io/ns/company# +driver http://deductions.github.io/drivers.owl.ttl# +geosp http://rdf.geospecies.org/ont/geospecies# +lingvo http://www.lingvoj.org/ontology# +olad http://openlad.org/vocab# +origins http://origins.link/ +bco http://purl.obolibrary.org/obo/bco.owl# +rdagd http://rdaregistry.info/termList/gender/ +fcs http://clarin.eu/fcs/resource# +cmdm http://infra.clarin.eu/cmd/ +bgdbp http://bg.dbpedia.org/property/ +rdagw http://rdaregistry.info/termList/grooveWidth/ +lden http://www.linklion.org/lden/ +gnvc http://purl.org/gc/ +saws http://purl.org/saws/ontology# +vsw http://verticalsearchworks.com/ontology/ +tg https://triplydb.com/Triply/tg/def/ +odpart http://www.ontologydesignpatterns.org/cp/owl/participation.owl# +tis http://www.ontologydesignpatterns.org/cp/owl/timeindexedsituation.owl# +swpatho http://swpatho.ag-nbi.de/context/meta.owl# +pkm http://www.ontotext.com/proton/protonkm# +vdpp http://data.lirmm.fr/ontologies/vdpp# +agrd http://agrinepaldata.com/ +ntag http://ns.inria.fr/nicetag/2010/09/09/voc# +radion http://www.w3.org/ns/radion# +vext http://ldf.fi/void-ext# +rdai http://rdaregistry.info/Elements/i/ +waarde https://lod.milieuinfo.be/ns/waarde# +aws http://purl.oclc.org/NET/ssnx/meteo/aws# +agls http://www.agls.gov.au/agls/terms/ +rdarole http://rdvocab.info/roles/ +gpml http://vocabularies.wikipathways.org/gpml# +agr http://promsns.org/def/agr# +im http://imgpedia.dcc.uchile.cl/resource/ +lexvo http://lexvo.org/ontology# +dbptmpl http://dbpedia.org/resource/Template: +employee http://www.employee.com/data# +npdv http://sws.ifi.uio.no/vocab/npd# +ontopic http://www.ontologydesignpatterns.org/ont/dul/ontopic.owl# +rdabm http://rdaregistry.info/termList/RDABaseMaterial/ +lw http://linkedwidgets.org/ontologies/ +lsweb http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-data.owl# +frsad http://iflastandards.info/ns/fr/frsad/ +gcis http://data.globalchange.gov/gcis.owl# +ordf http://purl.org/NET/ordf/ +situ http://www.ontologydesignpatterns.org/cp/owl/situation.owl# +friends http://www.openarchives.org/OAI/2.0/friends/ +dao http://purl.org/dao# +vartrans http://www.w3.org/ns/lemon/vartrans# +fire http://tldp.org/HOWTO/XML-RPC-HOWTO/xmlrpc-howto-java.html# +vrank http://purl.org/voc/vrank# +beth http://www.google.com/ +mtlo http://www.ics.forth.gr/isl/MarineTLO/v4/marinetlo.owl# +lmm1 http://www.ontologydesignpatterns.org/ont/lmm/LMM_L1.owl# +roevo http://purl.org/wf4ever/roevo# +cwrc http://sparql.cwrc.ca/ontology/cwrc# +oplprod http://www.openlinksw.com/ontology/products# +activity https://www.w3.org/TR/activitystreams-vocabulary/ +gm http://def.seegrid.csiro.au/isotc211/iso19107/2003/geometry# +bioc http://deductions.github.io/biological-collections.owl.ttl# +bot https://w3id.org/bot# +bcngeo http://datos.bcn.cl/ontologies/bcn-geographics# +scufl2 http://ns.taverna.org.uk/2010/scufl2# +galaksiya http://ontoloji.galaksiya.com/vocab/ +vmm http://spi-fm.uca.es/spdef/models/genericTools/vmm/1.0# +orth http://purl.org/net/orth# +lpeu http://purl.org/linkedpolitics/vocabulary/eu/plenary/ +csp http://vocab.deri.ie/csp# +uis http://uis.270a.info/dataset/ +ldvm http://linked.opendata.cz/ontology/ldvm/ +wikim http://spi-fm.uca.es/spdef/models/genericTools/wikim/1.0# +salad https://w3id.org/cwl/salad# +wf4ever http://purl.org/wf4ever/wf4ever# +being http://purl.org/ontomedia/ext/common/being# +lmdb http://data.linkedmdb.org/ +mammal http://lod.taxonconcept.org/ontology/p01/Mammalia/index.owl# +opengov http://www.w3.org/opengov# +ftcontent http://www.ft.com/ontology/content/ +wfn http://webofcode.org/wfn/ +pproc http://contsem.unizar.es/def/sector-publico/pproc# +opmo http://openprovenance.org/model/opmo# +mod http://www.isibang.ac.in/ns/mod# +bbcprov http://www.bbc.co.uk/ontologies/provenance/ +oae http://www.ics.forth.gr/isl/oae/core# +bnf http://www.w3.org/2000/10/swap/grammar/bnf# +passim http://data.lirmm.fr/ontologies/passim# +ogbd http://www.ogbd.fr/2012/ontologie# +frbrer http://iflastandards.info/ns/fr/frbr/frbrer/ +d0 http://ontologydesignpatterns.org/ont/wikipedia/d0.owl# +rlnr http://rdflivenews.aksw.org/resource/ +lsd http://linkedwidgets.org/statisticaldata/ontology/ +pcdt http://purl.org/procurement/public-contracts-datatypes# +language http://id.loc.gov/vocabulary/iso639-1/ +cjr http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/callejero# +eurostat http://wifo5-04.informatik.uni-mannheim.de/eurostat/resource/eurostat/ +graves http://rdf.muninn-project.org/ontologies/graves# +tddo http://databugger.aksw.org/ns/core# +wn20 http://www.w3.org/2006/03/wn/wn20/ +limoo http://purl.org/LiMo/0.1/ +contsem http://contsem.unizar.es/def/sector-publico/contratacion# +pwo http://purl.org/spar/pwo/ +static http://vocab-ld.org/vocab/static-ld# +crml http://semweb.mmlab.be/ns/rml/condition# +ids https://w3id.org/idsa/core/ +ws http://www.w3.org/ns/pim/space# +pco http://purl.org/procurement/public-contracts# +geos http://www.telegraphis.net/ontology/geography/geography# +edgar http://edgarwrap.ontologycentral.com/vocab/edgar# +samfl http://def.seegrid.csiro.au/ontology/om/sam-lite# +asgv http://aims.fao.org/aos/agrovoc/ +lmm2 http://www.ontologydesignpatterns.org/ont/lmm/LMM_L2.owl# +dq http://def.seegrid.csiro.au/isotc211/iso19115/2003/dataquality# +locwd http://purl.org/locwd/schema# +s4envi https://w3id.org/def/saref4envi# +imf http://imf.270a.info/dataset/ +citof http://www.essepuntato.it/2013/03/cito-functions# +roterms http://purl.org/wf4ever/roterms# +bgdbr http://bg.dbpedia.org/resource/ +phdd http://rdf-vocabulary.ddialliance.org/phdd# +fog https://w3id.org/fog# +babelnet http://babelnet.org/2.0/ +lmo http://linkedmultimedia.org/sparql-mm/ns/2.0.0/ontology# +sct http://snomed.info/id/ +foam https://www.koerperfettwaage-test.de/ +qb4o http://purl.org/olap# +swpm http://spi-fm.uca.es/spdef/models/deployment/swpm/1.0# +step http://purl.org/net/step# +lsqv http://lsq.aksw.org/vocab# +r4ta http://ns.inria.fr/ratio4ta/v1# +lda http://purl.org/linked-data/api/vocab# +rdact http://rdaregistry.info/termList/RDACarrierType/ +text http://jena.apache.org/text# +olca http://www.lingvoj.org/olca# +form http://deductions-software.com/ontologies/forms.owl.ttl# +omdoc http://omdoc.org/ontology/ +amalgame http://purl.org/vocabularies/amalgame# +hto http://project-haystack.org/hto# +csv http://vocab.sindice.net/csv/ +rdafrbr http://rdvocab.info/uri/schema/FRBRentitiesRDA/ +merge http://jazz.net/ns/lqe/merge/ +hlygt http://www.holygoat.co.uk/owl/redwood/0.1/tags/ +jjd http://www.joshuajeeson.com/ +mds http://doc.metalex.eu/id/ +trig http://www.w3.org/2004/03/trix/rdfg-1/ +condition http://www.kinjal.com/condition: +bis http://bis.270a.info/dataset/ +infection http://www.agfa.com/w3c/2009/infectiousDisorder# +lexicon http://www.example.org/lexicon# +acrt http://privatealpha.com/ontology/certification/1# +laabs http://dbpedia.org/resource/ +rut http://rdfunit.aksw.org/ns/core# +location http://sw.deri.org/2006/07/location/loc# +rdagrp http://rdaregistry.info/termList/groovePitch/ +dbrc http://dbpedia.org/resource/Category: +hico http://purl.org/emmedi/hico/ +topo http://data.ign.fr/def/topo# +odv http://reference.data.gov.uk/def/organogram/ +gaf http://groundedannotationframework.org/ +pkgsrc http://pkgsrc.co/schema# +rdf123 http://rdf123.umbc.edu/ns/ +lcdr http://ns.lucid-project.org/revision/ +pmd https://w3id.org/pmd/co/ +locah http://data.archiveshub.ac.uk/def/ +osadm http://data.ordnancesurvey.co.uk/ontology/admingeo/ +msm http://iserve.kmi.open.ac.uk/ns/msm# +jolux http://data.legilux.public.lu/resource/ontology/jolux# +gci http://ontology.eil.utoronto.ca/GCI/Foundation/GCI-Foundation.owl# +limo http://www.purl.org/limo-ontology/limo# +oecc http://www.oegov.org/core/owl/cc# +escom http://vocab.linkeddata.es/datosabiertos/def/comercio/tejidoComercial# +mocanal http://www.semanticweb.org/asow/ontologies/2013/9/untitled-ontology-36# +year http://www.w3.org/year/ +gnm http://www.geonames.org/ontology/mappings/ +owlse http://www.daml.org/services/owl-s/1.2/generic/Expression.owl# +tm http://def.seegrid.csiro.au/isotc211/iso19108/2002/temporal# +gt https://vocab.eccenca.com/geniustex/ +prof http://www.w3.org/ns/dx/prof/ +obeu http://data.openbudgets.eu/ontology/ +incident http://vocab.resc.info/incident# +sto https://w3id.org/i40/sto# +llm http://lodlaundromat.org/metrics/ontology/ +odbc http://www.openlinksw.com/ontology/odbc# +reegle http://reegle.info/schema# +rdarr http://rdaregistry.info/termList/RDAReductionRatio/ +rdarm http://registry.info/termList/recMedium/ +crowd http://purl.org/crowd/ +aktivesa http://sa.aktivespace.org/ontologies/aktivesa# +nxs http://www.neclimateus.org/ +dot https://w3id.org/dot# +pmc http://identifiers.org/pmc/ +jp1 http://rdf.muninn-project.org/ontologies/jp1/ +zr http://explain.z3950.org/dtd/2.0/ +airs https://raw.githubusercontent.com/airs-linked-data/lov/latest/src/airs_vocabulary.ttl# +dio https://w3id.org/dio# +crsw http://courseware.rkbexplorer.com/ontologies/courseware# +regorg http://www.w3.org/ns/regorg# +ecgl http://schema.geolink.org/ +proms http://promsns.org/def/proms# +sx http://shex.io/ns/shex# +pair http://virtual-assembly.org/ontologies/pair# +puml http://plantuml.com/ontology# +bevon http://rdfs.co/bevon/ +sru http://www.loc.gov/zing/srw/ +geod http://vocab.lenka.no/geo-deling# +uta http://uptheasset.org/ontology# +rdafs http://rdaregistry.info/termList/fontSize/ +rdatr http://rdaregistry.info/termList/typeRec/ +ceterms http://purl.org/ctdl/terms/ +demlab http://www.demcare.eu/ontologies/demlab.owl# +webservice http://www.openlinksw.com/ontology/webservices# +teamwork http://topbraid.org/teamwork# +genre http://sparql.cwrc.ca/ontologies/genre# +ou http://opendata.unex.es/def/ontouniversidad# +pv http://ns.inria.fr/provoc# +muldicat http://iflastandards.info/ns/muldicat# +uc http://ucuenca.edu.ec/ontology# +oprovo http://openprovenance.org/ontology# +rdaco http://rdaregistry.info/termList/RDAContentType/ +olac http://www.language-archives.org/OLAC/1.0/ +oplcb http://www.openlinksw.com/schemas/crunchbase# +cpack http://cliopatria.swi-prolog.org/schema/cpack# +voc http://voc.odw.tw/ +basic http://def.seegrid.csiro.au/isotc211/iso19103/2005/basic# +defns http://www.openarchives.org/OAI/2.0/ +ontosec http://www.semanticweb.org/ontologies/2008/11/OntologySecurity.owl# +ns1 http://www.w3.org/1999/xhtml/vocab# +cd http://citydata.wu.ac.at/ns# +cmdi http://www.clarin.eu/cmd/ +clirio http://clirio.kaerle.com/clirio.owl# +rdaftn http://rdaregistry.info/termList/TacNotation/ +glview http://schema.geolink.org/dev/view/ +omnfed http://open-multinet.info/ontology/omn-federation# +ha http://sensormeasurement.appspot.com/ont/home/homeActivity# +keys http://purl.org/NET/c4dm/keys.owl# +maso http://securitytoolbox.appspot.com/MASO# +rdag2 http://rdvocab.info/ElementsGr2/ +essglobal http://purl.org/essglobal/vocab/v1.0/ +soch http://kulturarvsdata.se/ksamsok# +eurlex http://eur-lex.publicdata.eu/ontology/ +crime http://purl.org/vocab/reloc/ +mmt http://linkedmultimedia.org/sparql-mm/functions/temporal# +oplecrm http://www.openlinksw.com/ontology/ecrm# +moo http://www.movieontology.org/2009/11/09/movieontology.owl# +output http://volt-name.space/vocab/output# +lofv http://purl.org/legal_form/vocab# +erce http://xxefe.de/ +rdafmn http://rdaregistry.info/termList/MusNotation/ +espresup http://vocab.linkeddata.es/datosabiertos/def/hacienda/presupuestos# +mdi http://w3id.org/multidimensional-interface/ontology# +spdx http://spdx.org/rdf/terms# +gq http://genomequest.com/ +oplmkt http://www.openlinksw.com/ontology/market# +ecglview http://schema.geolink.org/view/ +mml http://www.w3.org/1998/Math/MathML/ +bsym http://bsym.bloomberg.com/sym/ +lido http://www.lido-schema.org/ +rdacc http://rdaregistry.info/termList/RDAColourContent/ +kegg http://bio2rdf.org/ns/kegg# +vstoi http://hadatac.org/ont/vstoi# +rdaterm http://rdaregistry.info/termList/RDATerms/ +gts http://resource.geosciml.org/ontology/timescale/gts# +vcard2006 http://www.w3.org/2006/vcard/ns# +dsn http://purl.org/dsnotify/vocab/eventset/ +caplibacl http://schemas.capita-libraries.co.uk/2015/acl/schema# +ali http://www.niso.org/schemas/ali/1.0/ +roar https://w3id.org/roar# +esadm http://vocab.linkeddata.es/datosabiertos/def/sector-publico/territorio# +owsom https://onlinesocialmeasures.wordpress.com/ +rdag1 http://rdvocab.info/Elements/ +plg http://parliament.uk/ontologies/legislation/ +kml http://www.opengis.net/kml/2.2# +ttp http://eample.com/test# +hr http://iserve.kmi.open.ac.uk/ns/hrests# +fnabox http://www.ontologydesignpatterns.org/ont/framenet/abox/ +td5 http://td5.org/# +rofch http://rdaregistry.info/termList/rofch/ +nlon http://lod.nl.go.kr/ontology/ +ubiq http://server.ubiqore.com/ubiq/core# +rdasco http://rdaregistry.info/termList/soundCont/ +sylld http://www.semanticweb.org/syllabus/data/ +ppn http://parliament.uk/ontologies/person-name/ +eem http://purl.org/eem# +rofem http://rdaregistry.info/termList/rofem/ +eccauth https://vocab.eccenca.com/auth/ +tsn http://purl.org/net/tsn# +iana http://www.iana.org/assignments/relation/ +ruto http://rdfunit.aksw.org/ns/core# +door http://kannel.open.ac.uk/ontology# +organ http://www.univalle.edu.co/ontologies/Organ# +eccrev https://vocab.eccenca.com/revision/ +datex http://vocab.datex.org/terms# +navm https://w3id.org/navigation_menu# +jpost http://rdf.jpostdb.org/ontology/jpost.owl# +task http://deductions.github.io/task-management.owl.ttl# +oplweb http://www.openlinksw.com/schemas/oplweb# +newsevents http://www.aifb.uni-karlsruhe.de/WBS/uhe/ontologies# +lslife http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-lifemapper.owl# +lawd http://lawd.info/ontology/ +rofer http://rdaregistry.info/termList/rofer/ +logies https://data.vlaanderen.be/ns/logies# +diag http://www.loc.gov/zing/srw/diagnostic/ +oxi http://omerxi.com/ontologies/core.owl.ttl# +lmx http://www.w3.org/XML/1998/namespace/ +bb http://www.snik.eu/ontology/bb/ +sakthi http://infotech.nitk.ac.in/research-scholars/sakthi-murugan-r/ +ssno http://www.w3.org/ns/ssn/ +dcx http://dublincore.org/dcx/ +agrovoc http://aims.fao.org/aos/agrovoc/ +sdt http://statisticaldata.linkedwidgets.org/terms/ +tix http://toptix.com/2010/esro/ +esapar http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/aparcamiento# +lheo http://www.conjecto.com/ontology/2015/lheo# +mmoon http://mmoon.org/mmoon/ +onisep http://rdf.onisep.fr/resource/ +led http://led.kmi.open.ac.uk/term/ +fntbox http://www.ontologydesignpatterns.org/ont/framenet/tbox/ +rvz http://rdfvizler.dyreriket.xyz/vocabulary/core# +fuseki http://jena.apache.org/fuseki# +fr https://w3id.org/fr/def/core# +mexv http://mex.aksw.org/mex-algo# +ldl https://w3id.org/ldpdl/ns# +hva http://www.ebusiness-unibw.org/ontologies/hva/ontology# +csdbp http://cs.dbpedia.org/ +rdapmt http://rdaregistry.info/termList/prodTactile/ +geojson https://purl.org/geojson/vocab# +vidont http://vidont.org/ +figigii http://www.omg.org/spec/FIGI/GlobalInstrumentIdentifiers/ +efrbroo http://erlangen-crm.org/efrbroo/ +rdaemm http://rdaregistry.info/termList/emulsionMicro/ +munc http://ns.inria.fr/munc# +literal http://www.essepuntato.it/2010/06/literalreification/ +pato http://purl.obolibrary.org/obo/ +studiop http://purl.org/resource/pilatesstudio/ +oplres http://www.openlinksw.com/ontology/restrictions# +fdbp http://fr.dbpedia.org/property/ +cwl https://w3id.org/cwl/cwl# +cdao http://purl.obolibrary.org/obo/ +bbccore http://www.bbc.co.uk/ontologies/coreconcepts/ +voidext http://rdfs.org/ns/void-ext# +spcm http://spi-fm.uca.es/spdef/models/deployment/spcm/1.0# +ruian https://data.cssz.cz/ontology/ruian/ +dbug http://ontologi.es/doap-bugs# +whisky http://vocab.org/whisky/terms/ +rdag3 http://rdvocab.info/ElementsGr3/ +hello https://www.youtube.com/user/SuperTellAFriend/featured/ +roadmap http://mappings.roadmap.org/ +sirene https://sireneld.io/vocab/sirene# +oils http://lemon-model.net/oils# +dicom http://purl.org/healthcarevocab/v1# +tb https://w3id.org/timebank# +lswmo http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-modelling.owl# +ago http://awesemantic-geo.link/ontology/ +traffic http://www.sensormeasurement.appspot.com/ont/transport/traffic# +lswpm http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-lifemapper-parameters.owl# +rdfdata http://rdf.data-vocabulary.org/rdf.xml# +sgg http://www.springernature.com/scigraph/graphs/ +physo http://merlin.phys.uni.lodz.pl/onto/physo/physo.owl# +bibrm http://vocab.ub.uni-leipzig.de/bibrm/ +planet http://dbpedia.org/ +pid http://permid.org/ontology/organization/ +gdc https://portal.gdc.cancer.gov/cases/ +umls http://bioportal.bioontology.org/ontologies/umls/ +owl2xml http://www.w3.org/2006/12/owl2-xml# +webac http://fedora.info/definitions/v4/webac# +videogame http://purl.org/net/vgo# +faostat http://reference.eionet.europa.eu/faostat/schema/ +oliasystem http://purl.org/olia/system.owl# +orcid http://orcid.org/ +open311 http://ontology.eil.utoronto.ca/open311# +vogd http://ogd.ifs.tuwien.ac.at/vienna/geo/ +mbgd http://mbgd.genome.ad.jp/owl/mbgd.owl# +apf http://jena.apache.org/ARQ/property# +yd https://yodata.io/ +meeting http://www.w3.org/2002/07/meeting# +customer http://www.valuelabs.com/ +radar http://www.radar-projekt.org/display/ +escjr http://vocab.linkeddata.es/datosabiertos/def/urbanismo-infraestructuras/callejero# +conll http://ufal.mff.cuni.cz/conll2009-st/task-description.html# +ldt https://www.w3.org/ns/ldt# +tui http://data.ifs.tuwien.ac.at/study/resource/ +bbccms http://www.bbc.co.uk/ontologies/cms/ +ndnp http://chroniclingamerica.loc.gov/terms# +pp http://peoplesplaces.de/ontology# +rdaz http://rdaregistry.info/Elements/z/ +eccdi https://vocab.eccenca.com/di/ +religion http://rdf.muninn-project.org/ontologies/religion# +aprov http://purl.org/a-proc# +si http://sisteminformasi.com/ +rofrr http://rdaregistry.info/termList/rofrr/ +jerm http://jermontology.org/ontology/JERMOntology# +cpov http://data.europa.eu/m8g/ +ja http://jena.hpl.hp.com/2005/11/Assembler# +itm http://spi-fm.uca.es/spdef/models/genericTools/itm/1.0# +lemonuby http://lemon-model.net/lexica/uby/ +rdabf http://rdaregistry.info/termList/bookFormat/ +gg http://www.gemeentegeschiedenis.nl/gg-schema# +url http://schema.org/ +vocnet http://schema.vocnet.org/ +glycan http://purl.jp/bio/12/glyco/glycan# +uom http://www.opengis.net/def/uom/OGC/1.0/ +hdo http://www.samos.gr/ontologies/helpdeskOnto.owl# +doacc http://purl.org/net/bel-epa/doacc# +ensembl http://rdf.ebi.ac.uk/resource/ensembl/ +mls http://www.w3.org/ns/mls# +memento http://mementoweb.org/ns# +nobel http://data.nobelprize.org/terms/ +iati http://purl.org/collections/iati/ +omg https://w3id.org/omg# +lfov https://w3id.org/legal_form# +afr http://purl.allotrope.org/ontologies/result# +scco http://rdf.ebi.ac.uk/terms/surechembl# +bpo https://w3id.org/bpo# +dicera http://semweb.mmlab.be/ns/dicera# +fred http://www.ontologydesignpatterns.org/ont/fred/domain.owl# +pdf http://ns.adobe.com/pdf/1.3/ +gns http://sws.geonames.org/ +lgdm http://linkedgeodata.org/meta/ +wimpo http://rdfex.org/withImports?uri= +esair http://vocab.linkeddata.es/datosabiertos/def/medio-ambiente/calidad-aire# +reg http://purl.org/linked-data/registry# +gont https://gont.ch/ +dpn http://purl.org/dpn# +numbers http://km.aifb.kit.edu/projects/numbers/ +ofrd http://purl.org/opdm/refrigerator# +dataid http://dataid.dbpedia.org/ns/core# +lmf http://www.lexinfo.net/lmf# +its http://www.w3.org/2005/11/its/rdf# +ethc http://ethoinformatics.org/ethocore/ +ln https://w3id.org/ln# +rpath https://w3id.org/lodsight/rdf-path# +frgeo http://rdf.insee.fr/geo/ +ioto http://www.irit.fr/recherches/MELODI/ontologies/IoT-O# +cue http://www.clarin.eu/cmdi/cues/display/1.0# +rdacarx http://rdaregistry.info/termList/RDACarrierEU/ +fp3 http://vocab.fusepool.info/fp3# +amt http://academic-meta-tool.xyz/vocab# +volt http://volt-name.space/ontology/ +pep https://w3id.org/pep/ +cim http://iec.ch/TC57/2013/CIM-schema-cim16# +odapps http://semweb.mmlab.be/ns/odapps# +rdaar http://rdaregistry.info/termList/AspectRatio/ +cocoon https://w3id.org/cocoon/v1.0# +tx http://swtmp.gitlab.io/vocabulary/templates.owl# +llont http://www.linklion.org/ontology# +cbim http://www.coinsweb.nl/cbim-2.0.rdf# +rdalay http://rdaregistry.info/termList/layout/ +audit http://fedora.info/definitions/v4/audit# +alethio http://aleth.io/ +uby http://purl.org/olia/ubyCat.owl# +r3d http://www.re3data.org/schema/3-0# +biml http://schemas.varigence.com/biml.xsd# +yaco https://www.irit.fr/recherches/MELODI/ontologies/cinema# +h2o http://def.seegrid.csiro.au/isotc211/iso19150/-2/2012/basic# +esservicio http://vocab.linkeddata.es/datosabiertos/def/sector-publico/servicio# +datacite http://purl.org/spar/datacite/ +amsl http://vocab.ub.uni-leipzig.de/amsl/ +ttla https://w3id.org/ttla/ +markus http://www.markus.com/ +naval http://rdf.muninn-project.org/ontologies/naval# +sfd http://semantic-forms.cc:9112/ldp/ +huto http://ns.inria.fr/huto/ +eame http://www.semanticweb.org/ontologia_EA# +mexcore http://mex.aksw.org/mex-core# +provinsi http://provinsi.com/ +az https://w3id.org/people/az/ +seeds http://deductions.github.io/seeds.owl.ttl# +bdo http://purl.bdrc.io/ontology/core/ +opllog http://www.openlinksw.com/ontology/logging# +add http://www.datatourisme.fr/ontology/core/1.0# +um http://intelleo.eu/ontologies/user-model/ns/ +pmo http://premon.fbk.eu/ontology/core# +rofsm http://rdaregistry.info/termList/rofsm/ +wde http://www.wikidata.org/entity/ +ver https://w3id.org/version/ontology# +geovoid http://purl.org/geovocamp/ontology/geovoid/ +system http://www.univalle.edu.co/ontologies/System# +tadirah http://tadirah.dariah.eu/vocab/ +cwork http://www.bbc.co.uk/ontologies/creativework/ +svcs http://rdfs.org/sioc/services# +vplan http://www.ifs.tuwien.ac.at/~miksa/ontologies/VPlan.owl# +composer http://dbpedia.org/ontology/composer/ +imo http://imgpedia.dcc.uchile.cl/ontology# +travel http://www.co-ode.org/roberts/travel.owl# +lyon http://dbpedia.org/resource/Lyon/ +tree https://w3id.org/tree# +piero http://reactionontology.org/piero/ +imind http://schema.intellimind.ns/symbology# +opa https://w3id.org/laas-iot/adream# +da https://www.wowman.org/index.php?id=1&type=get# +lovc https://w3id.org/lovcube/ns/lovcube# +dk http://www.data-knowledge.org/dk/schema/rdf/latest/ +minim http://purl.org/minim/minim# +b3kat http://lod.b3kat.de/title/ +vir http://w3id.org/vir# +rdafnv http://rdaregistry.info/termList/noteForm/ +frappe http://streamreasoning.org/ontologies/frappe# +eepsa https://w3id.org/eepsa# +uneskos http://purl.org/voc/uneskos# +sdshare http://www.sdshare.org/2012/extension/ +owms http://standaarden.overheid.nl/owms/terms/ +qms http://data.europa.eu/esco/qms# +bdc http://dbpedia.org/resource/Category: +rofid http://rdaregistry.info/termList/rofid/ +l2sp http://www.linked2safety-project.eu/properties/ +alice http://example.org/ +koly http://www.ensias.ma/ +vacseen1 http://www.semanticweb.org/parthasb/ontologies/2014/6/vacseen1/ +rofin http://rdaregistry.info/termList/rofin/ +oplacl http://www.openlinksw.com/ontology/acl# +rls https://w3id.org/lovcube/ns/relovstats# +afm http://purl.allotrope.org/ontologies/material/ +meshv http://id.nlm.nih.gov/mesh/vocab# +tarql http://tarql.github.io/tarql# +rofit http://rdaregistry.info/termList/rofit/ +pcit http://public-contracts.nexacenter.org/id/propertiesRole/ +ecoll http://purl.org/ceu/eco/1.0# +lgt http://linkedgadget.com/wiki/Property: +ecore http://www.eclipse.org/emf/2002/Ecore# +cwlprov https://w3id.org/cwl/prov# +tgm http://id.loc.gov/vocabulary/graphicMaterials/ +rdapm http://rdaregistry.info/termList/RDAproductionMethod/ +ims http://www.imsglobal.org/xsd/imsmd_v1p2/ +hasneto http://hadatac.org/ont/hasneto# +eol http://purl.org/biodiversity/eol/ +sdmxcode http://purl.org/linked-data/sdmx/2009/code# +duv http://www.w3.org/ns/duv# +mexalgo http://mex.aksw.org/mex-algo# +id http://identifiers.org/ +fun http://w3id.org/sparql-generate/fn/ +dpv http://www.w3.org/ns/dpv# +rofrt http://rdaregistry.info/termList/rofrt/ +uri4uri http://uri4uri.net/vocab# +county http://myexample.org/county# +assoc https://w3id.org/associations/vocab# +gbol http://gbol.life/0.1# +mydb http://mydb.org/ +bblfish http://bblfish.net/people/henry/card# +scho http://www.scholarlydata.org/ontology/conference-ontology.owl# +swa http://topbraid.org/swa# +rgml http://purl.org/puninj/2001/05/rgml-schema# +fhir http://hl7.org/fhir/ +rdaspc http://rdaregistry.info/termList/specPlayback/ +vehma http://deductions.github.io/vehicule-management.owl.ttl# +juso http://rdfs.co/juso/ +dcosample http://info.deepcarbon.net/sample/schema# +cpi http://www.ebusiness-unibw.org/ontologies/cpi/ns# +qkdv http://qudt.org/vocab/dimensionvector/ +pmhb http://pmhb.org/ +mmm http://www.mico-project.eu/ns/mmm/2.0/schema# +brk http://brk.basisregistraties.overheid.nl/def/brk# +conference https://w3id.org/scholarlydata/ontology/conference-ontology.owl# +pmonb http://premon.fbk.eu/ontology/nb# +irsteaont http://ontology.irstea.fr/weather/ontology# +yso http://www.yso.fi/onto/yso/ +rdaft http://rdaregistry.info/termList/fileType/ +ilap http://data.posccaesar.org/ilap/ +smxm http://smxm.ga/ +rvl http://purl.org/rvl/ +itcat http://th-brandenburg.de/ns/itcat# +pmofn http://premon.fbk.eu/ontology/fn# +semiot http://w3id.org/semiot/ontologies/semiot# +mobivoc http://schema.mobivoc.org/ +gvoith http://assemblee-virtuelle.github.io/grands-voisins-v2/thesaurus.ttl# +irstea http://ontology.irstea.fr/ +ipsv http://id.esd.org.uk/list/ +iiif http://iiif.io/api/image/2# +rofrm http://rdaregistry.info/termList/rofrm/ +dwciri http://rs.tdwg.org/dwc/iri/ +lgdt http://linkedgeodata.org/triplify/ +rdabs http://rdaregistry.info/termList/broadcastStand/ +sorg http://schema.org/ +mandaat http://data.vlaanderen.be/ns/mandaat# +maeco http://edg.topbraid.solutions/maeco/ +drk http://drakon.su/ +srx http://www.w3.org/2005/sparql-results# +tosh http://topbraid.org/tosh# +dto http://www.datatourisme.fr/ontology/core/1.0# +dsw http://purl.org/dsw/ +dead http://utpl.edu.ec/sbc/data/ +emergelm http://purl.org/emergel/modules# +odf http://docs.oasis-open.org/ns/office/1.2/meta/odf# +alg http://drakon.su/ADF# +adf http://purl.allotrope.org/ontologies/datapackage# +besluit http://data.vlaanderen.be/ns/besluit# +vam http://www.metmuseum.org/ +dm2e http://onto.dm2e.eu/schemas/dm2e/ +neotec http://neotec.rc.unesp.br/resource/Neotectonics/ +sdmxm http://purl.org/linked-data/sdmx/2009/measure# +nature http://deductions.github.io/nature_observation.owl.ttl# +tavprov http://ns.taverna.org.uk/2012/tavernaprov/ +bds http://www.bigdata.com/rdf/search# +ondc http://www.semanticweb.org/ontologies/2012/1/Ontology1329913965202.owl# +oplli http://www.openlinksw.com/schemas/linkedin# +fluidops http://www.fluidops.com/ +rofhf http://rdaregistry.info/termList/rofhf/ +or http://openresearch.org/vocab/ +pm http://premon.fbk.eu/resource/ +gobierno http://www.gobierno.es/gobierno/ +chear http://hadatac.org/ont/chear# +clapit http://dati.gov.it/onto/clapit/ +ctrl https://w3id.org/ibp/CTRLont# +metadata http://purl.oreilly.com/ns/meta/ +ppr http://purl.org/datanode/ppr/ns/ +undata http://citydata.wu.ac.at/Linked-UNData/data/ +shui https://vocab.eccenca.com/shui/ +nkos http://w3id.org/nkos# +oplwebsrv http://www.openlinksw.com/ontology/webservices# +olac11 http://www.language-archives.org/OLAC/1.1/ +summa http://purl.org/voc/summa/ +ncicp http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl# +sfn http://semweb.datasciencelab.be/ns/sfn# +persee http://data.persee.fr/ontology/persee_ontology/ +isbdu http://iflastandards.info/ns/isbd/unc/elements/ +nih http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl# +voidex http://www.swi-prolog.org/rdf/library/ +dbfo http://dbpedia.org/facts/ontology# +scholl http://menemeneml.com/school# +vsearch http://vocab.sti2.at/vsearch# +pmovn http://premon.fbk.eu/ontology/vn# +esproc http://vocab.linkeddata.es/datosabiertos/def/sector-publico/procedimientos# +ctxdesc http://www.demcare.eu/ontologies/contextdescriptor.owl# +brt http://brt.basisregistraties.overheid.nl/def/top10nl# +timex http://data.wu.ac.at/ns/timex# +pfeepsa https://w3id.org/pfeepsa# +wdtn http://www.wikidata.org/prop/direct-normalized/ +rdfp https://w3id.org/rdfp/ +pcdm http://pcdm.org/models# +cubeont http://ontology.cube.global/ +input http://volt-name.space/vocab/input# +edac http://ontology.cybershare.utep.edu/ELSEWeb/elseweb-edac.owl# +ispra http://dati.isprambiente.it/ontology/core# +sgfn http://w3id.org/sparql-generate/fn/ +one https://bioportal.bioontology.org/ontologies/ONE/ +rdax http://rdaregistry.info/Elements/x/ +oplbenefit http://www.openlinksw.com/ontology/benefits# +iter http://w3id.org/sparql-generate/iter/ +veo http://linkeddata.finki.ukim.mk/lod/ontology/veo# +lsq http://lsq.aksw.org/vocab# +ldn https://www.w3.org/TR/ldn/# +semsur http://purl.org/SemSur/ +rdapf http://rdaregistry.info/termList/presFormat/ +osd http://a9.com/-/spec/opensearch/1.1/ +geoloc http://deductions.github.io/geoloc.owl.ttl# +legal http://www.w3.org/ns/legal# +mem http://mementoweb.org/ns# +edg http://edg.topbraid.solutions/model/ +lmu https://w3id.org/laas-iot/lmu# +aozora http://purl.org/net/aozora/ +remetca http://www.purl.org/net/remetca# +cog http://purl.org/ontology/cco/core# +edgarcik http://edgarwrap.ontologycentral.com/cik/ +vocals http://w3id.org/rsp/vocals# +beer http://beer.com/ +pand http://bag.basisregistraties.overheid.nl/bag/id/pand/ +refexo http://purl.jp/bio/01/refexo# +km4c http://www.disit.org/km4city/schema# +wdv http://www.wikidata.org/value/ +cff http://purl.oclc.org/NET/ssnx/cf/cf-feature# +dcodt http://info.deepcarbon.net/datatype/schema# +ucum http://purl.oclc.org/NET/muo/ucum/ +it http://www.influencetracker.com/ontology# +wail http://www.eyrie.org/~zednenem/2002/wail/ +neotecbib http://neotec.rc.unesp.br/resource/NeotectonicsBibliography/ +physics http://www.astro.umd.edu/~eshaya/astro-onto/owl/physics.owl# +asawoo http://liris.cnrs.fr/asawoo/ +spv http://completeness.inf.unibz.it/sp-vocab# +mwapi https://www.mediawiki.org/ontology#API/ +bkb https://budayakb.cs.ui.ac.id/ns# +provoc http://ns.inria.fr/provoc/ +sgiter http://w3id.org/sparql-generate/iter/ +fnom https://w3id.org/function/vocabulary/mapping# +dsfv http://sws.ifi.uio.no/vocab/dsf/henriwi/dsf# +isidore http://www.rechercheisidore.fr/class/ +sdmxc http://purl.org/linked-data/sdmx/2009/concept# +oplstocks http://www.openlinksw.com/ontology/stocks# +swrc2 https://www.cs.vu.nl/~mcaklein/onto/swrc_ext/2005/05# +elod http://linkedeconomy.org/ontology# +changeset http://purl.org/vocab/changeset/schema# +nosql http://purl.org/db/nosql# +bioentity http://bioentity.io/vocab/ +rami http://iais.fraunhofer.de/vocabs/rami# +wikimedia http://upload.wikimedia.org/wikipedia/commons/f/f6/ +docker http://www.w3.org/ns/bde/docker/ +swcomp https://github.com/ali1k/ld-reactor/blob/master/vocabulary/index.ttl# +s4syst https://saref.etsi.org/saref4syst/ +dcap http://purl.org/ws-mmi-dc/terms/ +roc https://w3id.org/ro/curate# +meat http://example.com/ +dsv https://w3id.org/dsv# +ido http://purl.obolibrary.org/obo/ido.owl# +eccpubsub https://vocab.eccenca.com/pubsub/ +rdacpc http://rdaregistry.info/termList/configPlayback/ +cska http://pfclitex.com/ +aml https://w3id.org/i40/aml# +dcodata http://info.deepcarbon.net/data/schema# +gdpr https://vocab.eccenca.com/gdpr/ +loted http://loted.eu/ontology# +ldqm http://linkeddata.es/resource/ldqm/ +sdterms http://statisticaldata.linkedwidgets.org/terms/ +mus http://data.doremus.org/ontology# +lg https://purl.org/lg/ +rdaill http://rdaregistry.info/termList/IllusContent/ +connard https://mail.google.com/mail/u/1/# +rm http://jazz.net/ns/rm# +wab http://wab.uib.no/cost-a32_philospace/wittgenstein.owl# +globalcube http://kalmar32.fzi.de/triples/global-cube.ttl# +nno https://w3id.org/nno/ontology# +seo http://sda.tech/SEOontology/SEO/ +vort http://rockets.topbraid.solutions/vort/ +wsdl http://www.w3.org/ns/wsdl-rdf# +edr https://w3id.org/laas-iot/edr# +maet http://edg.topbraid.solutions/taxonomy/macroeconomics/ +ca http://complyadvantage.com/ +ns2 http://ogp.me/ns#video: +number http://km.aifb.kit.edu/projects/numbers/number# +master1 http://idl.u-grenoble3.fr/ +dbms http://www.openlinksw.com/ontology/dbms-app-ontology# +xslopm http://purl.org/net/opmv/types/xslt# +psv http://www.wikidata.org/prop/statement/value/ +devuan https://devuan.net.br/ +bdr http://purl.bdrc.io/resource/ +ldq http://www.linkeddata.es/ontology/ldq# +d3s http://vocbench.solidaridad.cloud/taxonomies# +bob http://good.dad/meaning/bob# +iso37120 http://ontology.eil.utoronto.ca/ISO37120.owl# +rdagen http://rdaregistry.info/termList/RDAGeneration/ +aseonto http://requirement.ase.ru/requirements_ontology# +unspsc http://ontoview.org/schema/unspsc/1# +bld http://biglinkeddata.com/ +pbody http://reference.data.gov.uk/def/public-body/ +rdare http://rdaregistry.info/termList/RDARegionalEncoding/ +efd http://data.foodanddrinkeurope.eu/ontology# +qbe http://citydata.wu.ac.at/qb-equations# +ifcowl http://www.buildingsmart-tech.org/ifcOWL/IFC4_ADD2# +rofsf http://rdaregistry.info/termList/rofsf/ +aksw http://aksw.org/ +wn30 http://purl.org/vocabularies/princeton/wn30/ +trao http://linkeddata.finki.ukim.mk/lod/ontology/tao# +pop http://wiki.dbpedia.org/ +ontop https://w3id.org/ontop/ +eustd http://eurostat.linked-statistics.org/data# +marcrole http://id.loc.gov/vocabulary/relators/ +rofim http://rdaregistry.info/termList/rofim/ +s4ee https://w3id.org/saref4ee# +otl https://w3id.org/opentrafficlights# +w3cgeo http://www.w3.org/2003/01/geo/wgs84_pos# +rdavf http://rdaregistry.info/termList/videoFormat/ +dby http://dbpedia.org/class/yago/ +geo7 https://www.geo7.ch/ +imas https://sparql.crssnky.xyz/imasrdf/URIs/imas-schema.ttl# +tissue http://www.univalle.edu.co/ontologies/Tissue# +noise http://vocab.linkeddata.es/datosabiertos/def/medio-ambiente/contaminacion-acustica# +rdacdt http://rdaregistry.info/termList/RDACartoDT/ +halyard http://merck.github.io/Halyard/ns# +datacron http://www.datacron-project.eu/datAcron# +geor http://www.opengis.net/def/rule/geosparql/ +rfd http://com.intrinsec//ontology# +spvqa https://bmake.th-brandenburg.de/spv# +idot http://identifiers.org/idot/ +emergel http://purl.org/emergel/core# +sohukd http://sweetontology.net/humanKnowledgeDomain/ +foaffff http://gogl.com/ +apb http://www.analysispartners.org/businessmodel/ +ncbigene http://identifiers.org/ncbigene/ +sciprov http://sweetontology.net/reprSciProvenance/ +ksam http://kulturarvsdata.se/ksamsok# +powla http://purl.org/powla/powla.owl# +atlasterms http://rdf.ebi.ac.uk/terms/atlas/ +llr http://lodlaundromat.org/resource/ +dnbt http://d-nb.info/standards/elementset/dnb# +estatwrap http://ontologycentral.com/2009/01/eurostat/ns# +ul http://underlay.mit.edu/ns/ +bsh https://brickschema.org/schema/1.1.0/BrickShape# +phy https://w3id.org/skgo/phy# +obws http://delicias.dia.fi.upm.es/ontologies/ObjectWithStates.owl# +llalg http://www.linklion.org/algorithm/ +esagen http://vocab.ciudadesabiertas.es/def/sector-publico/agenda-municipal# +rsctx http://softeng.polito.it/rsctx# +ods http://lod.xdams.org/ontologies/ods/ +dpla http://dp.la/info/developers/map/ +soma http://sweetontology.net/matr/ +dgfr http://colin.maudry.com/ontologies/dgfr# +r4r http://guava.iis.sinica.edu.tw/r4r/ +rico https://www.ica.org/standards/RiC/ontology# +pmopb http://premon.fbk.eu/ontology/pb# +fnml http://semweb.mmlab.be/ns/fnml# +dm http://datamusee.givingsense.eu/onto/ +crmeh http://purl.org/crmeh# +dqc http://semwebquality.org/ontologies/dq-constraints# +goaf http://goaf.fr/goaf# +ermrk http://www.essepuntato.it/2008/12/earmark# +rdaad http://rdaregistry.info/Elements/a/datatype/ +kmgeo http://km.aifb.kit.edu/services/geo/ontology# +eproc http://10.0.3.120/download/eproc_FORN_v02.owl# +scra http://purl.org/net/schemarama# +dcatnl http://standaarden.overheid.nl/dcatnl/terms/ +bci https://w3id.org/BCI-ontology# +manto http://com.vortic3.MANTO/ +valueflows https://w3id.org/valueflows/ +decprov http://promsns.org/def/decprov# +oop http://w3id.org/oop# +modsci https://w3id.org/skgo/modsci# +gvoi http://assemblee-virtuelle.github.io/grands-voisins-v2/gv.owl.ttl# +estatgph http://estatwrap.ontologycentral.com/id/nama_aux_gph# +fssp http://linkeddata.fssprus.ru/resource/ +loci http://linked.data.gov.au/def/loci# +orgesv2 http://datos.gob.es/sites/default/files/OntologiaDIR3/orges.owl# +oplangel http://www.openlinksw.com/schemas/angel# +daap http://daap.dsi.universite-paris-saclay.fr/wiki/ +estrf http://vocab.linkeddata.es/datosabiertos/def/transporte/trafico# +voidwh http://www.ics.forth.gr/isl/VoIDWarehouse/VoID_Extension_Schema.owl# +ocds http://purl.org/onto-ocds/ocds# +s3n http://w3id.org/s3n/ +cbb https://data.cbb.omgeving.vlaanderen.be/ns/cbb# +rofet http://rdaregistry.info/termList/rofet/ +theme http://voc.odw.tw/theme/ +gmo http://purl.jp/bio/10/gmo/ +vss http://automotive.eurecom.fr/vsso# +nas https://data.nasa.gov/ontologies/atmonto/NAS# +rimmf http://rimmf.com/vocab/ +iotlite http://purl.oclc.org/NET/UNIS/fiware/iot-lite# +imjv https://data.imjv.omgeving.vlaanderen.be/ns/imjv# +dmp http://www.sysresearch.org/rda-common-dmp# +oup http://purl.org/ontology-use-patterns# +ideotalex http://www.ideotalex.eu/datos/recurso/ +literature http://purl.org/net/cnyt-literature# +odw http://odw.tw/ +ii http://sparql.cwrc.ca/ontologies/ii# +xbrll https://w3id.org/vocab/xbrll# +prohow https://w3id.org/prohow# +ogdl4m https://github.com/martynui/OGDL4M/ +tsnchange http://purl.org/net/tsnchange# +qk http://qudt.org/vocab/quantitykind/ +occ http://w3id.org/occ# +somaoc http://sweetontology.net/matrOrganicCompound/ +tikag https://www.tikag.com/ +lcsh http://id.loc.gov/authorities/subjects/ +pham https://w3id.org/skgo/pham# +crminf http://www.cidoc-crm.org/cidoc-crm/CRMinf/ +nrv http://ns.inria.fr/nrv# +ecowlim http://ecowlim.tfri.gov.tw/lode/resource/ +gdprov https://w3id.org/GDPRov# +geofabric http://linked.data.gov.au/def/geofabric# +hosp http://health.data.gov/def/hospital/ +gnaf http://linked.data.gov.au/def/gnaf# +snac http://socialarchive.iath.virginia.edu/ +gdprtext https://w3id.org/GDPRtEXT# +linkrel https://www.w3.org/ns/iana/link-relations/relation# +smartapi http://smart-api.io/ontology/1.0/smartapi# +mexperf http://mex.aksw.org/mex-perf# +soproptg http://sweetontology.net/propTemperatureGradient/ +oplp http://www.openlinksw.com/ontology/purchases# +terms http://purl.org/dc/terms/ +soreaa http://sweetontology.net/realmAtmo/ +eproc2 http://10.0.3.120/download/eproc_FORN_v04.owl# +yandex http://yandex.ru/ +loupe http://ont-loupe.linkeddata.es/def/core/ +iab https://www.iab.com/guidelines/taxonomy/ +ccp http://cookingbigdata.com/linkeddata/ccpricing# +omnlc http://open-multinet.info/ontology/omn-lifecycle# +cwlgit https://w3id.org/cwl/view/git/ +isaterms http://purl.org/isaterms/ +fel http://w3id.org/vcb/fel# +sfl http://data.finlex.fi/schema/sfl/ +shema http://schema.org/ +bitl http://lib.bit.edu.cn/ontology/1.0/ +esdbpr http://es.dbpedia.org/resource/ +s4bldg https://w3id.org/def/saref4bldg# +m3 http://sensormeasurement.appspot.com/m3# +earth http://linked.earth/ontology# +isoadr http://reference.data.gov.au/def/ont/iso19160-1-address# +lesa http://hadatac.org/ont/lesa# +ddb http://www.deutsche-digitale-bibliothek.de/edm/ +cwmo http://purl.org/cwmo/# +gcon https://w3id.org/GConsent# +mdont http://ont.matchdeck.com/ +wild http://purl.org/wild/vocab# +eqp https://data.nasa.gov/ontologies/atmonto/equipment# +ontoneo http://purl.obolibrary.org/obo/ontoneo/ +ordo http://www.orpha.net/ORDO/ +stx http://purl.org/cyber/stix# +jup http://w3id.org/charta77/jup/ +pplan http://purl.org/net/p-plan# +hctl https://www.w3.org/2019/wot/hypermedia# +sopropp http://sweetontology.net/propPressure/ +m3lite http://purl.org/iot/vocab/m3-lite# +pq http://www.wikidata.org/prop/qualifier/ +stencila http://schema.stenci.la/ +osys http://purl.org/olia/system.owl# +lblodlg http://data.lblod.info/vocabularies/leidinggevenden/ +iaph http://www.juntadeandalucia.es/datosabiertos/portal/iaph/dataset/dataset/6c199ca2-8d2e-4c12-833c-f28 +sopropsl http://sweetontology.net/propSpaceLocation/ +esgs https://w3id.org/edwin/ontology/ +biolink https://w3id.org/biolink/vocab/ +capes http://vocab.capes.gov.br/def/vcav# +medred http://w3id.org/medred/medred# +frbroo http://iflastandards.info/ns/fr/frbr/frbroo/ +extech https://w3id.org/executionTechnique/ontology/ +sostc http://sweetontology.net/stateChemical/ +losp http://sparql.sstu.ru:3030/speciality/ +soproptf http://sweetontology.net/propTimeFrequency/ +sophatmowm https://sweetontology.net/phenAtmoWindMesoscale/ +vehman http://deductions.github.io/vehicule-management.owl.ttl# +sostv http://sweetontology.net/stateVisibility/ +skoslex https://bp4mc2.org/def/skos-lex# +chemsci https://w3id.org/skgo/chemsci# +soprocsc http://sweetontology.net/procStateChange/ +sopropsp http://sweetontology.net/propSpeed/ +constant http://qudt.org/vocab/constant/ +epplan https://w3id.org/ep-plan# +jsonschema https://www.w3.org/2019/wot/json-schema# +sopropsdis http://sweetontology.net/propSpaceDistance/ +sorepsc http://sweetontology.net/reprSciComponent/ +sophsy http://sweetontology.net/phenSystem/ +wotsec https://www.w3.org/2019/wot/security# +sosttf http://sweetontology.net/stateTimeFrequency/ +esagm http://vocab.ciudadesabiertas.es/def/sector-publico/agenda-municipal# +soreacz http://sweetontology.net/realmClimateZone/ +sorepsf http://sweetontology.net/reprSciFunction/ +sorepmo http://sweetontology.net/reprMathOperation/ +sorelm http://sweetontology.net/relaMath/ +eppl https://w3id.org/ep-plan# +eccf http://data.europa.eu/54i/ +dave http://theme-e.adaptcentre.ie/dave# +sweet http://sweetontology.net/ +dentsci https://w3id.org/skgo/dentsci# +sopropti http://sweetontology.net/propTime/ +soreaas http://sweetontology.net/realmAstroStar/ +soprocp http://sweetontology.net/procPhysical/ +iospress http://ld.iospress.nl/rdf/ontology/ +sopropo http://sweetontology.net/propOrdinal/ +sorepsrs http://sweetontology.net/reprSpaceReferenceSystem/ +soproc http://sweetontology.net/proc/ +sopropi http://sweetontology.net/propIndex/ +soprops http://sweetontology.net/propSpace/ +sorept http://sweetontology.net/reprTime/ +sorealc http://sweetontology.net/realmLandCoastal/ +sohut http://sweetontology.net/humanTransportation/ +sorepsl http://sweetontology.net/reprSciLaw/ +sorelh http://sweetontology.net/relaHuman/ +somamin http://sweetontology.net/matrMineral/ +sostrr http://sweetontology.net/stateRoleRepresentative/ +sohur http://sweetontology.net/humanResearch/ +sopropsdir http://sweetontology.net/propSpaceDirection/ +sostth http://sweetontology.net/stateThermodynamic/ +soreaofl http://sweetontology.net/realmOceanFloor/ +pineapple http://hexananas.com/pineapple# +sophatmow http://sweetontology.net/phenAtmoWind/ +sopropr http://sweetontology.net/propRotation/ +sorepmso http://sweetontology.net/reprMathSolution/ +sohutr http://sweetontology.net/humanTechReadiness/ +ldc https://tac.nist.gov/tracks/SM-KBP/2018/ontologies/SeedlingOntology# +sophfd http://sweetontology.net/phenFluidDynamics/ +sorepscd http://sweetontology.net/reprSpaceCoordinate/ +pcdmuse http://pcdm.org/use# +sorepmg http://sweetontology.net/reprMathGraph/ +sophso http://sweetontology.net/phenSolid/ +soprope http://sweetontology.net/propEnergy/ +dprov http://promsns.org/def/do# +sorepmfo http://sweetontology.net/reprMathFunctionOrthogonal/ +sopropsh http://sweetontology.net/propSpaceHeight/ +sophoc http://sweetontology.net/phenOceanCoastal/ +sopropfr http://sweetontology.net/propFraction/ +asgs http://linked.data.gov.au/def/asgs# +misp http://purl.org/cyber/misp# +sorel http://sweetontology.net/rela/ +foio https://w3id.org/seas/FeatureOfInterestOntology/ +inchikey https://identifiers.org/inchikey: +somanr http://sweetontology.net/matrNaturalResource/ +sorepdp http://sweetontology.net/reprDataProduct/ +sorepsu http://sweetontology.net/reprSciUnits/ +somaae http://sweetontology.net/matrAerosol/ +soreas http://sweetontology.net/realmSoil/ +trek https://w3id.org/trek/ +sohues http://sweetontology.net/humanEnvirStandards/ +sostri http://sweetontology.net/stateRoleImpact/ +mccv http://purl.jp/bio/10/mccv# +sorelcl http://sweetontology.net/relaClimate/ +sorear http://sweetontology.net/realmRegion/ +skosthes http://purl.org/iso25964/skos-thes# +sorep http://sweetontology.net/repr/ +sophatmopc http://sweetontology.net/phenAtmoPrecipitation/ +sorelsp http://sweetontology.net/relaSpace/ +sopropb http://sweetontology.net/propBinary/ +sopropcap http://sweetontology.net/propCapacity/ +sopropmf http://sweetontology.net/propMassFlux/ +sostrt http://sweetontology.net/stateRoleTrust/ +phto http://rhizomik.net/ontologies/PlantHealthThreats.owl.ttl# +sorepm http://sweetontology.net/reprMath/ +sorelpr http://sweetontology.net/relaProvenance/ +somarock http://sweetontology.net/matrRock/ +somais http://sweetontology.net/matrIsotope/ +twitter http://stocktwits.com/ +sostso http://sweetontology.net/stateSolid/ +soreps http://sweetontology.net/reprSpace/ +probont http://www.probonto.org/ontology# +sorelsc http://sweetontology.net/relaSci/ +sost http://sweetontology.net/state/ +sopropm http://sweetontology.net/propMass/ +d2s https://w3id.org/d2s/ +sopropfu http://sweetontology.net/propFunction/ +sophel http://sweetontology.net/phenElecMag/ +somaem http://sweetontology.net/matrElementalMolecule/ +sosttg http://sweetontology.net/stateTimeGeologic/ +sorealp http://sweetontology.net/realmLandProtected/ +sopropef http://sweetontology.net/propEnergyFlux/ +proton http://www.ontotext.com/proton/ +edupro http://ns.inria.fr/semed/eduprogression# +sorepsp http://sweetontology.net/reprSciProvenance/ +somapl http://sweetontology.net/matrPlant/ +sophec http://sweetontology.net/phenEcology/ +sophatmos http://sweetontology.net/phenAtmoSky/ +sophcr http://sweetontology.net/phenCryo/ +sorelt http://sweetontology.net/relaTime/ +sorepsme http://sweetontology.net/reprSciMethodology/ +soph http://sweetontology.net/phen/ +sostsy http://sweetontology.net/stateSystem/ +sopropcat http://sweetontology.net/propCategorical/ +sophcy http://sweetontology.net/phenCycle/ +sophst http://sweetontology.net/phenStar/ +matvoc http://stream-ontology.com/matvoc/ +sorealo http://sweetontology.net/realmLandOrographic/ +sorepdsv http://sweetontology.net/reprDataServiceValidation/ +sorelch http://sweetontology.net/relaChemical/ +soreac http://sweetontology.net/realmCryo/ +soprop http://sweetontology.net/prop/ +soreabb http://sweetontology.net/realmBiolBiome/ +somains http://sweetontology.net/matrInstrument/ +sosto http://sweetontology.net/stateOrdinal/ +sorelph http://sweetontology.net/relaPhysical/ +soreao http://sweetontology.net/realmOcean/ +sostb http://sweetontology.net/stateBiological/ +sorepdsg http://sweetontology.net/reprDataServiceGeospatial/ +sorepdsr http://sweetontology.net/reprDataServiceReduction/ +sopropsm http://sweetontology.net/propSpaceMultidimensional/ +sorepsd http://sweetontology.net/reprSpaceDirection/ +somaind http://sweetontology.net/matrIndustrial/ +biogrid http://thebiogrid.org/ +sorepmst http://sweetontology.net/reprMathStatistics/ +sophei http://sweetontology.net/phenEnvirImpact/ +sohuj http://sweetontology.net/humanJurisdiction/ +somaw http://sweetontology.net/matrWater/ +sopropdifu http://sweetontology.net/propDiffusivity/ +sopropq http://sweetontology.net/propQuantity/ +soreaaw http://sweetontology.net/realmAtmoWeather/ +sopropcou http://sweetontology.net/propCount/ +soreahb http://sweetontology.net/realmHydroBody/ +sophatmofo http://sweetontology.net/phenAtmoFog/ +sopropdife http://sweetontology.net/propDifference/ +atts https://data.nasa.gov/ontologies/atmonto/general# +ciao http://ciao.it/ +ingredient http://www.owl-ontologies.com/test.owl/ingredient/ +sorepdsa http://sweetontology.net/reprDataServiceAnalysis/ +sorepmf http://sweetontology.net/reprMathFunction/ +sopropcon http://sweetontology.net/propConductivity/ +sorepdf http://sweetontology.net/reprDataFormat/ +somael http://sweetontology.net/matrElement/ +sopropche http://sweetontology.net/propChemical/ +somaf http://sweetontology.net/matrFacility/ +sophcm http://sweetontology.net/phenCycleMaterial/ +sophpc http://sweetontology.net/phenPlanetClimate/ +osmm https://www.openstreetmap.org/meta/ +somac http://sweetontology.net/matrCompound/ +sophwn http://sweetontology.net/phenWaveNoise/ +sorepds http://sweetontology.net/reprDataService/ +sophft http://sweetontology.net/phenFluidTransport/ +sopropdr http://sweetontology.net/propDimensionlessRatio/ +somarocki http://sweetontology.net/matrRockIgneous/ +bldont http://ont.biglinkeddata.com/ +donto http://reference.data.gov.au/def/ont/dataset# +snomedct http://purl.bioontology.org/ontology/SNOMEDCT/ +somab http://sweetontology.net/matrBiomass/ +sophb http://sweetontology.net/phenBiol/ +sophod http://sweetontology.net/phenOceanDynamics/ +beo http://pi.pauwel.be/voc/buildingelement# +country http://eulersharp.sourceforge.net/2003/03swap/countries# +sorepdm http://sweetontology.net/reprDataModel/ +somaen http://sweetontology.net/matrEnergy/ +sorepts http://sweetontology.net/reprTimeSeason/ +sophatmoc http://sweetontology.net/phenAtmoCloud/ +sopropst http://sweetontology.net/propSpaceThickness/ +lprov http://id.learning-provider.data.ac.uk/terms# +sopropcha http://sweetontology.net/propCharge/ +sostrg http://sweetontology.net/stateRoleGeographic/ +somaeq http://sweetontology.net/matrEquipment/ +soreaabl http://sweetontology.net/realmAtmoBoundaryLayer/ +sohuecons http://sweetontology.net/humanEnvirConservation/ +hdgi https://w3id.org/hdgi# +soreal http://sweetontology.net/realmLandform/ +eupont http://elite.polito.it/ontologies/eupont.owl# +sophatmot http://sweetontology.net/phenAtmoTransport/ +gleio http://lei.info/gleio/ +somas http://sweetontology.net/matrSediment/ +soman http://sweetontology.net/matrAnimal/ +istex https://data.istex.fr/ontology/istex# +esbici http://vocab.ciudadesabiertas.es/def/transporte/bicicleta-publica# +soprocc http://sweetontology.net/procChemical/ +idsc https://w3id.org/idsa/code/ +mmms http://ldf.fi/schema/mmm/ +sostf http://sweetontology.net/stateFluid/ +sophatmol http://sweetontology.net/phenAtmoLightning/ +sophw http://sweetontology.net/phenWave/ +taxref http://taxref.mnhn.fr/lod/taxon/ +sophsyc http://sweetontology.net/phenSystemComplexity/ +sosttc http://sweetontology.net/stateTimeCycle/ +cci http://cookingbigdata.com/linkeddata/ccinstances# +sostre http://sweetontology.net/stateRealm/ +sostti http://sweetontology.net/stateTime/ +sophr http://sweetontology.net/phenReaction/ +sophatmofr http://sweetontology.net/phenAtmoFront/ +sophm http://sweetontology.net/phenMixing/ +ocsw http://data.diekb.org/def/ocsw# +soprocw http://sweetontology.net/procWave/ +schoi https://w3id.org/scholarlydata/ontology/indicators-ontology.owl# +atd https://data.nasa.gov/ontologies/atmonto/data# +sostsb http://sweetontology.net/stateSpectralBand/ +dbm http://purl.org/net/dbm/ontology# +somaio http://sweetontology.net/matrIon/ +sostrc http://sweetontology.net/stateRoleChemical/ +cbs http://betalinkeddata.cbs.nl/def/cbs# +sorepsg3 http://sweetontology.net/reprSpaceGeometry3D/ +sophatmops http://sweetontology.net/phenAtmoPressure/ +sostdp http://sweetontology.net/stateDataProcessing/ +sostsp http://sweetontology.net/stateSpace/ +sopropt http://sweetontology.net/propTemperature/ +soreptd http://sweetontology.net/reprTimeDay/ +soreaah http://sweetontology.net/realmAstroHelio/ +sophatmo http://sweetontology.net/phenAtmo/ +sostrb http://sweetontology.net/stateRoleBiological/ +lv2 http://lv2plug.in/ns/lv2core/ +ggbn http://data.ggbn.org/schemas/ggbn/terms/ +osmt https://wiki.openstreetmap.org/wiki/Key: +mbkeys https://pastebin.com/ThBfphb8# +sophfi http://sweetontology.net/phenFluidInstability/ +sohu http://sweetontology.net/human/ +cfrl http://linkeddata.finki.ukim.mk/lod/ontology/cfrl# +sostp http://sweetontology.net/statePhysical/ +ccomid http://www.ontologyrepository.com/CommonCoreOntologies/Mid/ +sophhe http://sweetontology.net/phenHelio/ +asio http://purl.org/hercules/asio/core# +sophen http://sweetontology.net/phenEnergy/ +pnv https://w3id.org/pnv# +wds http://www.wikidata.org/entity/statement/ +omop http://api.ohdsi.org/WebAPI/vocabulary/concept/ +sostef http://sweetontology.net/stateEnergyFlux/ +malaka http://george.gr/ +somapa http://sweetontology.net/matrParticle/ +sostst http://sweetontology.net/stateStorm/ +soreaer http://sweetontology.net/realmEarthReference/ +omim http://purl.bioontology.org/ontology/OMIM/ +rank http://www.ontotext.com/owlim/RDFRank# +sostss http://sweetontology.net/stateSpaceScale/ +sostro http://sweetontology.net/stateRole/ +sohueccont http://sweetontology.net/humanEnvirControl/ +compub https://sireneld.io/vocab/compub# +soreaofe http://sweetontology.net/realmOceanFeature/ +she http://shacleditor.org/ +sorepsmo http://sweetontology.net/reprSciModel/ +sophhy http://sweetontology.net/phenHydro/ +mobiliteit https://data.vlaanderen.be/ns/mobiliteit# +sophgt http://sweetontology.net/phenGeolTectonic/ +oplsoft http://www.openlinksw.com/ontology/software# +ccsla http://cookingbigdata.com/linkeddata/ccsla# +s4city https://saref.etsi.org/saref4city/ +io https://iaco.me/ +sorealv http://sweetontology.net/realmLandVolcanic/ +sopho http://sweetontology.net/phenOcean/ +sorealf http://sweetontology.net/realmLandFluvial/ +sohuc http://sweetontology.net/humanCommerce/ +somamic http://sweetontology.net/matrMicrobiota/ +sohuea http://sweetontology.net/humanEnvirAssessment/ +sorealg http://sweetontology.net/realmLandGlacial/ +sostsc http://sweetontology.net/stateSpaceConfiguration/ +gx https://graphite.synaptica.net/extension/ +soreaab http://sweetontology.net/realmAstroBody/ +sophgs http://sweetontology.net/phenGeolSeismicity/ +soall http://sweetontology.net/sweetAll/ +sorealt http://sweetontology.net/realmLandTectonic/ +gas http://www.bigdata.com/rdf/gas# +sophgg http://sweetontology.net/phenGeolGeomorphology/ +brot https://w3id.org/brot# +sohua http://sweetontology.net/humanAgriculture/ +iaco https://iaco.me/ +oco https://w3id.org/oc/ontology/ +say http://example.org/say/ +birthdate http://schema.org/birthDate/ +dfcb http://datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl# +docam https://www.docam.ca/glossaurus/ +atm https://data.nasa.gov/ontologies/atmonto/ATM# +arp http://www.arpenteur.org/ontology/Arpenteur.owl# +sophg http://sweetontology.net/phenGeol/ +sohud http://sweetontology.net/humanDecision/ +ei2a http://opendata.aragon.es/def/ei2a# +taxrefprop http://taxref.mnhn.fr/lod/property/ +sostsl http://sweetontology.net/stateSpectralLine/ +wasa http://vocab.sti2.at/wasa/ +dfc http://datafoodconsortium.org/ontologies/DFC_FullModel.owl# +soreala http://sweetontology.net/realmLandAeolian/ +sophgv http://sweetontology.net/phenGeolVolcano/ +ci https://privatealpha.com/ontology/content-inventory/1# +dd http://example.org/dummydata/ +osmrel https://www.openstreetmap.org/relation/ +s4agri https://saref.etsi.org/saref4agri/ +waa http://purl.oclc.org/NET/WebApiAuthentication# +fernanda http://fernanda.nl/ +fibo https://spec.edmcouncil.org/fibo/ontology/master/latest/ +uimo http://vocab.sti2.at/uimo/ +bs https://w3id.org/bs# +persoon http://data.vlaanderen.be/ns/persoon# +bperson http://data.vlaanderen.be/ns/persoon# +ld http://linkeddata.ru/ +trak https://trakmetamodel.sourceforge.io/vocab/rdf-schema.rdf# +saref4envi https://saref.etsi.org/saref4envi/ +s4ener https://saref.etsi.org/saref4ener/ +wotc http://purl.org/wot-catalogue# +sophgf http://sweetontology.net/phenGeolFault/ +sorea http://sweetontology.net/realm/ +osmnode https://www.openstreetmap.org/node/ +osmway https://www.openstreetmap.org/way/ +oplfeat http://www.openlinksw.com/ontology/features# +mgv http://mangaview.fr/mgv# +ogura https://sparql.crssnky.xyz/Ogura_Hyakunin_Isshu_LinkedRDF/URIs/Ogura_Hyakunin_Isshu_schema.ttl# +ccr http://cookingbigdata.com/linkeddata/ccregions# +knows http://semantic.komc/usu/2020/knows# +movieo http://movie.com/ontology/ +ldes https://w3id.org/ldes# +lexicog http://www.w3.org/ns/lemon/lexicog# +toaru https://metadata.moe/toaru-sparql/elements/ +gco http://purl.jp/bio/12/glyco/conjugate# +eppo https://gd.eppo.int/taxon/ +mpg123 https://devuan.net.br/wiki/mpg123/ +ebg http://data.businessgraph.io/ontology# +univ http://univ.io/ +jur http://sweet.jpl.nasa.gov/2.3/humanJurisdiction.owl# +dbonto http://dbepedia.org/ontology/ +motogp http://www.motogp.com/ +mr http://marineregions.org/ns/ontology# +bao http://www.bioassayontology.org/bao# +quran http://khalidaloufi.sa/quran# +srv http://www.daml.org/services/owl-s/1.2/Service.owl# +estraf http://vocab.ciudadesabiertas.es/def/transporte/trafico# +maroc http://fr.dbpedia.org/page/Maroc/ +cto https://w3id.org/cto# +mltd https://mltd.pikopikopla.net/mltd-schema# +cts http://rdf.cdisc.org/ct/schema# +hola https://moodle.insa-lyon.fr/course/view.php?id= +rl http://rl.com/resources/ +esconv http://vocab.ciudadesabiertas.es/def/sector-publico/convenio# +prismdb https://prismdb.takanakahiko.me/prism-schema.ttl# +kko http://kbpedia.org/kko/rc/ +melding http://lblod.data.gift/vocabularies/automatische-melding/ +pgxo http://pgxo.loria.fr/ +ble http://vocab.rapidthings.eu/ns/ble.ttl# +geodcat http://data.europa.eu/930/ +ams http://data.amadeus.com/ +marcgt https://id.loc.gov/vocabulary/marcgt/ +cso http://cso.kmi.open.ac.uk/schema/cso/ +ibeacon http://vocab.rapidthings.eu/ns/apple/ibeacon.ttl# +accid http://pid.accurids.com/ +contry http://dbpedia.org/resource/Lyon# +rdapol http://rdaregistry.info/termList/RDAPolarity/ +fx http://sparql.xyz/facade-x/ns/ +nsg https://neuroshapes.org/ +gom https://w3id.org/gom# +rdasource http://rdaregistry.info/termList/RDARecordingSources/ +sty http://purl.bioontology.org/ontology/STY/ +vlueprint https://vlueprint.org/schema/ +xyz http://sparql.xyz/facade-x/data/ +i18n https://www.w3.org/ns/i18n# +la https://linked.art/ns/terms/ +mdcs https://mdcs.monumentenkennis.nl/damageatlas/ontology# +karstlink https://ontology.uis-speleo.org/ontology/# +mag https://makg.org/property/ +rdaut http://rdaregistry.info/termList/RDAUnitOfTime/ +rdat http://rdaregistry.info/Elements/t/ +esautob http://vocab.ciudadesabiertas.es/def/transporte/autobus# +contax https://w3id.org/con-tax# +oeso http://www.opensilex.org/vocabularies/oeso# +dom https://html.spec.whatwg.org/# +tso https://w3id.org/tso# +w3id https://w3id.org/ +rdaio http://rdaregistry.info/Elements/i/object/ +ssnx http://purl.oclc.org/NET/ssnx/ssn# +bop https://w3id.org/bop# +vph http://purl.org/ozo/vph.owl# +hops https://rdf.ag/o/hops# +rdaep http://rdaregistry.info/termList/RDAExtensionPlan/ +datagc https://data.grottocenter.org/ldp/ +esempleo http://vocab.ciudadesabiertas.es/def/sector-publico/empleo# +w3geo http://www.w3.org/2003/01/geo/wgs84_pos# +rofchrda http://rdaregistry.info/termList/rofchrda/ +rpg http://rpg.data.is4.site/ +srr https://w3id.org/srr# +check http://pornhub.com/ +matrycs http://matrycs.com/ +rdaao http://rdaregistry.info/Elements/a/object/ +smithy https://awslabs.github.io/smithy/rdf-1.0# +itops https://vocab.eccenca.com/itops/ +kpd http://purl.org/kpd/ +samian http://lod.archaeology.link/data/samian/ +rdaxd http://rdaregistry.info/Elements/x/datatype/ +freq http://purl.org/cld/freq/ +slm http://urn.fi/URN:NBN:fi:au:slm: +mnx https://rdf.metanetx.org/schema/ +mesh2021 http://id.nlm.nih.gov/mesh/2021/ +rdatd http://rdaregistry.info/Elements/t/datatype/ +textgrid https://textgridrep.org/ +rdaed http://rdaregistry.info/Elements/e/datatype/ +rdamo http://rdaregistry.info/Elements/m/object/ +bdg http://data.bigdatagrapes.eu/resource/ontology/ +rdato http://rdaregistry.info/Elements/t/object/ +rdaid http://rdaregistry.info/Elements/i/datatype/ +bleadapter http://vocab.rapidthings.eu/ns/ble/adapter.ttl# +seasd https://w3id.org/seas/ +epcis https://ns.gs1.org/epcis/ +rdatb http://rdaregistry.info/termList/RDATypeOfBinding/ +sou http://qudt.org/vocab/sou/ +vr https://www.w3.org/2018/credentials/v1/ +rdan http://rdaregistry.info/Elements/n/ +memorix http://memorix.io/ontology# +lado http://archaeology.link/ontology# +rdand http://rdaregistry.info/Elements/n/datatype/ +cerealstoo http://rdf.ag/o/cerealstoo# +comp http://semweb.mmlab.be/ns/rml-compression# +signify http://purl.org/signify/ns# +rdaxo http://rdaregistry.info/Elements/x/object/ +oghamonto http://ontology.ogham.link/ +faas http://semantic-faas.com/ontology# +rdamd http://rdaregistry.info/Elements/m/datatype/ +m8g http://data.europa.eu/m8g/ +cinema http://www.semanticweb.org/julien/morgann/cinema# +rdano http://rdaregistry.info/Elements/n/object/ +rdawd http://rdaregistry.info/Elements/w/datatype/ +kdsf https://kerndatensatz-forschung.de/version1/technisches_datenmodell/owl/kdsf.owl# +idpo https://w3id.org/idpo# +rdatask http://rdaregistry.info/termList/RDATasks/ +arena https://solid.ti.rw.fau.de/public/ns/arena# +bcom https://w3id.org/bcom# +rdap http://rdaregistry.info/Elements/p/ +spec http://www.w3.org/ns/spec# +ogham http://lod.ogham.link/data/ +rdamat http://rdaregistry.info/termList/RDAMaterial/ +hpont https://w3id.org/hpont# +cbv https://ns.gs1.org/cbv/ +ch https://schema.ld.admin.ch/ +eurio http://data.europa.eu/s66# +oidc http://www.w3.org/ns/solid/oidc# +rdasca http://rdaregistry.info/termList/scale/ +rdapath http://rdaregistry.info/termList/RDARecordingMethods/ +citedcat https://w3id.org/citedcat-ap/ +folio http://IBCNServices.github.io/Folio-Ontology/Folio.owl# +nprl http://data.nobelprize.org/resource/laureate/ +mrk http://www.mydomain.org/Mrk-ns# +rdapd http://rdaregistry.info/Elements/p/datatype/ +rdawo http://rdaregistry.info/Elements/w/object/ +ofn http://www.ontotext.com/sparql/functions/ +paf https://paf.link/ +rofsfrda http://rdaregistry.info/termList/rofsfrda/ +biocrm http://ldf.fi/schema/bioc/ +rofitrda http://rdaregistry.info/termList/rofitrda/ +rdaim http://rdaregistry.info/termList/RDAInteractivityMode/ +luigiusai https://www.luigiusai.it/wp# +encargado http://semRAT.edu/ +roffgrda http://rdaregistry.info/termList/roffgrda/ +bcfowl http://lbd.arch.rwth-aachen.de/bcfOWL# +nanopub http://www.nanopub.org/nschema# +poke https://pokemonkg.org/ontology# +react https://w3id.org/react# +uberon http://purl.obolibrary.org/obo/UBERON_ +cpc https://data.epo.org/linked-data/def/cpc/ +eep https://w3id.org/eep# +bag2 http://bag.basisregistraties.overheid.nl/def/bag# +cpg http://modellingdh.github.io/ont/odp/pgc/ +aspect http://purl.org/aspect/ +ea http://eaontology.protect.linkeddata.es/def/ +rmlt http://semweb.mmlab.be/ns/rml-target# +lsqr http://lsq.aksw.org/ +ghga http://w3id.org/ghga/ +s223 http://data.ashrae.org/standard223# +aff https://w3id.org/affectedBy# +xmlns http://xmlns.com/foaf/0.1/ +djo http://purl.org/datajourneys/ +mrt http://marineregions.org/ns/placetypes# +gax http://w3id.org/gaia-x/core# +cgo https://www.tno.nl/agrifood/ontology/common-greenhouse-ontology# +setl http://purl.org/twc/vocab/setl/ +tci https://w3id.org/lbs/tci# +opltw http://www.openlinksw.com/schemas/twitter# +bau https://terminology.fraunhofer.de/voc/bau# +srmo https://w3id.org/srmo# +nsd https://w3id.org/nsd# +srtun https://www.inf.bi.rub.de/srtun# +hqdmontol http://www.semanticweb.org/magma-core/ontologies/hqdm# +srt http://w3id.org/srt# +generiek https://data.vlaanderen.be/ns/generiek# +ewg http://ethoinformatics.org/ +wfont https://w3id.org/wfont# +ontobras http://www.semanticweb.org/fefar/ontologies/ontobras# +ldpsc https://solid.ti.rw.fau.de/public/ns/stream-containers# +m4i http://w3id.org/nfdi4ing/metadata4ing# +olias http://purl.org/olia/system.owl# +interop http://www.w3.org/ns/solid/interop# +rc https://w3id.org/rc# +ppeer http://parliament.uk/ontologies/peerage/ +wdno http://www.wikidata.org/prop/novalue/ +walmart https://www.amazon.de/ +esc https://solid.ti.rw.fau.de/public/ns/event-sourcing-containers# +quid https://w3id.org/quid/ +rdaeo http://rdaregistry.info/Elements/e/object/ +edu https://schema.edu.ee/ +stix http://purl.org/cyber/stix# +paam https://lod.mediathek-tanz-theater.de/schema/paam/ +eb https://w3id.org/eb# +hqdm http://www.semanticweb.org/hqdm# +gufo http://purl.org/nemo/gufo# +caso http://www.w3id.org/def/caso# +raum https://terminology.fraunhofer.de/voc/raum# +lds https://solid.ti.rw.fau.de/public/ns/linked-data-structures# +jsonld http://www.w3.org/ns/json-ld# +magmardl http://www.semanticweb.org/magma-core/rdl# +dsd https://w3id.org/dsd# +godaddy https://sso.godaddy.com/ +lrcommon http://landregistry.data.gov.uk/def/common/ +asf https://www.stm-assoc.org/asf/ +marc http://www.loc.gov/MARC21/slim/ +kgi http://ns.inria.fr/kg/index# +magmauser http://www.semanticweb.org/magma-core/user# +feed https://www.feedipedia.org/ +hni https://collectiedata.hetnieuweinstituut.nl/ +ofo https://w3id.org/ofo# +archivo https://archivo.dbpedia.org/onto# +bdsubj https://purl.org/fidbaudigital/subjects# +osdu https://w3id.org/OSDU# +diso https://purls.helmholtz-metadaten.de/diso# +lbdserver https://w3id.org/lbdserver# +rto https://w3id.org/rail/topo# +conllu https://universaldependencies.org/format.html# +rdb http://www.dbs.cs.uni-duesseldorf.de/RDF/relational# +nomo https://nomenclature.info/nom/ontology/ +rro http://semanticweb.org/patricia/ontologies/rro# +value http://gfgfd.vs/ +tern http://w3id.org/tern/ontologies/tern/ +covido https://w3id.org/CovidO# +sds https://w3id.org/sds# +respond https://w3id.org/respond# +rsx http://rdf4j.org/shacl-extensions# +linkml https://w3id.org/linkml/ +chameo http://w3id.org/emmo-chameo/chameo# +stirdata https://w3id.org/stirdata/vocabulary/ +weki https://en.wikipedia.org/wiki/ +experts http://emmo.info/emmo/application/maeo/experts# +robotarm https://solid.ti.rw.fau.de/public/ns/robotArm# +nbo http://data.bioontology.org/ontologies/NBO/ +fpr http://www.filmstandards.org/schemas/filmportal_relations# +nom https://nomenclature.info/nom/ +oeo http://openenergy-platform.org/ontology/oeo/ +itcrdf http://www.w3.org/2005/11/its/rdf# +lbds https://w3id.org/lbdserver# +perscido https://perscido.univ-grenoble-alpes.fr/ +tro https://w3id.org/TRO/ +express https://w3id.org/express# +dmo https://w3id.org/dmo# +rsp http://www.researchspace.org/resource/ +cido http://purl.obolibrary.org/obo/cido.owl/ +pgo http://ii.uwb.edu.pl/pgo# +dsi https://data.dsi.omgeving.vlaanderen.be/ns/dsi# +chemrof https://w3id.org/chemrof/ +icon https://w3id.org/icon/ontology/ +rnce https://data.cultureelerfgoed.nl/id/rnce# +linkedart https://linked.art/ns/terms/ +tempo http://purl.org/tempo/ +rism http://rism.online/ +osmo https://purl.org/vimmp/osmo# +ultragaz https://ultragaz24horas.com/ +veelana http://onlyfans.com/veelana/ +dbd http://dbpedia.org/datatype/ +roh http://w3id.org/roh# +chess http://purl.org/NET/rdfchess/ontology/ +vntourism http://www.semanticweb.org/minhn/ontologies/2021/0/vntourism# +raad https://raadzaam.nl/schema/ +rtedurp http://purl.org/eduo/rtedurp/ +ttrpg https://w3id.org/TTRpg# +dqvno https://data.norge.no/vocabulary/dqvno# +iddo https://w3id.org/iddo# +era http://data.europa.eu/949/ +bp3 http://www.biopax.org/release/biopax-level3.owl# +gql http://www.openlinksw.com/schemas/graphql# +vl https://version.link/ +fso https://w3id.org/fso# +consolid https://w3id.org/consolid# +kokot http://www.koko.t/ +ammo http://ldf.fi/schema/ammo/ +pubchem https://pubchem.ncbi.nlm.nih.gov/ +ufo http://ufo.com/# +rcgs https://collection.rcgs.jp/terms/ +besluitvor https://data.vlaanderen.be/ns/besluitvorming# +mondo http://purl.obolibrary.org/obo/ +cvb http://rdfs.org/resume-rdf/base.rdfs# +film http://semantics.id/ns/example/film/ +iottta https://w3id.org/iot-tta# +grscicoll https://www.gbif.org/grscicoll/collection/ +nen2660 https://w3id.org/nen2660/def# +thub http://vocabularis.crai.ub.edu/thub/ +dcb http://dbpedia.org/resource/Category: +skosm http://www.w3.org/2004/02/skos/mapping# +apods http://activitypods.org/ns/core# +nalt https://lod.nal.usda.gov/nalt/ +koko https://seznam.cz/ +coy https://schema.coypu.org/global# +version https://version.link/ +yanice http://yanice-boady.webflow.io/ +bmp http://w3id.org/bmp# +dick http://pornhub.com/ +lib http://purl.org/library/ +vhbieo https://w3id.org/vhbieo# +dcatno https://data.norge.no/vocabulary/dcatno# +vcs https://data.vlaanderen.be/ns/chemische_stof# +ntp https://schema.finto.fi/ntp# +ceox https://linkeddata.cultureelerfgoed.nl/def/ceox# +fdp https://w3id.org/fdp/fdp-o# +crmsci http://cidoc-crm.org/crmsci/ +nutscode http://data.europa.eu/nuts/code/ +goavoc http://bio2rdf.org/goa_vocabulary: +hyr https://w3id.org/simulation/data/ +hmas https://purl.org/hmas/ +dbpg http://dbpedia.org/page/ +ncbi https://www.ncbi.nlm.nih.gov/ +lcnaf http://id.loc.gov/authorities/names/ +lis http://rds.posccaesar.org/ontology/lis14/rdl/ +coda http://art.uniroma2.it/coda/contracts/ +relation http://www.iana.org/assignments/relation/ +lol https://sbalot.github.io/lol/ +acp http://www.w3.org/ns/solid/acp# +ecfo https://w3id.org/ecfo# +epo http://data.europa.eu/a4g/ontology# +ags https://id.agschemas.org/ +plant http://example.org/plant/ +dcatap http://data.europa.eu/r5r/ +tsso https://scch.org/technical_standards# +fs https://www.compliancequest.com/training-management-software-system-solutions/ +peco https://w3id.org/peco# +coreo http://purl.org/coreo# +spatialf http://jena.apache.org/function/spatial# +atcc https://www.atcc.org/products/ +cur http://qudt.org/2.1/vocab/currency/ +aec3po https://w3id.org/lbd/aec3po/ +rb https://w3id.org/riverbench/schema/metadata# +doce http://purl.org/nemo/doce# +fdof https://w3id.org/fdof/ontology# +sure http://ns.inria.fr/sure# +mindat https://www.mindat.org/ +threat https://cve.mitre.org/ +oav http://lod.openaire.eu/vocab/ +coos http://id.unece.org/def/coos# +databus https://dataid.dbpedia.org/databus# +risk https://www.w3id.org/risk# +asb https://w3id.org/asbingowl/core# +ontouml https://w3id.org/ontouml# +egdo http://example.org/ +bacnet http://data.ashrae.org/bacnet/2020# +bsdd http://bsdd.buildingsmart.org/def# +iop https://w3id.org/iadopt/ont/ +quest https://rb.gy/ntg7l/ +hu https://mail.google.com/ +baf https://w3id.org/baf# +batmanont http://emmo.info/emmo/application/bmo# +docbook http://docbook.org/ns/docbook/ +p2po https://purl.org/p2p-o# +ontologia http://ub.edu/dades/ontologia/Cinema#Cinemes# +oplben http://www.openlinksw.com/ontology/benefits# +pit http://data.elsevier.com/vocabulary/ElsevierPubItemTypes/ +ksamsok http://kulturarvsdata.se/ksamsok# +fisa https://ifitkau.github.io/fisa/ +mi http://www.marineinfo.org/ns/ontology# +matmine http://materialsmine.org/ns/ +uio https://www.mitre.org/mparmelee/ontologies/2023/6/UserIntentOntology/ +notify http://www.w3.org/ns/solid/notifications# +mibc http://marineinfo.org/ns/library/bibcodes# +sense https://w3id.org/sense# +cpsvno http://data.norge.no/vocabulary/cpsvno# +imbor https://data.crow.nl/imbor/def/ +wrroc https://w3id.org/ro/terms/workflow-run# +rbdoc https://w3id.org/riverbench/schema/documentation# +ocmv https://w3id.org/ontouml-models/vocabulary# +quit http://quit.aksw.org/vocab/ +dde https://www.ddeworld.org/ +keyon http://keyelements.ltd/ontologies/keyon/# +cercabib https://cercabib.ub.edu/ +sssom https://w3id.org/sssom/ +ogcf http://www.opengis.net/def/function/geosparql/ +doam http://emmo.info/doam# +bioschemas https://bioschemas.org/ +stax https://w3id.org/stax/ontology# +skosno http://data.norge.no/skosno# +przecieki http://onlyfans.com/emiliaszymanska/ +emmo https://w3id.org/emmo# +bto http://w3id.org/emmo-bto/bto# +mibt https://marineinfo.org/ns/library/bibtypes# +maeo http://w3id.org/emmo-maeo/maeo# +ind https://w3id.org/inesdata# +olis http://olis.dev/ +semapv https://w3id.org/semapv/vocab/ +pbac https://w3id.org/pbac# +ies4 http://ies.data.gov.uk/ontology/ies4# +mifesto https://w3id.org/mifesto# +exekg https://raw.githubusercontent.com/nsai-uio/ExeKGOntology/main/ds_exeKGOntology.ttl# +mir http://marineinfo.org/ns/person/roles# +w3 http://www.w3.org/ +cergy https://dbpedia.org/page/Cergy/ +eurovoc http://eurovoc.europa.eu/ +guez http://guez.fr/ +ies http://ies.data.gov.uk/ontology/ies4# +into https://www.apluss.de/ontology/into# +plasma https://w3id.org/plasma# +iig https://w3id.org/iicongraph/data/ +miprog https://marineinfo.org/ns/progress# +sri https://w3id.org/sri# +hpo http://w3id.org/emmo-hpo/hpo# +hy https://api.hyprdia.com/ +uiot http://www.w3id.org/urban-iot/core# +pcp https://pcp-on-web.de/ontology/0.2/index-en.html# +soa https://semopenalex.org/ontology/ +oio http://www.geneontology.org/formats/oboInOwl# +deonta https://deonta.linkedmodel.org/deonta/ +ceosp https://linkeddata.cultureelerfgoed.nl/def/ceosp/ +cp http://schemas.openxmlformats.org/package/2006/metadata/core-properties/ +lpwc https://linkedpaperswithcode.com/property/ +ioc http://w3id.org/ioc# +htv http://www.w3.org/2011/http# +occupation http://nikunj.org/ontology/occupatioin# +loinc https://loinc.org/ +pwkso http://ns.inria.fr/pwkso/ +chpaf https://ch.paf.link/ +tsdcreq https://w3id.org/oseg/ont/tsdc/req# +okh https://w3id.org/oseg/ont/okh# +tdm http://www.w3.org/ns/tdmrep# +tsdc https://w3id.org/oseg/ont/tsdc/core# +osh https://w3id.org/oseg/ont/osh# +otrl https://w3id.org/oseg/ont/otrl# +spa https://paul.ti.rw.fau.de/~jo00defe/voc/spa# +aao http://purl.obolibrary.org/obo/AAO_ +ontohgis https://onto.kul.pl/ontohgis/ +firebim http://w3id.org/firebim# +spo https://w3id.org/steel/ProcessOntology/ +clyh http://purl.obolibrary.org/obo/ZP_ +lrm https://iflastandards.info/ns/lrm/lrmoo/ +envo http://purl.obolibrary.org/obo/ZP_ +oplmarket http://www.openlinksw.com/ontology/market# +kbmarc https://id.kb.se/marc/ +cwo http://kcoyle.net/cwo/ +ado http://purl.obolibrary.org/obo/ADO_ +clo http://purl.obolibrary.org/obo/ZP_ +dcid https://datacommons.org/browser/ +reloc https://w3id.org/reloc# +obi http://purl.obolibrary.org/obo/OBI_ +rxno http://purl.obolibrary.org/obo/ZP_ +sibo http://purl.obolibrary.org/obo/ZP_ +cacax http://cacax.fun/ +coswot https://w3id.org/coswot/ +crcr https://credit.niso.org/contributor-roles/ +dinto http://purl.obolibrary.org/obo/ZP_ +moont https://w3id.org/moont/ +obom https://w3id.org/open-bom/ont/open-bom# +gecko http://purl.obolibrary.org/obo/ZP_ +dpo http://purl.obolibrary.org/obo/FBcv_ +lpto http://w3id.org/lpto# +oplgit http://www.openlinksw.com/schemas/github# +bcgo http://purl.obolibrary.org/obo/ZP_ +sep http://purl.obolibrary.org/obo/ZP_ +htn http://purl.obolibrary.org/obo/ZP_ +txpo http://purl.obolibrary.org/obo/ZP_ +adw https://animaldiversity.org/accounts/ +ohd http://purl.obolibrary.org/obo/ZP_ +ypc http://www.semanticweb.org/sunsr/ontologies/2024/ypc# +mpio http://purl.obolibrary.org/obo/ZP_ +mfo http://purl.obolibrary.org/obo/ZP_ +ckg http://example.org/ckg# +omit http://purl.obolibrary.org/obo/OMIT_ +bspo http://purl.obolibrary.org/obo/BSPO_ +aimaix https://w3id.org/aimaix# +oix http://www.exemple.org/ontologia/ +ogi http://purl.obolibrary.org/obo/OGI_ +mbl https://w3id.org/mbl# +uo http://purl.obolibrary.org/obo/UO_ +zo https://linkeddata.cultureelerfgoed.nl/def/zo/ +oip http://www.exemple.org/ontologia/ +ontoavida http://purl.obolibrary.org/obo/ONTOAVIDA_ +sopharm http://purl.obolibrary.org/obo/SOPHARM_ +libeas https://w3id.org/libeas# +mop http://purl.obolibrary.org/obo/MOP_ +aix https://w3id.org/aix# +xlmod http://purl.obolibrary.org/obo/XLMOD_ +fovt http://purl.obolibrary.org/obo/FOVT_ +sepio http://purl.obolibrary.org/obo/SEPIO_ +phipo http://purl.obolibrary.org/obo/PHIPO_ +gramene http://www.gramene.org/db/ontology/search?id=GRO: +duo http://purl.obolibrary.org/obo/DUO_ +imr http://www.inoh.org/ontology-viewer/cgi-bin/InohOVAttr.php?type=IMR&id= +omo http://purl.obolibrary.org/obo/OMO_ +nmr https://www.ebi.ac.uk/ols4/ontologies/nmrcv/terms?short_form=NMR: +fro https://foundry.ai.mil/ontology/nas/fro/ +msl https://w3id.org/msl# +fypo http://purl.obolibrary.org/obo/FYPO_ +gallont http://purl.obolibrary.org/obo/GALLONT_ +credit https://credit.niso.org/ +zp http://purl.obolibrary.org/obo/ZP_ +meas https://graph.interoptx.org/meas/ +isoprops https://w3id.org/isoprops# +zfs http://purl.obolibrary.org/obo/ZFS_ +mco http://purl.obolibrary.org/obo/MCO_ +foodon http://purl.obolibrary.org/obo/FOODON_ +xco http://purl.obolibrary.org/obo/XCO_ +pgdso http://purl.obolibrary.org/obo/PGDSO_ +scdo http://purl.obolibrary.org/obo/SCDO_ +fbcv http://purl.obolibrary.org/obo/FBcv_ +ogsf http://purl.obolibrary.org/obo/OGSF_ +bila http://4dx.embl.de/4DXpress/reg/all/cview/gene.do?geneID= +loin http://w3id.org/loin# +psm https://paul.ti.rw.fau.de/~jo00defe/ont/psm# +cams https://graph.interoptx.org/cams/schema/ +cteno http://purl.obolibrary.org/obo/CTENO_ +zeco http://purl.obolibrary.org/obo/ZECO_ +t4fs http://purl.obolibrary.org/obo/T4FS_ +xpo http://purl.obolibrary.org/obo/XPO_ +oba http://purl.obolibrary.org/obo/OBA_ +gaz http://purl.obolibrary.org/obo/GAZ_ +stato http://purl.obolibrary.org/obo/STATO_ +cdno http://purl.obolibrary.org/obo/CDNO_ +ddanat http://purl.obolibrary.org/obo/DDANAT_ +micro http://purl.obolibrary.org/obo/MICRO_ +zfa http://purl.obolibrary.org/obo/ZFA_ +ceph http://purl.obolibrary.org/obo/CEPH_ +aism http://purl.obolibrary.org/obo/AISM_ +colao http://purl.obolibrary.org/obo/COLAO_ +poro http://purl.obolibrary.org/obo/PORO_ +ehda http://purl.obolibrary.org/obo/EHDA_ +dron http://purl.obolibrary.org/obo/DRON_ +spd http://purl.obolibrary.org/obo/SPD_ +opmi http://purl.obolibrary.org/obo/OPMI_ +symp http://purl.obolibrary.org/obo/SYMP_ diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfModel.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfModel.java new file mode 100644 index 00000000..7543f5e1 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfModel.java @@ -0,0 +1,355 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model; + +import cool.rdf.core.model.impl.DefaultRdfModel; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFParser; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.stream.Stream; + +public interface RdfModel extends Model { + String DEFAULT_EMPTY_PREFIX = "urn:cool-rdf:empty"; + + static RdfModel fromModel( final Model model ) { + return new DefaultRdfModel( model ); + } + + /** + * Parses a string containing an RDF document in a given syntax into a model + * + * @param document the string containing literal RDF (i.e., not a file name or URL) + * @param syntax the RDF syntax + * @return the loaded model + */ + static RdfModel fromDocument( final String document, final Lang syntax ) { + return fromDocument( new ByteArrayInputStream( document.getBytes( StandardCharsets.UTF_8 ) ), syntax ); + } + + /** + * Loads an RDF model in a given syntax from an input stream. The stream is not closed. + * + * @param input the input stream + * @param syntax the syntax + * @return the model + */ + static RdfModel fromDocument( final InputStream input, final Lang syntax ) { + return fromDocument( input, syntax, DEFAULT_EMPTY_PREFIX ); + } + + /** + * Loads an RDF model in a given syntax from an input stream, with a given base URI. The stream is not closed. + * + * @param input the input stream + * @param syntax the syntax + * @param base the base URI + * @return the model + */ + static RdfModel fromDocument( final InputStream input, final Lang syntax, final String base ) { + return fromModel( RDFParser.create() + .source( input ) + .lang( syntax ) + .base( base ) + .toModel() ); + } + + /** + * Parses a string containing an RDF/Turtle document into a model + * + * @param document the string containing literal RDF (i.e., not a file name or URL) + * @return the loaded model + */ + static RdfModel fromTurtle( final String document ) { + return fromDocument( document, Lang.TURTLE ); + } + + static RdfModel fromTurtle( final URI uri ) { + return fromDocument( uri, Lang.TURTLE ); + } + + static RdfModel fromDocument( final URI uri, final Lang syntax ) { + return fromDocument( uri, syntax, DEFAULT_EMPTY_PREFIX ); + } + + static RdfModel fromDocument( final URI uri, final Lang syntax, final String base ) { + return fromModel( RDFParser.create() + .source( uri.toString() ) + .lang( syntax ) + .base( base ) + .toModel() ); + } + + /** + * Similar to {@link Model#listSubjects()}}, list all resources which are subjects of statements. + *

+ * Subsequent operations on those resource may modify this model. + *

+ * + * @return a stream of resources which are subjects of statements + */ + Stream subjects(); + + /** + * Similar to {@link Model#listNameSpaces()}, list all namespaces used by predicates and types in the model. + * + * @return a stream of every predicate and type namespace + * @see org.apache.jena.shared.PrefixMapping + */ + Stream namespaces(); + + /** + * Similar to {@link Model#listResourcesWithProperty(Property)}, list all resources in this model that have the + * property. + * + * @param property the property + * @return a stream of resources with the property + */ + Stream resourcesWithProperty( Property property ); + + /** + * Similar to {@link Model#listResourcesWithProperty(Property, RDFNode)}, list all resources in this model that have + * the property with the object. + * + * @param property the property + * @param object the object + * @return a stream of resources with the property and the object + */ + Stream resourcesWithProperty( Property property, RDFNode object ); + + /** + * Similar to {@link Model#listObjects()}, list all objects in the model. + * + * @return a stream of all objects + */ + Stream objects(); + + /** + * Similar to {@link Model#listObjectsOfProperty(Property)}, list all objects of a given property + * + * @param property the property + * @return the stream of objects + */ + Stream objectsOfProperty( Property property ); + + /** + * Similar to {@link Model#listObjectsOfProperty(Resource, Property)}, list the values of a property of a resource. + * + * @param subject the resource + * @param property the property + * @return a stream of values of the property of the resource + */ + Stream objectsOfProperty( Resource subject, Property property ); + + /** + * Similar to {@link Model#listStatements()}, lists all statements in a model. + * + * @return a stream of statements + */ + Stream statements(); + + /** + * Similar to {@link Model#listStatements(Resource, Property, RDFNode)}, list all statements matching a pattern. The + * statements selected are those whose subject matches the subject argument, whose predicate matches + * the predicate argument and whose object matches the object argument. If an argument is + * null it matches anything. + *

+ * + * @param subject the subject of the pattern + * @param predicate the predicate of the pattern + * @param object the object of the pattern + * @return a stream of matching statements + */ + Stream statements( Resource subject, Property predicate, RDFNode object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, boolean)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, boolean object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, char)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, char object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, long)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, long object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, int)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, int object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, float)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, float object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listLiteralStatements(Resource, Property, double)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, double object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listStatements(Resource, Property, String)}, list statements + * with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, String object ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listStatements(Resource, Property, String, String)}, list + * statements with given subject, predicate and object values. + * + * @param subject the subject + * @param predicate the predicate + * @param object the object + * @param language the language code of the string + * @return a stream of matching statements + */ + Stream literalStatements( Resource subject, Property predicate, String object, String language ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, boolean)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, boolean o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, long)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, long o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, char)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, char o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, float)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, float o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, double)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, double o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listResourcesWithProperty(Property, Object)}, list the + * resources in this model which have value o' for property p, where o' is the type literal corresponding to o. + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, Object o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listSubjectsWithProperty(Property, String)}, list subjects + * with a given property and value + * + * @param p the property + * @param o the object + * @return a stream of matching resources + */ + Stream subjectsWithProperty( Property p, String o ); + + /** + * Similar to {@link org.apache.jena.rdf.model.ModelCon#listSubjectsWithProperty(Property, String, String)}, list + * subjects with a given property and value + * + * @param p the property + * @param o the object + * @param l the language tag of the string + * @return a stream of matching resources + */ + Stream resourcesWithProperty( Property p, String o, String l ); +} diff --git a/cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfNode.java similarity index 67% rename from cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java rename to cool-rdf-core/src/main/java/cool/rdf/core/model/RdfNode.java index 8d9fbf2a..7b28c67b 100644 --- a/cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfNode.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,8 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli; +package cool.rdf.core.model; -public class SystemExitCapturedException extends RuntimeException { - private static final long serialVersionUID = 6080552325336609875L; +import org.apache.jena.rdf.model.RDFNode; + +public interface RdfNode extends RDFNode { + // TODO: Add token information } diff --git a/cli/settings.gradle b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfPrefix.java similarity index 74% rename from cli/settings.gradle rename to cool-rdf-core/src/main/java/cool/rdf/core/model/RdfPrefix.java index 63a2731b..34c4a438 100644 --- a/cli/settings.gradle +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfPrefix.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,5 +14,10 @@ * limitations under the License. */ -rootProject.name = 'cli' -include ':diagram' +package cool.rdf.core.model; + +public interface RdfPrefix { + String prefix(); + + String uri(); +} diff --git a/settings.gradle b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfProperty.java similarity index 70% rename from settings.gradle rename to cool-rdf-core/src/main/java/cool/rdf/core/model/RdfProperty.java index b278086a..35f498dc 100644 --- a/settings.gradle +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -rootProject.name = 'owl-cli' -include ':diagram' -include ':write' -include ':infer' -include ':cli' -include ':docs' +package cool.rdf.core.model; + +import org.apache.jena.rdf.model.Property; + +public interface RdfProperty extends Property, RdfResource { +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfResource.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfResource.java new file mode 100644 index 00000000..fd869163 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfResource.java @@ -0,0 +1,27 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model; + +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.Resource; + +public interface RdfResource extends RdfNode, Resource { + Literal literalValue( Property property ); + + boolean isList(); +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfStatement.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfStatement.java new file mode 100644 index 00000000..9ddf298e --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/RdfStatement.java @@ -0,0 +1,28 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model; + +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Statement; + +public interface RdfStatement extends Statement { + RdfResource subject(); + + RdfProperty predicate(); + + RDFNode object(); +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfModel.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfModel.java new file mode 100644 index 00000000..f558a711 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfModel.java @@ -0,0 +1,183 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfModel; +import cool.rdf.core.model.RdfProperty; +import cool.rdf.core.model.RdfResource; +import cool.rdf.core.model.RdfStatement; +import lombok.experimental.Delegate; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; + +import java.util.stream.Stream; + +import static cool.rdf.core.util.IteratorStream.stream; + +public class DefaultRdfModel implements RdfModel { + private final @Delegate Model model; + + public DefaultRdfModel( final Model model ) { + this.model = model; + } + + private RdfResource mapResource( final Resource resource ) { + return new DefaultRdfResource( resource ); + } + + private RdfProperty mapProperty( final Property property ) { + return new DefaultRdfProperty( property ); + } + + private RDFNode mapResourceRdfNode( final RDFNode node ) { + return node.isResource() ? mapResource( node.asResource() ) : node; + } + + private RdfStatement mapResourcesInStatement( final Statement statement ) { + return new DefaultRdfStatement( createStatement( mapResource( statement.getSubject() ), mapProperty( statement.getPredicate() ), + mapResourceRdfNode( statement.getObject() ) ) ); + } + + @Override + public Stream subjects() { + return stream( listSubjects() ).map( this::mapResource ); + } + + @Override + public Stream namespaces() { + return stream( listNameSpaces() ); + } + + @Override + public Stream resourcesWithProperty( final Property property ) { + return stream( listResourcesWithProperty( property ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property property, final RDFNode object ) { + return stream( listResourcesWithProperty( property, object ) ).map( this::mapResource ); + } + + @Override + public Stream objects() { + return stream( listObjects() ).map( this::mapResourceRdfNode ); + } + + @Override + public Stream objectsOfProperty( final Property property ) { + return stream( listObjectsOfProperty( property ) ).map( this::mapResourceRdfNode ); + } + + @Override + public Stream objectsOfProperty( final Resource subject, final Property property ) { + return stream( listObjectsOfProperty( subject, property ) ).map( this::mapResourceRdfNode ); + } + + @Override + public Stream statements() { + return stream( listStatements() ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream statements( final Resource subject, final Property predicate, final RDFNode object ) { + return stream( listStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final boolean object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final char object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final long object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final int object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final float object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final double object ) { + return stream( listLiteralStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final String object ) { + return stream( listStatements( subject, predicate, object ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream literalStatements( final Resource subject, final Property predicate, final String object, + final String language ) { + return stream( listStatements( subject, predicate, object, language ) ).map( this::mapResourcesInStatement ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final boolean o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final long o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final char o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final float o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final double o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final Object o ) { + return stream( listResourcesWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream subjectsWithProperty( final Property p, final String o ) { + return stream( listSubjectsWithProperty( p, o ) ).map( this::mapResource ); + } + + @Override + public Stream resourcesWithProperty( final Property p, final String o, final String l ) { + return stream( listSubjectsWithProperty( p, o, l ) ).map( this::mapResource ); + } +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfNode.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfNode.java new file mode 100644 index 00000000..73f37830 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfNode.java @@ -0,0 +1,29 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfNode; +import lombok.experimental.Delegate; +import org.apache.jena.rdf.model.RDFNode; + +public class DefaultRdfNode implements RdfNode { + private final @Delegate RDFNode rdfNode; + + public DefaultRdfNode( final RDFNode rdfNode ) { + this.rdfNode = rdfNode; + } +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfPrefix.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfPrefix.java new file mode 100644 index 00000000..1ff12c93 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfPrefix.java @@ -0,0 +1,22 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfPrefix; + +public record DefaultRdfPrefix( String prefix, String uri ) implements RdfPrefix { +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfProperty.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfProperty.java new file mode 100644 index 00000000..37c04b10 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfProperty.java @@ -0,0 +1,30 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfProperty; +import lombok.experimental.Delegate; +import org.apache.jena.rdf.model.Property; + +public class DefaultRdfProperty extends DefaultRdfResource implements RdfProperty { + private final @Delegate Property property; + + public DefaultRdfProperty( final Property property ) { + super( property ); + this.property = property; + } +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfResource.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfResource.java new file mode 100644 index 00000000..770b5bf7 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfResource.java @@ -0,0 +1,62 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfResource; +import lombok.experimental.Delegate; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.shared.PropertyNotFoundException; +import org.apache.jena.vocabulary.RDF; + +import java.util.List; + +import static cool.rdf.core.util.IteratorStream.stream; + +public class DefaultRdfResource extends DefaultRdfNode implements RdfResource { + private final @Delegate Resource resource; + + public DefaultRdfResource( final Resource resource ) { + super( resource ); + this.resource = resource; + } + + public Statement property( final Property property ) { + final List statements = stream( listProperties( property ) ).toList(); + if ( statements.size() != 1 ) { + throw new PropertyNotFoundException( property ); + } + return statements.get( 0 ); + } + + @Override + public Literal literalValue( final Property property ) { + final RDFNode object = property( property ).getObject(); + if ( !object.isLiteral() ) { + throw new PropertyNotFoundException( property ); + } + return object.asLiteral(); + } + + @Override + public boolean isList() { + return resource.equals( RDF.Nodes.nil ) || ( resource.hasProperty( RDF.rest ) && resource.hasProperty( RDF.first ) ); + } +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfStatement.java b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfStatement.java new file mode 100644 index 00000000..b927af26 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/model/impl/DefaultRdfStatement.java @@ -0,0 +1,53 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.model.impl; + +import cool.rdf.core.model.RdfNode; +import cool.rdf.core.model.RdfProperty; +import cool.rdf.core.model.RdfResource; +import cool.rdf.core.model.RdfStatement; +import lombok.experimental.Delegate; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; + +public class DefaultRdfStatement implements RdfStatement { + private final @Delegate Statement statement; + + public DefaultRdfStatement( final Statement statement ) { + this.statement = statement; + } + + @Override + public RdfResource subject() { + final Resource resource = getResource(); + return resource instanceof final RdfResource rdfResource ? rdfResource : new DefaultRdfResource( resource ); + } + + @Override + public RdfProperty predicate() { + final Property property = getPredicate(); + return property instanceof final RdfProperty rdfProperty ? rdfProperty : new DefaultRdfProperty( property ); + } + + @Override + public RdfNode object() { + final RDFNode object = getObject(); + return object instanceof final RdfNode rdfNode ? rdfNode : new DefaultRdfNode( object ); + } +} diff --git a/cool-rdf-core/src/main/java/cool/rdf/core/util/IteratorStream.java b/cool-rdf-core/src/main/java/cool/rdf/core/util/IteratorStream.java new file mode 100644 index 00000000..f9c094f3 --- /dev/null +++ b/cool-rdf-core/src/main/java/cool/rdf/core/util/IteratorStream.java @@ -0,0 +1,28 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.core.util; + +import java.util.Iterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class IteratorStream { + public static Stream stream( final Iterator iterator ) { + return StreamSupport.stream( Spliterators.spliteratorUnknownSize( iterator, 0 ), false ); + } +} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java b/cool-rdf-core/src/main/java/cool/rdf/core/util/StringTemplate.java similarity index 73% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java rename to cool-rdf-core/src/main/java/cool/rdf/core/util/StringTemplate.java index 0351d43f..4db13402 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java +++ b/cool-rdf-core/src/main/java/cool/rdf/core/util/StringTemplate.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,19 +14,24 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.core.util; import java.util.Map; import java.util.function.Function; /** - * Minimalistic String template. The template string can contain references to (e.g. ${foo}) that are replaced - * with values on calling {@link #apply(Map)}. + * Minimalistic String template. The template string can contain references to (e.g. ${foo}) that are replaced with + * values on calling {@link #apply(Map)}. */ -public class Template implements Function, String> { +public class StringTemplate implements Function, String> { final private String template; - public Template( final String template ) { + /** + * Construct the template from the template string + * + * @param template the template string + */ + public StringTemplate( final String template ) { this.template = template; } diff --git a/cool-rdf-diagram-owl/pom.xml b/cool-rdf-diagram-owl/pom.xml new file mode 100644 index 00000000..39dfc86e --- /dev/null +++ b/cool-rdf-diagram-owl/pom.xml @@ -0,0 +1,100 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-diagram-owl + Cool RDF Diagram OWL + + + + + cool.rdf + cool-rdf-core + + + + + com.github.ben-manes.caffeine + caffeine + + + org.apache.commons + commons-text + + + com.google.guava + guava + + + net.sourceforge.owlapi + owlapi-distribution + + + org.slf4j + slf4j-simple + + + + + org.slf4j + slf4j-api + + + io.vavr + vavr + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/Configuration.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/Configuration.java new file mode 100644 index 00000000..320603f6 --- /dev/null +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/Configuration.java @@ -0,0 +1,169 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.diagram.owl; + +import lombok.Builder; + +/** + * The configuration that controls the visual output + */ +@Builder +public class Configuration { + /** + * The name (and possibly path) to the GraphViz dot binary + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String dotBinary = "dot"; + + /** + * The default font name + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String fontname = "Verdana"; + + /** + * The default font size + */ + @Builder.Default + public int fontsize = 12; + + /** + * The name of the font for nodes + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String nodeFontname = "Verdana"; + + /** + * The size of the font for nodes + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public int nodeFontsize = 12; + + /** + * The default node shape, see Node Shapes for the possible + * options + */ + @Builder.Default + public String nodeShape = "box"; + + /** + * The margin values to be used for shapes, see margin for + * syntax + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String nodeMargin = "0.05,0.0"; + + /** + * The style to use for nodes, see style for details + */ + @Builder.Default + public String nodeStyle = "rounded"; + + /** + * The background color for nodes + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String bgColor = "white"; + + /** + * The foreground color (lines and text) + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public String fgColor = "black"; + + /** + * The output format + */ + @Builder.Default + public Format format = Format.SVG; + + /** + * The diagram layout direction + */ + @SuppressWarnings( "CanBeFinal" ) + @Builder.Default + public LayoutDirection layoutDirection = LayoutDirection.LEFT_TO_RIGHT; + + /** + * The possible formats for diagram generation + */ + public enum Format { + /** + * PNG format + */ + PNG, + /** + * SVG format + */ + SVG; + + /** + * The file extension according to the format, e.g. "png" or "svg" + * + * @return the file extension + */ + public String getExtension() { + return toString().toLowerCase(); + } + + @Override + public String toString() { + return switch ( this ) { + case PNG -> "png"; + case SVG -> "svg"; + }; + } + } + + /** + * The possible directions in which the generated diagrams are aligned + */ + public enum LayoutDirection { + /** + * Diagrams are aligned vertically, with the root node on top + */ + TOP_TO_BOTTOM, + + /** + * Diagrams are aligned horizontally, with the root node on the left + */ + LEFT_TO_RIGHT, + + /** + * Check if the file contains the {@link #HINT_PREFIX} followed by either "top_to_bottom" or "left_to_right" + */ + DETECT; + + public static final String HINT_PREFIX = "#pragma diagram: "; + + @Override + public String toString() { + return switch ( this ) { + case TOP_TO_BOTTOM -> "top_to_bottom"; + case LEFT_TO_RIGHT -> "left_to_right"; + case DETECT -> "detect"; + }; + } + } +} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/DiagramGenerator.java similarity index 81% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/DiagramGenerator.java index 78899729..c5bef62d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/DiagramGenerator.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLOntologyMapper; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.OWLOntologyMapper; import io.vavr.control.Try; import org.apache.commons.io.IOUtils; import org.semanticweb.owlapi.model.OWLOntology; @@ -36,8 +36,8 @@ import java.util.stream.Stream; /** - * Main diagram generator class: Loads an ontology, initializes and calls the {@link GraphvizGenerator} to transform - * the ontology into a Graphviz document, writes the document to a file and calls the Graphviz (dot) binary. + * Main diagram generator class: Loads an ontology, initializes and calls the {@link GraphvizGenerator} to transform the + * ontology into a Graphviz document, writes the document to a file and calls the Graphviz (dot) binary. */ public class DiagramGenerator { private final OWLOntologyMapper ontologyMapper; @@ -51,7 +51,7 @@ public class DiagramGenerator { /** * Constructor. Initializes the Diagram generator with the necessary configuration. * - * @param configuration the configuration to provide to the Graphviz Genenerator + * @param configuration the configuration to provide to the Graphviz Generator * @param mappingConfig the mapping configuration to fine-tune the ontology mapping operation */ public DiagramGenerator( final Configuration configuration, final MappingConfiguration mappingConfig ) { @@ -68,10 +68,8 @@ private Try writeStreamToOutput( final InputStream in, final OutputStream } } - Try executeDot( final ThrowingConsumer contentProvider, - final OutputStream output, - final File workingDir, - final Configuration configuration ) { + Try executeDot( final ThrowingConsumer contentProvider, final OutputStream output, + final File workingDir, final Configuration configuration ) { final String command = configuration.dotBinary + " -T" + configuration.format.getExtension(); final Process process; try { @@ -90,7 +88,7 @@ Try executeDot( final ThrowingConsumer contentP !graphvizStderr.startsWith( "Warning:" ) && !graphvizStderr.contains( "Pango-WARNING" ) ) { LOG.debug( "Dot returned an error: {}", graphvizStderr ); - return Try.failure( new RuntimeException( "An error occured while running dot. This is most likely " + return Try.failure( new RuntimeException( "An error occurred while running dot. This is most likely " + "due to a bug in owl-cli. Captured message was: " + graphvizStderr ) ); } @@ -104,8 +102,8 @@ Try executeDot( final ThrowingConsumer contentP } final String svgOutput = new String( graphvizStdout, StandardCharsets.UTF_8 ); - return postprocess( svgOutput ).flatMap( processedOutput -> - writeStreamToOutput( processedOutput, output ).flatMap( writingResult -> { + return postProcess( svgOutput ).flatMap( processedOutput -> writeStreamToOutput( processedOutput, output ).flatMap( + writingResult -> { LOG.debug( "Writing to output {}", output ); try { process.waitFor(); @@ -119,7 +117,7 @@ Try executeDot( final ThrowingConsumer contentP } } - private Try postprocess( final String dotOutput ) { + private Try postProcess( final String dotOutput ) { return svgPostProcessors.stream().sequential().reduce( Function.identity(), Function::andThen ) .apply( Try.success( dotOutput ) ) .map( string -> IOUtils.toInputStream( string, StandardCharsets.UTF_8 ) ); @@ -129,22 +127,22 @@ private Try postprocess( final String dotOutput ) { * Performs diagram generation for an input ontology. The result is either written to a given {@link OutputStream} * or a given {@link Path}. * - * @param ontology the input ontology - * @param output the output to write + * @param ontology the input ontology + * @param output the output to write * @param configuration the configuration for the diagram generation * @return {@link io.vavr.control.Try.Success} on success */ public Try generate( final OWLOntology ontology, final OutputStream output, - final Configuration configuration ) { + final Configuration configuration ) { LOG.info( "Applying ontology mappers" ); - final Stream ontologyGraphRepresenation = ontologyMapper.apply( ontology ).stream(); + final Stream ontologyGraphRepresentation = ontologyMapper.apply( ontology ).stream(); LOG.info( "Generating Graphviz document" ); - final GraphvizDocument graphvizDocument = graphvizGenerator.apply( ontologyGraphRepresenation ); + final GraphvizDocument graphvizDocument = graphvizGenerator.apply( ontologyGraphRepresentation ); final String graphvizGraph = graphvizDocument.apply( configuration ); LOG.trace( "Generated Graphviz document: {}", graphvizGraph ); final ThrowingConsumer contentProvider = outputStream -> { - outputStream.write( graphvizGraph.getBytes() ); + outputStream.write( graphvizGraph.getBytes( StandardCharsets.UTF_8 ) ); outputStream.flush(); if ( outputStream != System.out ) { outputStream.close(); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/FontEmbedder.java similarity index 78% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/FontEmbedder.java index 00c4eeb4..fa0b19dd 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/FontEmbedder.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,32 +14,32 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.diagram.owl; import io.vavr.control.Try; import java.util.function.Function; /** - * SVG post processor that embeds the 'owlcli' font used for the element type and disjoint union symbols - * as a data URI. This is to make sure that the symbols are rendered the same in all browsers. + * SVG post processor that embeds the 'owlcli' font used for the element type and disjoint union symbols as a data URI. + * This is to make sure that the symbols are rendered the same in all browsers. */ +@SuppressWarnings( "SpellCheckingInspection" ) public class FontEmbedder implements Function, Try> { /* - * This is the encoded symbol font that contains exactly the glyphs used in the diagrams. - * The steps to obtain this are: - * 1. Install fonttools (pip3 install fonttools) to get the pyftsubset command - * 2. Create a template font from an existing font file that contains glyphs for the used code points: - * pyftsubset somefont.otf --output-file=owlcli.otf --unicodes-file=<(echo U+02B24 U+025AC U+025C6 U+026AC U+026AD) - * 3. Adjust the glyphs using fontforge, File->Generate Fonts... save as .woff - * 4. cat owlcli.woff | base64 -w 0 + * This is the encoded symbol font that contains exactly the glyphs used in the diagrams. The steps to obtain this + * are: 1. Install fonttools (pip3 install fonttools) to get the pyftsubset command 2. Create a template font from + * an existing font file that contains glyphs for the used code points: pyftsubset somefont.otf + * --output-file=owlcli.otf --unicodes-file=<(echo U+02B24 U+025AC U+025C6 U+026AC U+026AD) 3. Adjust the glyphs + * using fontforge, File->Generate Fonts... save as .woff 4. cat owlcli.woff | base64 -w 0 */ + // @formatter:off private final static String FONT = "d09GRk9UVE8AAAZMAAsAAAAACLAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAADoAAAAlQAAAKaAI5uDkZGVE0AAAYYAAAAHAAAABx0r+u3R0RFRgAABfQAAAAiAAAAJgAnACxPUy8yAAABaAAAAFkAAABg9/HsLGNtYXAAAANAAAAASQAAAVpVl0qpaGVhZAAAAQgAAAA2AAAANgNlIvdoaGVhAAABQAAAAB4AAAAkB74DJ2htdHgAAAY0AAAAGAAAABgRewDIbWF4cAAAAWAAAAAGAAAABgAGUABuYW1lAAABxAAAAXkAAAK76PMnInBvc3QAAAOMAAAAEwAAACD/hgAyAAEAAAGcOdvJNsGbXw889QALA+gAAAAAw95dmAAAAADa5EhmABT/PAPUAv0AAAAIAAIAAAAAAAB4nGNgZGBgbvlvwZDC/IIBCJivMDAyoAI2AGZuA+0AAAAAUAAABgAAeJxjYGFmZ5zAwMrAwNTFFMHAwHACQjO2MRgyMjGyMjGxMbOysDIxszCAQYICAxS4+4UqMBxQXaOtwqzw34IhhbmFUSeBkfH///9A3YeYpjEoACEjADatDvUAAAB4nHWRvU7DMBSFj/sThIQ6M1oMTG3kuFQqZQOUDkgdqGAvrZtGimrktKp4FF6CJ2BCTGw8By/AyIlr0Q6QyMefb659T64BtPACge0zwXtggUicBa7hQNwEruNEPAduMOcjcBNH4itwhKgWMVM0Drl687sqFsw5DVxDS1wEruNajAM3mPMauIlj8Rk4Yvwbl3RYwmAGCYslNYXj2mDM4ZBjjpjRK359xJOPZFhgxZiG4qvR/uXuHvf2uL/H57+ccOxYk4YY4W7Pw9x7qmpNA1X1H7AmWXJJb7iclGYm7VKmzpixcfk8llf28cnl2WIltVK6XWnXa89r3+t5pYnyquVwdOdPmNvlSk4pLn9Yr6wrWcJig4IeClaH3RTTgvMtDWa0UrCFjkuTrYsJIQ1WU28xY1b1izF/UmLg27w7bBtJ2KyOH9o3VPEQGkity4zUsZIDuS1KSHqdXkcrrf5xde+vrWRoe52KlRPOuDeuzNklFSfy770/vtlwygAAAHicY2BgYGaAYBkGRgYQCAHyGMF8FgYLIM3FwMHAxMCkukb1mNpabZX//xkYwOw1IPat0Fs2N8OvPITqhQJGNgZUgREIAOkpD9QAAAB4nGNgZgCD/80MRgxYAAAoRAG4AHicTZJNTxNRFIbvbQstpbZKHDbWdkQXaAVLUaNGE2MTiRtcKGjA2kyHoTOl05JpizGKC0z8uhtaIAghQEAggl/YYt2YEBb4A9z49Q+wBFl4pr2a2E6NunluzuJ97nmTg5HBgDDGxuiNMB+WENYhjFwqi9R9WK3Tqfv1KmOYolcLYj5ZYUeqzY7QTjvW77KjBrtOrkFVpYAN7UF16CByo2Y0jMbRdCDM8T2KwMe5SDAsaFOXxMnRSFciInmOc3z50aaA56i7sekcFxO62GiEPa8IwiVBkbobWW+096YiBcU463G7PYdLbNZ4TOMJjSdLbHJr9LAtrW2aoTsaibN8EYoUSMSjSqyxXPBPTYTwffwAP8SPMEGVpQo6VFMsION63GH9QmAT50O1sPmrhW4arT9SfVh1Ui8DFH5SCpQWWWGle+FeGrYzeC0D22n9hupjNj5+zsGBRcqKDadPuUTKzkO9I1BLbVtHwAhVuQ2oBvOhHDX76VmRXnBYt/4prmUAp8GX1q8VReWEI0tWxp7PvIiv9GeJ6f+8s49cudspS7PcmJ+YyjZnprb0v+MlWRiYuSOGejuJl1ycbV8WlNvyQA8xlfdxwldwMU/GF4eXis6/yzpvkeBgcGp5eXaVrJP12Krw2hSKMW/8o60kQToSPqlHnotnyHvybvrtsyWTFT4Uz6INTxUu6wsivGJggnIg0wU6QcOUp/N0EngagjmYhBDwMOewqt92588w/WNq+whcH62kkUFj0mImluqs+elQciT52GL5Xv0plRoZGrTs+A0JIyBEeJxjYGRgYOABYjEGOQYmBkYgZAViFqAIExAzQjAACKkAVAAAAAAAAQAAAADV7UW4AAAAAMPeXZgAAAAA2uRIZgJYAAAC+QAjAxQAIwIgADcDDgA3A+gAFA=="; + // @formatter:on - private final static String CSS_BLOCK = - ""; + private final static String CSS_BLOCK = ""; @Override public Try apply( final Try svgDocument ) { diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java similarity index 88% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java index 8e6ace27..3ef601fc 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.diagram.owl; import com.google.common.collect.ImmutableMap; +import cool.rdf.core.util.StringTemplate; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -36,13 +37,21 @@ @Getter @FieldDefaults( makeFinal = true, level = AccessLevel.PRIVATE ) public class GraphvizDocument implements Function { + /** + * A document containing no elements + */ public static final GraphvizDocument BLANK = new GraphvizDocument(); + /** + * The default configuration for rendering the document + */ public static final Configuration DEFAULT_CONFIGURATION = Configuration.builder().build(); - private static final Template GRAPHVIZ_TEMPLATE = new Template( """ + @SuppressWarnings( "SpellCheckingInspection" ) + private static final StringTemplate GRAPHVIZ_TEMPLATE = new StringTemplate( """ digraph G { rankdir = ${rankdir} + charset = "utf-8" bgcolor = "${bgcolor}" color = "${fgcolor}" @@ -101,11 +110,11 @@ GraphvizDocument merge( final GraphvizDocument other ) { .collect( Collectors.toList() ) ); } + @SuppressWarnings( "SpellCheckingInspection" ) @Override public String apply( final Configuration configuration ) { final Map templateMap = new ImmutableMap.Builder() - .put( "rankdir", configuration.layoutDirection == Configuration.LayoutDirection.TOP_TO_BOTTOM ? "TB" : - "LR" ) + .put( "rankdir", configuration.layoutDirection == Configuration.LayoutDirection.TOP_TO_BOTTOM ? "TB" : "LR" ) .put( "fontname", configuration.fontname ) .put( "fontsize", configuration.fontsize ) .put( "nodeFontname", configuration.nodeFontname ) @@ -130,7 +139,7 @@ public String toString() { '}'; } - record Statement(String content) { + record Statement( String content ) { String toFragment() { return content + "\n"; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java similarity index 80% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java index e81379c8..875ca9e4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,48 +14,49 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.diagram.owl; import com.google.common.collect.Ordering; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.GraphVisitor; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +import cool.rdf.core.util.StringTemplate; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.GraphVisitor; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.DisjointUnion; +import cool.rdf.diagram.owl.graph.node.Disjointness; +import cool.rdf.diagram.owl.graph.node.Equality; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.graph.node.Inequality; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.graph.node.Key; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.ObjectExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; +import cool.rdf.diagram.owl.graph.node.Rule; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; import org.apache.commons.text.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,17 +82,17 @@ public class GraphvizGenerator implements Function, Graphvi * * @param configuration the given configuration */ + @SuppressWarnings( "SpellCheckingInspection" ) GraphvizGenerator( final Configuration configuration ) { final Node.Visitor nodeTypeToGraphviz = new GraphvizNodeVisitor( configuration ); final Function decoratedEdgeToGraphviz = edge -> { final String label = edge.getLabel().getLabel(); - final String edgeStyle = - edgeTypeToGraphviz( edge.getType() ) - .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", - style, configuration.fontsize, configuration.fontname, configuration.fgColor, - configuration.fgColor ) ) - .orElse( "" ); + final String edgeStyle = edgeTypeToGraphviz( edge.getType() ) + .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", + style, configuration.fontsize, configuration.fontname, configuration.fgColor, + configuration.fgColor ) ) + .orElse( "" ); return GraphvizDocument.withEdge( new GraphvizDocument.Statement( String.format( "%s -> %s [label=\"%s\", %s]", escapeNodeId( edge.getFrom().getId() ), escapeNodeId( edge.getTo().getId() ), label, edgeStyle ) ) ); @@ -101,7 +102,7 @@ public class GraphvizGenerator implements Function, Graphvi final String edgeStyle = edgeTypeToGraphviz( edge.getType() ) .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", style, configuration.fontsize, configuration.fontname, configuration.fgColor, - configuration.fgColor ) ) + configuration.fgColor ) ) .orElse( "" ); return GraphvizDocument.withEdge( new GraphvizDocument.Statement( String.format( "%s -> %s [%s]", escapeNodeId( edge.getFrom().getId() ), @@ -131,18 +132,14 @@ private static String escapeNodeId( final Node.Id id ) { return id.getId().replace( "-", "_" ); } + @SuppressWarnings( "SpellCheckingInspection" ) private Optional edgeTypeToGraphviz( final Edge.Type type ) { return switch ( type ) { - case DEFAULT_ARROW: - yield Optional.of( "arrowhead = normal" ); - case DASHED_ARROW: - yield Optional.of( "arrowhead = normal, style = dashed" ); - case HOLLOW_ARROW: - yield Optional.of( "arrowhead = empty" ); - case DOUBLE_ENDED_HOLLOW_ARROW: - yield Optional.of( "dir = both, arrowhead = empty, arrowtail = empty" ); - case NO_ARROW: - yield Optional.of( "arrowhead = none" ); + case DEFAULT_ARROW -> Optional.of( "arrowhead = normal" ); + case DASHED_ARROW -> Optional.of( "arrowhead = normal, style = dashed" ); + case HOLLOW_ARROW -> Optional.of( "arrowhead = empty" ); + case DOUBLE_ENDED_HOLLOW_ARROW -> Optional.of( "dir = both, arrowhead = empty, arrowtail = empty" ); + case NO_ARROW -> Optional.of( "arrowhead = none" ); }; } @@ -170,11 +167,11 @@ private enum Symbol { INDIVIDUAL( "#874B82", "◆", 14 ), DATA_TYPE( "#AD3B45", "⬤", 12 ); - String color; + final String color; - String symbol; + final String symbol; - int symbolSize; + final int symbolSize; Symbol( final String color, final String symbol, final int symbolSize ) { this.color = color; @@ -183,31 +180,35 @@ private enum Symbol { } /** - * Returns a DOT fragement for an element with this symbol. Note that the referenced font 'owlcli' - * is injected during rendering using the {@link FontEmbedder}. + * Returns a DOT fragment for an element with this symbol. Note that the referenced font 'owlcli' is + * injected during rendering using the {@link FontEmbedder}. * - * @param elementName the name of the element + * @param elementName the name of the element * @param configuration the diagram generation configuration * @return the dot fragment for this element */ + @SuppressWarnings( "SpellCheckingInspection" ) String getNodeValue( final String elementName, final Configuration configuration ) { return String.format( "%s " + - "%s", + "%s", symbolSize, color, symbol, configuration.fontsize, configuration.fgColor, configuration.fontname, elementName ); } } - final Template literalNodeTemplate = new Template( """ + @SuppressWarnings( "TrailingWhitespacesInTextBlock" ) + final StringTemplate literalNodeTemplate = new StringTemplate( """ ${nodeId} [label="${value}"] """ ); - final Template htmlLabelNodeTemplate = new Template( """ + @SuppressWarnings( "TrailingWhitespacesInTextBlock" ) + final StringTemplate htmlLabelNodeTemplate = new StringTemplate( """ ${nodeId} [label=<${value}>] """ ); - final Template invisibleNodeTemplate = new Template( """ + @SuppressWarnings( { "TrailingWhitespacesInTextBlock", "SpellCheckingInspection" } ) + final StringTemplate invisibleNodeTemplate = new StringTemplate( """ ${nodeId} [label="", width="0", style="invis"] """ ); - Configuration configuration; + final Configuration configuration; GraphvizNodeVisitor( final Configuration configuration ) { this.configuration = configuration; @@ -294,6 +295,7 @@ public GraphvizDocument visit( final Union union ) { return generateHtmlLabelNode( union.getId(), "or" ); } + @SuppressWarnings( "SpellCheckingInspection" ) @Override public GraphvizDocument visit( final Disjointness disjointness ) { final String label = """ @@ -305,6 +307,7 @@ public GraphvizDocument visit( final Disjointness disjointness ) { return generateHtmlLabelNode( disjointness.getId(), label ); } + @SuppressWarnings( "SpellCheckingInspection" ) @Override public GraphvizDocument visit( final DisjointUnion disjointUnion ) { final String label = """ diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java similarity index 86% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java index 82b3318f..99609f3d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package cool.rdf.diagram.owl; /** * See {@link java.util.function.Consumer} @@ -29,6 +29,7 @@ public interface ThrowingConsumer { * Performs this operation on the given argument. * * @param t the input argument + * @throws E some exception */ void accept( T t ) throws E; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java similarity index 55% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java index 5534b04b..24f18b72 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package cool.rdf.diagram.owl.graph; import lombok.EqualsAndHashCode; import lombok.Value; @@ -23,25 +23,74 @@ * Sealed class that represents the types of edges in the graph */ public abstract class Edge implements GraphElement { + /** + * The type of edge + */ public enum Type { + /** + * Default filled black arrow, indicating default relation + */ DEFAULT_ARROW, + + /** + * Hollow tipped arrow, indicating inheritance + */ HOLLOW_ARROW, + + /** + * Double ended hollow tipped arrow, indicating equivalence + */ DOUBLE_ENDED_HOLLOW_ARROW, + + /** + * Dashed arrow, indicating implicit relation + */ DASHED_ARROW, + + /** + * Edge without arrows + */ NO_ARROW } private Edge() { } + /** + * Returns the "from" node + * + * @return the node + */ public abstract Node getFrom(); + /** + * Returns the "to" node + * + * @return the node + */ public abstract Node getTo(); - public abstract Edge.Type getType(); - + /** + * Returns the edge's type + * + * @return the type + */ + public abstract Type getType(); + + /** + * Returns a new edge with the "from" node updated to a new value + * + * @param newFromId the new "from" node id + * @return the new edge + */ public abstract Edge setFrom( Node newFromId ); + /** + * Returns a new edge with the "to" node updated to a new value + * + * @param newToId the new "to" node id + * @return the new edge + */ public abstract Edge setTo( Node newToId ); @Override @@ -54,11 +103,16 @@ public Edge asEdge() { return this; } + /** + * A plain edge (i.e., which does not have a label) + */ @Value @EqualsAndHashCode( callSuper = true ) public static class Plain extends Edge { Type type; + Node from; + Node to; @Override @@ -77,33 +131,78 @@ public T accept( final Visitor visitor ) { } } + /** + * An Edge with an attached label + */ @Value @EqualsAndHashCode( callSuper = true ) public static class Decorated extends Edge { + /** + * The possible labels + */ public enum Label { + /** + * Indicates an edge pointing to a class + */ CLASS( "C" ), + + /** + * Indicates an edge pointing to an object property + */ OBJECT_PROPERTY( "P" ), + + /** + * Indicates an edge pointing to a data property + */ DATA_PROPERTY( "P" ), + + /** + * Indicates an edge pointing to a (data) class + */ DATA_RANGE( "C" ), + + /** + * Indicates an edge pointing to an individual + */ INDIVIDUAL( "v" ), + + /** + * Indicates an edge pointing to a literal value + */ LITERAL( "v" ), + + /** + * Indicates an edge pointing to a given data range + */ RANGE( "range" ), + + /** + * Indicates an edge pointing to a given data domain + */ DOMAIN( "domain" ); - String label; + final String label; Label( final String label ) { this.label = label; } + /** + * Returns the label string + * + * @return the label string + */ public String getLabel() { return label; } } Type type; + Node from; + Node to; + Label label; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java similarity index 54% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java index 9788a419..b923991c 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package cool.rdf.diagram.owl.graph; import lombok.Getter; @@ -27,38 +27,87 @@ */ @Getter public class Graph { - Node node; - Stream otherElements; + final Node node; + final Stream otherElements; + + /** + * Builds a new graph from a given focus node and a number of other graph elements + * + * @param node the focus node + * @param otherElements the remaining graph elements + */ protected Graph( final Node node, final Stream otherElements ) { this.node = node; this.otherElements = otherElements; } + /** + * Builds a new graph from a given focus node and a number of other graph elements + * + * @param node the focus node + * @param otherElements the remaining graph elements + * @return the new graph + */ public static Graph of( final Node node, final Stream otherElements ) { return new Graph( node, otherElements ); } + /** + * Builds a new graph from a given focus node + * + * @param node the focus node + * @return the new graph + */ public static Graph of( final Node node ) { return new Graph( node, Stream.empty() ); } + /** + * Builds a new graph by merging this graph with the other graph. This graph's focus node becomes the constructed + * graph's focus node. + * + * @param other the other graph + * @return the new graph + */ public Graph and( final Graph other ) { return new Graph( node, Stream.concat( otherElements, other.toStream() ) ); } + /** + * Builds a new graph by merging another element with this graph's other elements. + * + * @param element the new element + * @return the new graph + */ public Graph and( final GraphElement element ) { return new Graph( node, Stream.concat( Stream.of( element ), otherElements ) ); } + /** + * Builds a new graph by merging a number of other elements with this graph's other elements. + * + * @param elements the new elements + * @return the new graph + */ public Graph and( final Stream elements ) { return new Graph( node, Stream.concat( otherElements, elements ) ); } + /** + * Turns this graph into a stream of graph elements + * + * @return the stream + */ public Stream toStream() { return Stream.concat( Stream.of( node ), otherElements ); } + /** + * Turns this graph into a set of graph elements + * + * @return the set + */ public Set getElementSet() { return toStream().collect( Collectors.toSet() ); } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java new file mode 100644 index 00000000..9ab03301 --- /dev/null +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java @@ -0,0 +1,134 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.diagram.owl.graph; + +import java.util.stream.Stream; + +/** + * An element of the graph + */ +public interface GraphElement { + /** + * Visitor for graph elements + * + * @param the visitor's return type + */ + interface Visitor { + /** + * Visit a plain edge + * + * @param edge the ege + * @return the visitor's return value + */ + T visit( Edge.Plain edge ); + + /** + * Visit a decorated edge + * + * @param decoratedEdge the ege + * @return the visitor's return value + */ + T visit( Edge.Decorated decoratedEdge ); + + /** + * Visit a node + * + * @param node the node + * @return the visitor's return value + */ + T visit( Node node ); + } + + /** + * Returns whether this graph element is an edge + * + * @return true if it is an edge + */ + default boolean isEdge() { + return false; + } + + /** + * Returns whether this graph element is a node + * + * @return true if is a node + */ + default boolean isNode() { + return false; + } + + /** + * Checks if this graph element is a certain type of subclass + * + * @param class_ the subclass + * @param the type of the subclass + * @return true if this is an instance of the class + */ + default boolean is( final Class class_ ) { + return class_.isAssignableFrom( getClass() ); + } + + /** + * Casts this graph element into a concrete subclass + * + * @param class_ the subclass + * @param the type of the subclass + * @return the cast object + */ + default T as( final Class class_ ) { + return class_.cast( this ); + } + + /** + * Returns a view to this graph element: A stream containing this object cast to the given subclass if possible, + * empty stream otherwise + * + * @param class_ the subclass + * @param the type of the subclass + * @return the stream + */ + default Stream view( final Class class_ ) { + return is( class_ ) ? Stream.of( as( class_ ) ) : Stream.empty(); + } + + /** + * Returns this graph element as a node + * + * @return the node + */ + default Node asNode() { + throw new UnsupportedOperationException(); + } + + /** + * Returns this graph element as an edge + * + * @return the edge + */ + default Edge asEdge() { + throw new UnsupportedOperationException(); + } + + /** + * Accepts a graph element visitor + * + * @param visitor the visitor + * @param the visitor's return type + * @return the visitor's return value + */ + T accept( Visitor visitor ); +} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java index d1bd2120..ce28cbcf 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package cool.rdf.diagram.owl.graph; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -23,7 +23,7 @@ import java.util.function.Function; /** - * Visitor for a elements of a graph + * Visitor for elements of a graph * * @param the result type of the visit operation */ @@ -31,7 +31,9 @@ @FieldDefaults( makeFinal = true, level = AccessLevel.PRIVATE ) public class GraphVisitor implements GraphElement.Visitor { Node.Visitor nodeTypeVisitor; + Function plainEdgeHandler; + Function decoratedEdgeHandler; @Override @@ -45,7 +47,7 @@ public T visit( final Edge.Decorated decoratedEdge ) { } @Override - public T visit( final Node nodeType ) { - return nodeType.accept( nodeTypeVisitor ); + public T visit( final Node node ) { + return node.accept( nodeTypeVisitor ); } } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java new file mode 100644 index 00000000..6af16378 --- /dev/null +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java @@ -0,0 +1,464 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.diagram.owl.graph; + +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.DisjointUnion; +import cool.rdf.diagram.owl.graph.node.Disjointness; +import cool.rdf.diagram.owl.graph.node.Equality; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.graph.node.Inequality; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.graph.node.Key; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.ObjectExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; +import cool.rdf.diagram.owl.graph.node.Rule; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.FieldDefaults; +import org.semanticweb.owlapi.model.IRI; + +import java.util.Optional; + +/** + * Sealed class that contains the different types of nodes of the ontology graph. + */ +@ToString +@EqualsAndHashCode +@FieldDefaults( makeFinal = true, level = AccessLevel.PRIVATE ) +@Getter +public abstract class Node implements GraphElement { + /** + * Visitor for the nodes + * + * @param the resulting type of the visit operation + */ + public interface Visitor { + /** + * Visit a class object + * + * @param class_ the object + * @return the visitor's return value + */ + T visit( Class class_ ); + + /** + * Visit a data property object + * + * @param dataProperty the data property + * @return the visitor's return value + */ + T visit( DataProperty dataProperty ); + + /** + * Visit an object property object + * + * @param objectProperty the object property + * @return the visitor's return value + */ + T visit( ObjectProperty objectProperty ); + + /** + * Visit an annotation property object + * + * @param annotationProperty the annotation property + * @return the visitor's return value + */ + T visit( AnnotationProperty annotationProperty ); + + /** + * Visit an OWL individual object + * + * @param individual the individual + * @return the visitor's return value + */ + T visit( Individual individual ); + + /** + * Visit a literal + * + * @param literal the literal + * @return the visitor's return value + */ + T visit( Literal literal ); + + /** + * Visit an object property chain + * + * @param propertyChain the property chain + * @return the visitor's return value + */ + T visit( PropertyChain propertyChain ); + + /** + * Visit a data type + * + * @param datatype the data type + * @return the visitor's return value + */ + T visit( Datatype datatype ); + + /** + * Visit an existential restriction + * + * @param existentialRestriction the restriction + * @return the visitor's return value + */ + T visit( ExistentialRestriction existentialRestriction ); + + /** + * Visit a value restriction + * + * @param valueRestriction the restriction + * @return the visitor's return value + */ + T visit( ValueRestriction valueRestriction ); + + /** + * Visit a universal restriction + * + * @param universalRestriction the restriction + * @return the visitor's return value + */ + T visit( UniversalRestriction universalRestriction ); + + /** + * Visit a class intersection + * + * @param intersection the intersection + * @return the visitor's return value + */ + T visit( Intersection intersection ); + + /** + * Visit a class union + * + * @param union the union + * @return the visitor's return value + */ + T visit( Union union ); + + /** + * Visit a disjointness axiom + * + * @param disjointness the axiom + * @return the visitor's return value + */ + T visit( Disjointness disjointness ); + + /** + * Visit a disjoint union axiom + * + * @param disjointUnion the axiom + * @return the visitor's return value + */ + T visit( DisjointUnion disjointUnion ); + + /** + * Visit a class inequality axiom + * + * @param inequality the axiom + * @return the visitor's return value + */ + T visit( Equality inequality ); + + /** + * Visit an inverse axiom + * + * @param inverse the axiom + * @return the visitor's return value + */ + T visit( Inverse inverse ); + + /** + * Visit a class inequality axiom + * + * @param inequality the axiom + * @return the visitor's return value + */ + T visit( Inequality inequality ); + + /** + * Visit a closed class axiom + * + * @param closedClass the axiom + * @return the visitor's return value + */ + T visit( ClosedClass closedClass ); + + /** + * Visit a complement axiom + * + * @param complement the axiom + * @return the visitor's return value + */ + T visit( Complement complement ); + + /** + * Visit a self axiom + * + * @param self the axiom + * @return the visitor's return value + */ + T visit( Self self ); + + /** + * Visit a minimal cardinality restriction + * + * @param objectMinimalCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectMinimalCardinality objectMinimalCardinality ); + + /** + * Visit a qualified minimal cardinality restriction + * + * @param objectQualifiedMinimalCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectQualifiedMinimalCardinality objectQualifiedMinimalCardinality ); + + /** + * Visit a maximal cardinality restriction + * + * @param objectMaximalCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectMaximalCardinality objectMaximalCardinality ); + + /** + * Visit a qualified maximal cardinality restriction + * + * @param objectQualifiedMaximalCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectQualifiedMaximalCardinality objectQualifiedMaximalCardinality ); + + /** + * Visit an exact cardinality restriction + * + * @param objectExactCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectExactCardinality objectExactCardinality ); + + /** + * Visit a qualified exact cardinality restriction + * + * @param objectQualifiedExactCardinality the restriction + * @return the visitor's return value + */ + T visit( ObjectQualifiedExactCardinality objectQualifiedExactCardinality ); + + /** + * Visit a data minimal cardinality restriction + * + * @param dataMinimalCardinality the restriction + * @return the visitor's return value + */ + T visit( DataMinimalCardinality dataMinimalCardinality ); + + /** + * Visit a data maximal cardinality restriction + * + * @param dataMaximalCardinality the restriction + * @return the visitor's return value + */ + T visit( DataMaximalCardinality dataMaximalCardinality ); + + /** + * Visit a data exact cardinality restriction + * + * @param dataExactCardinality the restriction + * @return the visitor's return value + */ + T visit( DataExactCardinality dataExactCardinality ); + + /** + * Visit an invisible node + * + * @param invisible the node + * @return the visitor's return value + */ + T visit( Invisible invisible ); + + /** + * Visit an IRI reference node + * + * @param iriReference the node + * @return the visitor's return value + */ + T visit( IRIReference iriReference ); + + /** + * Visit a property marker node + * + * @param propertyMarker the marker + * @return the visitor's return value + */ + T visit( PropertyMarker propertyMarker ); + + /** + * Visit a key node + * + * @param key the node + * @return the visitor's return value + */ + T visit( Key key ); + + /** + * Visit a rule node + * + * @param rule the node + * @return the visitor's return value + */ + T visit( Rule rule ); + } + + /** + * ID of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the ontology + * element that is represented by the node having this ID. + */ + @Getter + @EqualsAndHashCode + public static class Id { + final String id; + + final Optional iri; + + /** + * Constructs an ID from an internal identifier (id) and stores the IRI of the element identified by the Id + * + * @param id the internal identifier + * @param iri the IRI of the identified element + */ + public Id( final String id, final IRI iri ) { + this.id = id; + this.iri = Optional.of( iri ); + } + + /** + * Constructs an ID from an internal identifier + * + * @param id the id + */ + public Id( final String id ) { + this.id = id; + iri = Optional.empty(); + } + + @Override + public String toString() { + return "Id{" + "id='" + id + '\'' + ", iri=" + iri.map( IRI::toString ).orElse( "" ) + '}'; + } + } + + /** + * A node with a name + */ + public abstract static class NamedNode extends Node { + /** + * The name of this node + * + * @return the name + */ + public abstract String getName(); + } + + /** + * A node representing a cardinality + */ + public abstract static class CardinalityNode extends Node { + /** + * The cardinality + * + * @return the cardinality + */ + public abstract int getCardinality(); + } + + /** + * An invisible node (without label or border) + */ + public abstract static class InvisibleNode extends Node { + } + + @Override + public T accept( final GraphElement.Visitor visitor ) { + return visitor.visit( this ); + } + + /** + * The ID of this node + * + * @return the ID + */ + public abstract Id getId(); + + /** + * Accepts visitors following the visitor pattern + * + * @param visitor the visitor + * @param the visitor's return type + * @return the value returned by the visitor + */ + public abstract T accept( final Visitor visitor ); + + /** + * Constructs a copy of this node with a changed ID + * + * @param newId the new id + * @return the new node + */ + public abstract Node withId( Id newId ); + + @Override + public boolean isNode() { + return true; + } + + @Override + public Node asNode() { + return this; + } +} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java index d4273cfd..0302737f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class AnnotationProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java index e52fe4d0..1a0e5999 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class Class extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java index 1a7bce6c..36444240 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java index 68f148e6..df53a86e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java index 7b9afd58..e1f0efd0 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class DataExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java index 0d228dd2..e123ce2f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class DataMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java index 12e6a559..b5dc5d60 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class DataMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java index 5f98ff7a..46e15fc4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class DataProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java index 6ed541ff..0991c4e1 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class Datatype extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java index 137e20cb..fe6505b1 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java index 109cf3b2..a0c741cf 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java index d51b2d54..1285a3d4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java index 76aa457f..de318255 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java similarity index 68% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java index ef043e65..ac9f2dfe 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,25 +14,26 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.transformer.IriReferenceResolver; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; import org.semanticweb.owlapi.model.IRI; /** - * Represents a reference to some yet unknown other graph that has a {@link Node.Id} with a given {@link IRI}. - * This type of node should never end up in the final graph, as it is resolved by the - * {@link de.atextor.owlcli.diagram.graph.transformer.IriReferenceResolver} after the Axiom -> Graph Elements mapping - * is done. + * Represents a reference to some yet unknown other graph that has a {@link Node.Id} with a given {@link IRI}. This type + * of node should never end up in the final graph, as it is resolved by the {@link IriReferenceResolver} after the Axiom + * -> Graph Elements mapping is done. */ @Value @EqualsAndHashCode( callSuper = true ) @With public class IRIReference extends Node.InvisibleNode { Id id; + IRI iri; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java index db456bdd..7efde5f4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class Individual extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java index f686c266..1541a331 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java index 16da01fc..483e95fa 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java index a4f03027..c738beaf 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java index 1d29029b..7930c1a4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java index 188286f1..144fcd2e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java index 3e10e0b5..30ab010b 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class Literal extends Node { Id id; + String value; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java index 313d7a92..813d0609 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java index d94ba38d..41b4b036 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java index b6f85c29..40eb0ef7 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java index 9fe21265..2e518d47 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java index 0eb160c7..5f181352 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectQualifiedExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java index 68f559c2..98c5d1aa 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectQualifiedMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java index 263a569c..70b3ee6b 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -29,6 +29,7 @@ @With public class ObjectQualifiedMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java similarity index 78% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java index edbcda2e..b2be1b17 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -28,9 +28,13 @@ @EqualsAndHashCode( callSuper = true ) @With public class PropertyChain extends Node { + /** + * The symbol that represents property chains when they are rendered to strings + */ public static final String OPERATOR_SYMBOL = "o"; Id id; + String value; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java similarity index 57% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java index 65ab285d..c03dafe4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -24,24 +24,55 @@ import java.util.Set; /** - * Represents a property marker node in the graph, i.e. a node that contains the list of attributes that a given - * OWL Object Property or OWL Data Property has. + * Represents a property marker node in the graph, i.e. a node that contains the list of attributes that a given OWL + * Object Property or OWL Data Property has. */ @Value @EqualsAndHashCode( callSuper = true ) @With public class PropertyMarker extends Node { + /** + * The various kinds of markers + */ public enum Kind { + /** + * The marked property is functional + */ FUNCTIONAL, + + /** + * The marked property is inverse functional + */ INVERSE_FUNCTIONAL, + + /** + * The marked property is transitive + */ TRANSITIVE, + + /** + * The marked property is symmetric + */ SYMMETRIC, + + /** + * The marked property is asymmetric + */ ASYMMETRIC, + + /** + * The marked property is reflexive + */ REFLEXIVE, + + /** + * The marked property is irreflexive + */ IRREFLEXIVE } Id id; + Set kind; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java similarity index 72% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java index 9b2a56cc..bc554344 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -28,10 +28,18 @@ @EqualsAndHashCode( callSuper = true ) @With public class Rule extends Node { + /** + * The symbol that represents conjunctions in rules when they are rendered to strings + */ public static final String CONJUNCTION_SYMBOL = "∧"; + + /** + * The symbol that represents implication in rules when they are rendered to strings + */ public static final String IMPLICATION_SYMBOL = "⇒"; Id id; + String value; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java similarity index 75% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java index 2e72846e..86d834ac 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; /** - * Represents a OWL Object Property self restriction symbol ("self") node in the graph. + * Represents an OWL Object Property self restriction symbol ("self") node in the graph. */ @Value @EqualsAndHashCode( callSuper = true ) diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java index 472b33b8..b5be451f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java index 60e4e6ab..781e1b02 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java index 7805d6f4..ac922c44 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package cool.rdf.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java similarity index 81% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java index 6de85a9d..68e7182e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,24 +14,19 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package cool.rdf.diagram.owl.graph.transformer; import com.google.common.collect.Sets; -import de.atextor.owlcli.diagram.graph.GraphElement; -import lombok.Value; +import cool.rdf.diagram.owl.graph.GraphElement; import java.util.Set; /** * Represents additions and deletions to perform on a set of {@link GraphElement}s */ -@Value -class ChangeSet { +record ChangeSet( Set additions, Set deletions ) { public static final ChangeSet EMPTY = new ChangeSet( Set.of(), Set.of() ); - Set additions; - Set deletions; - /** * Create a new ChangeSet from this and another given ChangeSet * diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java similarity index 62% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java index ced12b8a..abd1f9a9 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package cool.rdf.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; import java.util.Set; @@ -31,6 +31,13 @@ * Base class for graph transformations */ public abstract class GraphTransformer implements UnaryOperator> { + /** + * Finds the nodes in a graph that have a given IRI + * + * @param graph the graph + * @param iri the IRI to look for + * @return the resulting nodes + */ protected Stream findNodesWithIri( final Set graph, final IRI iri ) { return graph.stream() .filter( GraphElement::isNode ) @@ -38,18 +45,34 @@ protected Stream findNodesWithIri( final Set graph, final IR .filter( node -> node.getId().getIri().map( nodeIri -> nodeIri.equals( iri ) ).orElse( false ) ); } + /** + * Calculates a {@link ChangeSet} for a given graph in which all edges pointing to a given node are instead now + * pointing to a diffent node + * + * @param graph the graph + * @param oldToNode the old node + * @param newToNode the new node + * @return the change set + */ protected ChangeSet updateEdgesTo( final Set graph, final Node oldToNode, final Node newToNode ) { return updateEdge( graph, oldToNode, newToNode, Edge::getTo, Edge::setTo ); } - protected ChangeSet updateEdgesFrom( final Set graph, final Node oldFromNode, - final Node newFromNode ) { + /** + * Calculates a {@link ChangeSet} for a given graph in which all edges outgoing from a given node are instead now + * outgoing from a different node + * + * @param graph the graph + * @param oldFromNode the old node + * @param newFromNode the new node + * @return the change set + */ + protected ChangeSet updateEdgesFrom( final Set graph, final Node oldFromNode, final Node newFromNode ) { return updateEdge( graph, oldFromNode, newFromNode, Edge::getFrom, Edge::setFrom ); } private ChangeSet updateEdge( final Set graph, final Node oldNode, final Node newNode, - final Function getter, - final BiFunction setter ) { + final Function getter, final BiFunction setter ) { return graph.stream() .filter( GraphElement::isEdge ) .map( GraphElement::asEdge ) diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java index 7a06e818..24c9464c 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package cool.rdf.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.node.Literal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,9 +29,9 @@ import java.util.stream.Stream; /** - * Implements a graph transformation that removes all nodes of type {@link IRIReference} from a graph and - * replaces them with the corresponding direct links to the referenced nodes where possible, and with literal - * nodes representing the reference IRI otherwise + * Implements a graph transformation that removes all nodes of type {@link IRIReference} from a graph and replaces them + * with the corresponding direct links to the referenced nodes where possible, and with literal nodes representing the + * reference IRI otherwise */ public class IriReferenceResolver extends GraphTransformer { private final MappingConfiguration mappingConfiguration; @@ -51,7 +51,7 @@ public IriReferenceResolver( final MappingConfiguration mappingConfiguration ) { * Apply this transformer to the given input graph * * @param graph the input graph - * @return the resulting graph that contains no {@link IRIReference}s any more + * @return the resulting graph that contains no {@link IRIReference}s anymore */ @Override public Set apply( final Set graph ) { diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java similarity index 81% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java index 792e3ecb..2ce5e41f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package cool.rdf.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; import io.vavr.Tuple2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,8 +31,8 @@ import java.util.stream.Stream; /** - * Implements a graph transformer that merges multiple {@link PropertyMarker}s on a given Object property - * or Data Property into one Property Marker + * Implements a graph transformer that merges multiple {@link PropertyMarker}s on a given Object property or Data + * Property into one Property Marker */ public class PropertyMarkerMerger extends GraphTransformer { private final MappingConfiguration mappingConfiguration; @@ -63,10 +63,9 @@ private Optional markerByEdge( final Set graph, fi } private ChangeSet mergePropertyMarkers( final Set> propertyMarkers ) { - final Set mergedKindSet = - propertyMarkers.stream().flatMap( marker -> marker._2().getKind().stream() ).collect( Collectors.toSet() ); - final PropertyMarker newMarker = - new PropertyMarker( mappingConfiguration.getIdentifierMapper().getSyntheticId(), mergedKindSet ); + final Set mergedKindSet = propertyMarkers.stream().flatMap( marker -> marker._2().getKind().stream() ).collect( + Collectors.toSet() ); + final PropertyMarker newMarker = new PropertyMarker( mappingConfiguration.getIdentifierMapper().getSyntheticId(), mergedKindSet ); final Edge newEdge = propertyMarkers.iterator().next()._1().setTo( newMarker ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java similarity index 81% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java index 7f6bea47..8c459365 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package cool.rdf.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,9 +29,9 @@ /** * Implements a graph transformer that resolves - * Punning in a graph: An input ontology that - * uses punning for e.g. an individual and a class results in a graph that contains both the individual and the class - * as nodes, but both share the same {@link Node.Id}, as it is derived from the the element's + * Punning in a graph: An input ontology that uses + * punning for e.g. an individual and a class results in a graph that contains both the individual and the class as + * nodes, but both share the same {@link Node.Id}, as it is derived from the element's * {@link org.semanticweb.owlapi.model.IRI}. This transformer replaces the nodes with new, uniquely identified nodes * (that keep the original IRI in their IDs) and updates all edges in the graph accordingly. */ @@ -58,6 +58,7 @@ public PunningRemover( final MappingConfiguration mappingConfiguration ) { @Override public Set apply( final Set graph ) { LOG.debug( "Removing punning in {}", graph ); + @SuppressWarnings( "OptionalGetWithoutIsPresent" ) final Set result = graph.stream() .filter( GraphElement::isNode ) .map( GraphElement::asNode ) @@ -81,8 +82,7 @@ private Stream updateNode( final Set graph, final Node } private Node.Id buildNewNodeId( final Node.Id original ) { - return original.getIri().map( iri -> - mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) + return original.getIri().map( iri -> mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) .orElseGet( () -> mappingConfiguration.getIdentifierMapper().getSyntheticId() ); } } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java similarity index 87% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java index ef644754..2af38443 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; import java.util.UUID; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java similarity index 80% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java index 42c101c1..74a78a7f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.printers.OWLClassExpressionPrinter; -import de.atextor.owlcli.diagram.printers.OWLDataPrinter; -import de.atextor.owlcli.diagram.printers.OWLIndividualPrinter; -import de.atextor.owlcli.diagram.printers.OWLPropertyExpressionPrinter; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.printers.OWLClassExpressionPrinter; +import cool.rdf.diagram.owl.printers.OWLDataPrinter; +import cool.rdf.diagram.owl.printers.OWLIndividualPrinter; +import cool.rdf.diagram.owl.printers.OWLPropertyExpressionPrinter; import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; import org.semanticweb.owlapi.model.OWLAnnotationSubjectVisitorEx; import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; @@ -34,22 +34,40 @@ import java.util.Optional; +/** + * Default implementation for {@link MappingConfiguration} + */ public class DefaultMappingConfiguration implements MappingConfiguration { private OWLAxiomVisitorEx owlAxiomMapper; + private OWLClassExpressionVisitorEx owlClassExpressionMapper; + private OWLIndividualVisitorEx owlIndividualMapper; + private OWLPropertyExpressionVisitorEx owlPropertyExpressionMapper; + private OWLObjectVisitorEx owlObjectMapper; + private OWLDataVisitorEx owlDataMapper; + private OWLEntityVisitorEx owlEntityMapper; + private OWLAnnotationObjectVisitorEx owlAnnotationObjectMapper; + private OWLAnnotationSubjectVisitorEx owlAnnotationSubjectMapper; + private SWRLObjectVisitorEx swrlObjectMapper; + private IdentifierMapper identifierMapper; + private NameMapper nameMapper; + private OWLDataVisitorEx owlDataPrinter; + private OWLPropertyExpressionVisitorEx owlPropertyExpressionPrinter; + private OWLIndividualVisitorEx owlIndividualPrinter; + private OWLClassExpressionVisitorEx owlClassExpressionPrinter; private DefaultMappingConfiguration() { @@ -171,7 +189,7 @@ private void setOwlAnnotationSubjectMapper( final OWLAnnotationSubjectVisitorEx< this.owlAnnotationSubjectMapper = owlAnnotationSubjectMapper; } - public void setSwrlObjectMapper( final SWRLObjectVisitorEx swrlObjectMapper ) { + private void setSwrlObjectMapper( final SWRLObjectVisitorEx swrlObjectMapper ) { this.swrlObjectMapper = swrlObjectMapper; } @@ -199,108 +217,233 @@ private void setOwlClassExpressionPrinter( final OWLClassExpressionVisitorEx> owlAxiomMapper = Optional.empty(); + private Optional> owlClassExpressionMapper = Optional.empty(); + private Optional> owlIndividualMapper = Optional.empty(); + private Optional> owlPropertyExpressionMapper = Optional.empty(); + private Optional> owlObjectMapper = Optional.empty(); + private Optional> owlDataMapper = Optional.empty(); + private Optional> owlEntityMapper = Optional.empty(); + private Optional> owlAnnotationObjectMapper = Optional.empty(); + private Optional> owlAnnotationSubjectMapper = Optional.empty(); + private Optional> swrlObjectMapper = Optional.empty(); + private Optional identifierMapper = Optional.empty(); + private Optional nameMapper = Optional.empty(); + private Optional> owlDataPrinter = Optional.empty(); + private Optional> owlPropertyExpressionPrinter = Optional.empty(); + private Optional> owlIndividualPrinter = Optional.empty(); + private Optional> owlClassExpressionPrinter = Optional.empty(); + /** + * Sets the OWL axiom mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlAxiomMapper( final OWLAxiomVisitorEx mapper ) { owlAxiomMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL class expression mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlClassExpressionMapper( final OWLClassExpressionVisitorEx mapper ) { owlClassExpressionMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL individual mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlIndividualMapper( final OWLIndividualVisitorEx mapper ) { owlIndividualMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL property expression mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlPropertyExpressionMapper( final OWLPropertyExpressionVisitorEx mapper ) { owlPropertyExpressionMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL object mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlObjectMapper( final OWLObjectVisitorEx mapper ) { owlObjectMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL data mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlDataMapper( final OWLDataVisitorEx mapper ) { owlDataMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL entity mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlEntityMapper( final OWLEntityVisitorEx mapper ) { owlEntityMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL annotation object mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlAnnotationObjectMapper( final OWLAnnotationObjectVisitorEx mapper ) { owlAnnotationObjectMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL annotation subject mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder owlAnnotationSubjectMapper( final OWLAnnotationSubjectVisitorEx mapper ) { owlAnnotationSubjectMapper = Optional.of( mapper ); return this; } + /** + * Sets the SWRL object mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder swrlObjectMapper( final SWRLObjectVisitorEx mapper ) { swrlObjectMapper = Optional.of( mapper ); return this; } + /** + * Sets the identifier mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder identifierMapper( final IdentifierMapper mapper ) { identifierMapper = Optional.of( mapper ); return this; } + /** + * Sets the name mapper + * + * @param mapper the mapper + * @return the builder + */ public Builder nameMapper( final NameMapper mapper ) { nameMapper = Optional.of( mapper ); return this; } + /** + * Sets the OWL data printer + * + * @param printer the printer + * @return the builder + */ public Builder owlDataPrinter( final OWLDataVisitorEx printer ) { owlDataPrinter = Optional.of( printer ); return this; } + /** + * Sets the OWL property expression printer + * + * @param printer the printer + * @return the builder + */ public Builder owlPropertyExpressionPrinter( final OWLPropertyExpressionVisitorEx printer ) { owlPropertyExpressionPrinter = Optional.of( printer ); return this; } + /** + * Sets the OWL individual printer + * + * @param printer the printer + * @return the builder + */ public Builder owlIndividualPrinter( final OWLIndividualVisitorEx printer ) { owlIndividualPrinter = Optional.of( printer ); return this; } + /** + * Sets the OWL class expression printer + * + * @param printer the printer + * @return the builder + */ public Builder owlClassExpressionPrinter( final OWLClassExpressionVisitorEx printer ) { owlClassExpressionPrinter = Optional.of( printer ); return this; } + /** + * Builds the mapping configuration using set values, otherwise with default values + * + * @return the mapping configuration + */ public MappingConfiguration build() { final DefaultMappingConfiguration mappingConfig = new DefaultMappingConfiguration(); @@ -321,7 +464,7 @@ public MappingConfiguration build() { mappingConfig .setSwrlObjectMapper( swrlObjectMapper.orElseGet( () -> new SWRLObjectMapper( mappingConfig ) ) ); mappingConfig.setIdentifierMapper( identifierMapper.orElseGet( DefaultIdentifierMapper::new ) ); - mappingConfig.setNameMapper( nameMapper.orElseGet( () -> new DefaultNameMapper( mappingConfig ) ) ); + mappingConfig.setNameMapper( nameMapper.orElseGet( DefaultNameMapper::new ) ); mappingConfig.setOwlDataPrinter( owlDataPrinter.orElseGet( () -> new OWLDataPrinter( mappingConfig ) ) ); mappingConfig.setOwlPropertyExpressionPrinter( owlPropertyExpressionPrinter .orElseGet( () -> new OWLPropertyExpressionPrinter( mappingConfig ) ) ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java similarity index 75% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java index 366ec0f9..ee4885a8 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; @@ -23,13 +23,6 @@ * Default implementation for the {@link NameMapper} */ class DefaultNameMapper implements NameMapper { - private final MappingConfiguration mappingConfig; - - public DefaultNameMapper( final MappingConfiguration mappingConfig ) { - this.mappingConfig = mappingConfig; - } - - @Override public String getName( final HasIRI object ) { return getName( object.getIRI() ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java similarity index 56% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java index a2e9eecb..d9f36797 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,19 +14,36 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Node; +import cool.rdf.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; /** - * Creates {@link Node.Id}s for named nodes (i.e. for ontology elements that are identified by {@link IRI}s) - * or anonymous nodes + * Creates {@link Node.Id}s for named nodes (i.e. for ontology elements that are identified by {@link IRI}s) or + * anonymous nodes */ public interface IdentifierMapper { + /** + * Builds a deterministic ID from a given IRI + * + * @param iri the IRI + * @return the ID + */ Node.Id getIdForIri( final IRI iri ); + /** + * Builds a synthetic (nondeterministic) ID for some model element + * + * @return the ID + */ Node.Id getSyntheticId(); + /** + * Build a synthetic (nondeterministic) ID for the model element with the given IRI + * + * @param iri the iri + * @return the ID + */ Node.Id getSyntheticIdForIri( final IRI iri ); } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java new file mode 100644 index 00000000..b7f955ef --- /dev/null +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java @@ -0,0 +1,150 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.diagram.owl.mappers; + +import cool.rdf.diagram.owl.graph.Graph; +import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; +import org.semanticweb.owlapi.model.OWLAnnotationSubjectVisitorEx; +import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; +import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; +import org.semanticweb.owlapi.model.OWLDataVisitorEx; +import org.semanticweb.owlapi.model.OWLEntityVisitorEx; +import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; +import org.semanticweb.owlapi.model.OWLObjectVisitorEx; +import org.semanticweb.owlapi.model.OWLPropertyExpressionVisitorEx; +import org.semanticweb.owlapi.model.SWRLObjectVisitorEx; + +/** + * Captures the different parts of the ontology-to-{@link Graph} mapping operation + */ +public interface MappingConfiguration { + /** + * The OWL axiom mapper translates arbitrary OWL axioms to graphs + * + * @return the mapper + */ + OWLAxiomVisitorEx getOwlAxiomMapper(); + + /** + * The OWL class expression mapper translates OWL class expressions (declarations, but also unions, intersections + * etc.) to graphs + * + * @return the mapper + */ + OWLClassExpressionVisitorEx getOwlClassExpressionMapper(); + + /** + * The OWL individual mapper translates OWL individuals to graphs + * + * @return the mapper + */ + OWLIndividualVisitorEx getOwlIndividualMapper(); + + /** + * The OWL property expression mapper translates OWL object properties and data properties to graphs + * + * @return the mapper + */ + OWLPropertyExpressionVisitorEx getOwlPropertyExpressionMapper(); + + /** + * The OWL object mapper unifies the interfaces for various other mappers, and translates the corresponding OWL + * objects to graphs + * + * @return the mapper + */ + OWLObjectVisitorEx getOwlObjectMapper(); + + /** + * The OWL data mapper translates data axioms, such as data unions and complements, to graphs + * + * @return the mapper + */ + OWLDataVisitorEx getOwlDataMapper(); + + /** + * The OWL entity mapper translates structural OWL elements such as classes, properties and individuals, to graphs + * + * @return the mapper + */ + OWLEntityVisitorEx getOwlEntityMapper(); + + /** + * The OWL annotation objects mapper translates annotation objects (i.e., annotations) to graphs + * + * @return the mapper + */ + OWLAnnotationObjectVisitorEx getOwlAnnotationObjectMapper(); + + /** + * The OWL annotation subject mapper translates annotation subjects (i.e., annotated elements) to graphs + * + * @return the mapper + */ + OWLAnnotationSubjectVisitorEx getOwlAnnotationSubjectMapper(); + + /** + * The SWRL object visitor translates SWRL axioms to graphs + * + * @return the mapper + */ + SWRLObjectVisitorEx getSwrlObjectMapper(); + + /** + * The identifier mapper creates graph (node and edge) identifiers from input ontology identifiers + * + * @return the mapper + */ + IdentifierMapper getIdentifierMapper(); + + /** + * The name mapper translates ontology element IRIs to graph (node and edge) string labels + * + * @return the mapper + */ + NameMapper getNameMapper(); + + /** + * The OWL data printer translates data axioms, such as data unions and complements, to expression String + * representations + * + * @return the printer + */ + OWLDataVisitorEx getOwlDataPrinter(); + + /** + * The OWL property expression printer translates OWL object properties and data properties to expression String + * representations + * + * @return the printer + */ + OWLPropertyExpressionVisitorEx getOwlPropertyExpressionPrinter(); + + /** + * The OWL individual printer translates OWL individuals to expression String representations + * + * @return the printer + */ + OWLIndividualVisitorEx getOwlIndividualPrinter(); + + /** + * The OWL class expression printer translates OWL class expressions to String representations + * + * @return the printer + */ + OWLClassExpressionVisitorEx getOwlClassExpressionPrinter(); +} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java similarity index 69% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java index 7554a357..5a7d2f2d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; @@ -23,7 +23,19 @@ * Determines how the name (i.e. label) of a node is retrieved from the original ontology element */ public interface NameMapper { + /** + * Determines a name for an object that has an IRI + * + * @param object the object + * @return the name + */ String getName( final HasIRI object ); + /** + * Determines a name for the given IRI + * + * @param object the IRI + * @return the name + */ String getName( IRI object ); } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java index 636eb2e6..a04a550b 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.IRIReference; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLAnnotation; import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; @@ -35,6 +35,11 @@ public class OWLAnnotationObjectMapper implements OWLAnnotationObjectVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new annotation object mapper given a mapping config + * + * @param mappingConfig the config + */ public OWLAnnotationObjectMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java similarity index 85% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java index c7de43a1..1a5a9a12 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,26 +14,26 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; import com.google.common.collect.Sets; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DisjointUnion; +import cool.rdf.diagram.owl.graph.node.Disjointness; +import cool.rdf.diagram.owl.graph.node.Equality; +import cool.rdf.diagram.owl.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.node.Inequality; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.graph.node.Key; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; +import cool.rdf.diagram.owl.graph.node.Rule; import org.semanticweb.owlapi.model.HasOperands; import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; import org.semanticweb.owlapi.model.OWLAnnotationPropertyDomainAxiom; @@ -109,6 +109,11 @@ public class OWLAxiomMapper implements OWLAxiomVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new OWL axiom mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLAxiomMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } @@ -125,8 +130,8 @@ public Graph visit( final @Nonnull OWLSubClassOfAxiom axiom ) { } private

Stream - propertyStructure( final OWLPropertyAssertionAxiom axiom, final Node thirdNode, - final Edge.Type subjectToThirdNodeType ) { + propertyStructure( final OWLPropertyAssertionAxiom axiom, final Node thirdNode, + final Edge.Type subjectToThirdNodeType ) { final Graph subjectGraph = axiom.getSubject().accept( mappingConfig.getOwlIndividualMapper() ); final Graph propertyGraph = axiom.getProperty().accept( mappingConfig.getOwlPropertyExpressionMapper() ); @@ -176,7 +181,8 @@ private

> G return domainGraph.and( propertyGraph ).and( domainEdge ); } - private

> Graph propertyRange( final A axiom ) { + private

> Graph propertyRange( + final A axiom ) { final Graph propertyGraph = axiom.getProperty().accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Graph rangeGraph = axiom.getRange().accept( mappingConfig.getOwlObjectMapper() ); final Edge rangeEdge = new Edge.Decorated( Edge.Type.DEFAULT_ARROW, propertyGraph.getNode(), @@ -249,7 +255,7 @@ public Graph visit( final @Nonnull OWLSubObjectPropertyOfAxiom axiom ) { } private Graph linkNodeToMultipleOthers( final HasOperands axiom, - final Node fromNode ) { + final Node fromNode ) { return axiom.operands().map( operand -> { final Graph operandGraph = operand.accept( mappingConfig.getOwlObjectMapper() ); final Edge fromNodeToOperandEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, fromNode, operandGraph @@ -279,7 +285,7 @@ public Graph visit( final @Nonnull OWLDataPropertyRangeAxiom axiom ) { } private Graph propertyMarker( final OWLPropertyExpression propertyExpression, - final PropertyMarker.Kind markerKind ) { + final PropertyMarker.Kind markerKind ) { final Node marker = new PropertyMarker( mappingConfig.getIdentifierMapper().getSyntheticId(), Set.of( markerKind ) ); final Node propertyNode = propertyExpression.accept( mappingConfig.getOwlPropertyExpressionMapper() ).getNode(); @@ -293,18 +299,18 @@ public Graph visit( final @Nonnull OWLFunctionalDataPropertyAxiom axiom ) { } /** - * Shared logic for axioms that generate sets of nodes that are pairwise equivalent, - * e.g. {@link org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom}s. + * Shared logic for axioms that generate sets of nodes that are pairwise equivalent, e.g. + * {@link org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom}s. * - * @param axiom The axiom to generate results for + * @param axiom The axiom to generate results for * @param visitor The visitor that handles the type of axiom - * @param The type of object the axiom describes - * @param The axiom type - * @param The type of visitor that handles the axiom type + * @param The type of object the axiom describes + * @param The axiom type + * @param The type of visitor that handles the axiom type * @return the graph representing the equivalency */ private , V extends OWLObjectVisitorEx> - Graph pairwiseEquivalent( final A axiom, final V visitor ) { + Graph pairwiseEquivalent( final A axiom, final V visitor ) { final Map operands = axiom.operands().collect( Collectors.toMap( Function.identity(), object -> object.accept( visitor ) ) ); @@ -316,11 +322,10 @@ Graph pairwiseEquivalent( final A axiom, final V visitor ) { final List newList = new ArrayList<>( expressionsList ); newList.sort( Comparator.comparing( o -> operands.get( o ).getNode().getId().getId() ) ); return newList; - } - ).filter( expressionsList -> { - final Iterator iterator = expressionsList.iterator(); - return !iterator.next().equals( iterator.next() ); - } ).collect( Collectors.toSet() ); + } ).filter( expressionsList -> { + final Iterator iterator = expressionsList.iterator(); + return !iterator.next().equals( iterator.next() ); + } ).collect( Collectors.toSet() ); // For each of the combinations, create a corresponding edge final Stream edges = combinations.stream().map( expressionsList -> { @@ -344,8 +349,7 @@ public Graph visit( final @Nonnull OWLClassAssertionAxiom axiom ) { final OWLIndividual individual = axiom.getIndividual(); final OWLClassExpression classExpression = axiom.getClassExpression(); final Graph individualGraph = individual.accept( mappingConfig.getOwlIndividualMapper() ); - final Graph classExpressionGraph = - classExpression.accept( mappingConfig.getOwlClassExpressionMapper() ); + final Graph classExpressionGraph = classExpression.accept( mappingConfig.getOwlClassExpressionMapper() ); final Edge edge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, individualGraph.getNode(), classExpressionGraph.getNode() ); @@ -404,8 +408,7 @@ public Graph visit( final @Nonnull OWLSubPropertyChainOfAxiom axiom ) { final OWLPropertyExpressionVisitorEx mapper = mappingConfig.getOwlPropertyExpressionMapper(); final List chainLinks = axiom.getPropertyChain().stream() - .map( expression -> expression.accept( mapper ).getNode() ) - .collect( Collectors.toList() ); + .map( expression -> expression.accept( mapper ).getNode() ).toList(); final String value = chainLinks.stream() .flatMap( node -> node.getId().getIri().stream() ) .map( iri -> mappingConfig.getNameMapper().getName( iri ) ) @@ -503,50 +506,48 @@ public Graph visit( final @Nonnull OWLAnnotationPropertyRangeAxiom axiom ) { @Override public Graph visit( final @Nonnull SWRLRule rule ) { - final Function, String> reduceWithConjuction = stream -> - stream.map( element -> element.as( Literal.class ) ) - .map( Literal::getValue ) - .collect( Collectors.joining( " " + Rule.CONJUNCTION_SYMBOL + " " ) ); + final Function, String> reduceWithConjunction = stream -> stream.map( element -> element.as( Literal.class ) ) + .map( Literal::getValue ) + .collect( Collectors.joining( " " + Rule.CONJUNCTION_SYMBOL + " " ) ); - final Map> partitionedBodyElements = - rule.body().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) - .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); + final Map> partitionedBodyElements = rule.body().flatMap( atom -> atom.accept( mappingConfig + .getSwrlObjectMapper() ).toStream() ) + .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); - final String bodyExpression = reduceWithConjuction.apply( partitionedBodyElements.get( true ).stream() ); + final String bodyExpression = reduceWithConjunction.apply( partitionedBodyElements.get( true ).stream() ); - final Map> partitionedHeadElements = - rule.head().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) - .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); + final Map> partitionedHeadElements = rule.head().flatMap( atom -> atom.accept( mappingConfig + .getSwrlObjectMapper() ).toStream() ) + .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); - final String headExpression = reduceWithConjuction.apply( partitionedHeadElements.get( true ).stream() ); + final String headExpression = reduceWithConjunction.apply( partitionedHeadElements.get( true ).stream() ); final Node ruleNode = new Rule( mappingConfig.getIdentifierMapper().getSyntheticId(), String.format( "%s %s %s", bodyExpression, Rule.IMPLICATION_SYMBOL, headExpression ) ); - final Set allSyntaxParts = - Stream.of( partitionedBodyElements.get( true ), partitionedHeadElements.get( true ) ) - .flatMap( List::stream ) - .map( GraphElement::asNode ) - .collect( Collectors.toSet() ); - - final Stream remainingElements = - Stream.of( partitionedBodyElements.get( false ), partitionedHeadElements.get( false ) ) - .flatMap( List::stream ) - .map( element -> { - if ( element.isEdge() ) { - final Edge edge = element.asEdge(); - if ( allSyntaxParts.contains( edge.getFrom() ) ) { - return edge.setFrom( ruleNode ); - } + final Set allSyntaxParts = Stream.of( partitionedBodyElements.get( true ), partitionedHeadElements.get( true ) ) + .flatMap( List::stream ) + .map( GraphElement::asNode ) + .collect( Collectors.toSet() ); + + final Stream remainingElements = Stream.of( partitionedBodyElements.get( false ), partitionedHeadElements.get( + false ) ) + .flatMap( List::stream ) + .map( element -> { + if ( element.isEdge() ) { + final Edge edge = element.asEdge(); + if ( allSyntaxParts.contains( edge.getFrom() ) ) { + return edge.setFrom( ruleNode ); } - return element; - } ); + } + return element; + } ); return Graph.of( ruleNode, remainingElements ); } @Override - public Graph doDefault( final T object ) { + public Graph doDefault( final @Nonnull T object ) { return TODO(); } } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java similarity index 88% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java index bd9ebc0a..4019ef87 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,30 +14,30 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.ObjectExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; @@ -77,12 +77,17 @@ public class OWLClassExpressionMapper implements OWLClassExpressionVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new OWL axiom mapper from a given mapping config + * + * @param mappingConfig the mapping config + */ public OWLClassExpressionMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } private Stream createEdgeToClassExpression( final Node sourceNode, - final OWLClassExpression classExpression ) { + final OWLClassExpression classExpression ) { final Graph diagramPartsForClassExpression = classExpression.accept( this ); final Node targetNode = diagramPartsForClassExpression.getNode(); final Stream remainingElements = diagramPartsForClassExpression.getOtherElements(); @@ -116,7 +121,7 @@ public Graph visit( final @Nonnull OWLObjectComplementOf classExpression ) { } private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, - final OWLQuantifiedObjectRestriction classExpression ) { + final OWLQuantifiedObjectRestriction classExpression ) { final OWLClassExpression c = classExpression.getFiller(); final OWLObjectPropertyExpression r = classExpression.getProperty(); final Graph cNodeGraph = c.accept( mappingConfig.getOwlClassExpressionMapper() ); @@ -130,7 +135,7 @@ private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, } private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, - final OWLQuantifiedDataRestriction classExpression ) { + final OWLQuantifiedDataRestriction classExpression ) { final OWLDataRange u = classExpression.getFiller(); final OWLDataPropertyExpression d = classExpression.getProperty(); final Graph uNodeGraph = u.accept( mappingConfig.getOwlDataMapper() ); @@ -143,7 +148,7 @@ private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, } private Graph createPropertyEdge( final Node restrictionNode, final OWLRestriction classExpression, - final Edge.Decorated.Label edgeLabel ) { + final Edge.Decorated.Label edgeLabel ) { final OWLPropertyExpression property = classExpression.getProperty(); final Graph rNodeGraph = property.accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Edge rEdge = new Edge.Decorated( Edge.Type.DEFAULT_ARROW, restrictionNode, rNodeGraph diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java similarity index 74% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java index d4031631..c541ff3e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,18 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.Union; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.Union; import org.semanticweb.owlapi.model.OWLDataComplementOf; import org.semanticweb.owlapi.model.OWLDataIntersectionOf; import org.semanticweb.owlapi.model.OWLDataOneOf; @@ -45,12 +45,17 @@ public class OWLDataMapper implements OWLDataVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new data mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLDataMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } private Stream createEdgeToDataRange( final Node sourceNode, - final OWLDataRange classExpression ) { + final OWLDataRange classExpression ) { final Graph diagramPartsForDataRange = classExpression.accept( this ); final Node targetNode = diagramPartsForDataRange.getNode(); final Stream remainingElements = diagramPartsForDataRange.getOtherElements(); @@ -61,8 +66,7 @@ private Stream createEdgeToDataRange( final Node sourceNode, @Override public Graph visit( final @Nonnull OWLDataComplementOf dataRange ) { - final Node complementNode = - new Complement( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node complementNode = new Complement( mappingConfig.getIdentifierMapper().getSyntheticId() ); final Stream remainingElements = createEdgeToDataRange( complementNode, dataRange.getDataRange() ); return Graph.of( complementNode, remainingElements ); @@ -70,8 +74,7 @@ public Graph visit( final @Nonnull OWLDataComplementOf dataRange ) { @Override public Graph visit( final @Nonnull OWLDataOneOf dataRange ) { - final Node restrictionNode = - new ClosedClass( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node restrictionNode = new ClosedClass( mappingConfig.getIdentifierMapper().getSyntheticId() ); return dataRange.values().map( value -> { final Graph valueGraph = value.accept( mappingConfig.getOwlDataMapper() ); final Edge vEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, restrictionNode, valueGraph.getNode() ); @@ -81,18 +84,17 @@ public Graph visit( final @Nonnull OWLDataOneOf dataRange ) { @Override public Graph visit( final @Nonnull OWLDataIntersectionOf dataRange ) { - final Node intersectionNode = - new Intersection( mappingConfig.getIdentifierMapper().getSyntheticId() ); - final Stream remainingElements = dataRange.operands().flatMap( operand -> - createEdgeToDataRange( intersectionNode, operand ) ); + final Node intersectionNode = new Intersection( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Stream remainingElements = dataRange.operands().flatMap( operand -> createEdgeToDataRange( intersectionNode, + operand ) ); return Graph.of( intersectionNode, remainingElements ); } @Override public Graph visit( final @Nonnull OWLDataUnionOf dataRange ) { final Node unionNode = new Union( mappingConfig.getIdentifierMapper().getSyntheticId() ); - final Stream remainingElements = dataRange.operands().flatMap( operand -> - createEdgeToDataRange( unionNode, operand ) ); + final Stream remainingElements = dataRange.operands().flatMap( operand -> createEdgeToDataRange( unionNode, + operand ) ); return Graph.of( unionNode, remainingElements ); } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java index bb8c29f2..e65b75f0 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLDataProperty; @@ -39,6 +39,11 @@ public class OWLEntityMapper implements OWLEntityVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new entity mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLEntityMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java similarity index 82% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java index 139f024b..7d9a62e8 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Individual; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Individual; import org.semanticweb.owlapi.model.OWLAnonymousIndividual; import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; import org.semanticweb.owlapi.model.OWLNamedIndividual; @@ -31,6 +31,11 @@ public class OWLIndividualMapper implements OWLIndividualVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new individual mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLIndividualMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java similarity index 88% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java index 1de749f8..a2dc8fdb 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; +import cool.rdf.diagram.owl.graph.Graph; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLDataAllValuesFrom; @@ -53,12 +53,17 @@ import javax.annotation.Nonnull; /** - * Dispatcher of multiple types of OWL objects; this is called in some generic mapping operations. - * Maps {@link org.semanticweb.owlapi.model.OWLObject}s to {@link Graph}s. + * Dispatcher of multiple types of OWL objects; this is called in some generic mapping operations. Maps + * {@link org.semanticweb.owlapi.model.OWLObject}s to {@link Graph}s. */ public class OWLObjectMapper implements OWLObjectVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new object mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLObjectMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } @@ -179,42 +184,42 @@ public Graph visit( final @Nonnull OWLNamedIndividual individual ) { } @Override - public Graph visit( final OWLLiteral literal ) { + public Graph visit( final @Nonnull OWLLiteral literal ) { return mappingConfig.getOwlDataMapper().visit( literal ); } @Override - public Graph visit( final OWLDatatype datatype ) { + public Graph visit( final @Nonnull OWLDatatype datatype ) { return mappingConfig.getOwlDataMapper().visit( datatype ); } @Override - public Graph visit( final OWLDataComplementOf complement ) { + public Graph visit( final @Nonnull OWLDataComplementOf complement ) { return mappingConfig.getOwlDataMapper().visit( complement ); } @Override - public Graph visit( final OWLDataOneOf oneOf ) { + public Graph visit( final @Nonnull OWLDataOneOf oneOf ) { return mappingConfig.getOwlDataMapper().visit( oneOf ); } @Override - public Graph visit( final OWLDataIntersectionOf intersection ) { + public Graph visit( final @Nonnull OWLDataIntersectionOf intersection ) { return mappingConfig.getOwlDataMapper().visit( intersection ); } @Override - public Graph visit( final OWLDataUnionOf union ) { + public Graph visit( final @Nonnull OWLDataUnionOf union ) { return mappingConfig.getOwlDataMapper().visit( union ); } @Override - public Graph visit( final OWLDatatypeRestriction restriction ) { + public Graph visit( final @Nonnull OWLDatatypeRestriction restriction ) { return mappingConfig.getOwlDataMapper().visit( restriction ); } @Override - public Graph visit( final OWLFacetRestriction restriction ) { + public Graph visit( final @Nonnull OWLFacetRestriction restriction ) { return mappingConfig.getOwlDataMapper().visit( restriction ); } } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java similarity index 64% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java index 65bc85a8..e00b85b8 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,14 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.transformer.IriReferenceResolver; -import de.atextor.owlcli.diagram.graph.transformer.PropertyMarkerMerger; -import de.atextor.owlcli.diagram.graph.transformer.PunningRemover; +import cool.rdf.diagram.owl.graph.transformer.GraphTransformer; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.transformer.IriReferenceResolver; +import cool.rdf.diagram.owl.graph.transformer.PropertyMarkerMerger; +import cool.rdf.diagram.owl.graph.transformer.PunningRemover; import org.semanticweb.owlapi.model.OWLOntology; import java.util.List; @@ -29,22 +30,27 @@ import java.util.stream.Collectors; /** - * Main class for mapping an {@link OWLOntology} to a {@link Graph}. The mapping is done in two steps: - * First, all axioms in the ontology are separatly mapped using the respective OWL*Mappers into nodes and edges. - * Secondly, the {@link de.atextor.owlcli.diagram.graph.transformer.GraphTransformer}s clean up the graph by - * performing changes that take the context of the whole graph into account. + * Main class for mapping an {@link OWLOntology} to a {@link Graph}. The mapping is done in two steps: First, all axioms + * in the ontology are separately mapped using the respective OWL*Mappers into nodes and edges. Secondly, the + * {@link GraphTransformer}s clean up the graph by performing changes that take the context of the whole graph into + * account. */ public class OWLOntologyMapper implements Function> { private final MappingConfiguration mappingConfiguration; + private final List, Set>> transformers; + /** + * Creates a new ontology mapper from a given mapping config + * + * @param mappingConfiguration the config + */ public OWLOntologyMapper( final MappingConfiguration mappingConfiguration ) { this.mappingConfiguration = mappingConfiguration; transformers = List.of( new PunningRemover( mappingConfiguration ), new IriReferenceResolver( mappingConfiguration ), - new PropertyMarkerMerger( mappingConfiguration ) - ); + new PropertyMarkerMerger( mappingConfiguration ) ); } @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java similarity index 77% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java index bad74a47..ce71d22e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLDataProperty; import org.semanticweb.owlapi.model.OWLObjectInverseOf; @@ -38,17 +38,20 @@ public class OWLPropertyExpressionMapper implements OWLPropertyExpressionVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates an new property expression mapper from a given mapping config + * + * @param mappingConfig the config + */ public OWLPropertyExpressionMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } @Override public Graph visit( final @Nonnull OWLObjectInverseOf property ) { - final Node inverseNode = - new Inverse( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node inverseNode = new Inverse( mappingConfig.getIdentifierMapper().getSyntheticId() ); final OWLPropertyExpression invertedProperty = property.getInverseProperty(); - final Graph propertyVisitorGraph = - invertedProperty.accept( mappingConfig.getOwlPropertyExpressionMapper() ); + final Graph propertyVisitorGraph = invertedProperty.accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Edge propertyEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, inverseNode, propertyVisitorGraph .getNode() ); return Graph.of( inverseNode ).and( propertyVisitorGraph ).and( propertyEdge ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java similarity index 80% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java index b9631717..a446b054 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package cool.rdf.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Literal; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Literal; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLPropertyExpression; import org.semanticweb.owlapi.model.SWRLArgument; @@ -47,23 +47,36 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import static io.vavr.API.TODO; + +/** + * A mapper that translates SWRL rules into a {@link Graph}: The rule is represented as one distinct node that contains + * a human-readable string representation of the rule, with outgoing edges to the nodes representing the elements + * (classes etc.) that are referred to in the rule. + */ public class SWRLObjectMapper implements SWRLObjectVisitorEx { /** - * During traversal of the rule expression tree, both Literal nodes and other GraphElements - * (mainly Edges) are collected. The values of the Literal nodes are concatenated in the end - * to render the final rule representation. In order to differentiate the to-be-concatenated - * Literal nodes from "regular" Literal nodes that might occur, they are given an internal - * identifier "marker" IRI. The concatenation is done in - * {@link de.atextor.owlcli.diagram.mappers.OWLAxiomMapper#visit(SWRLRule)}. + * The "marker" ID, see {@link #IS_RULE_SYNTAX_PART}. */ private static final IRI LITERAL_ID = IRI.create( "urn:owl-cli:literal-id" ); - public static final Predicate IS_RULE_SYNTAX_PART = - graphElement -> graphElement.is( Literal.class ) && - graphElement.as( Literal.class ).getId().getIri().map( iri -> iri.equals( LITERAL_ID ) ).orElse( false ); + /** + * During traversal of the rule expression tree, both Literal nodes and other GraphElements (mainly Edges) are + * collected. The values of the Literal nodes are concatenated in the end to render the final rule representation. + * In order to differentiate the to-be-concatenated Literal nodes from "regular" Literal nodes that might occur, + * they are given an internal identifier "marker" IRI. The concatenation is done in + * {@link OWLAxiomMapper#visit(SWRLRule)}. + */ + public static final Predicate IS_RULE_SYNTAX_PART = graphElement -> graphElement.is( Literal.class ) && + graphElement.as( Literal.class ).getId().getIri().map( iri -> iri.equals( LITERAL_ID ) ).orElse( false ); private final MappingConfiguration mappingConfig; + /** + * Creates a new SWRL object mapper from a given mapping config + * + * @param mappingConfig the mapping config + */ public SWRLObjectMapper( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } @@ -97,8 +110,7 @@ public Graph visit( final @Nonnull SWRLDataRangeAtom atom ) { } private List argumentElements( final SWRLAtom atom ) { - return atom.allArguments().flatMap( argument -> - argument.accept( this ).toStream() ).collect( Collectors.toList() ); + return atom.allArguments().flatMap( argument -> argument.accept( this ).toStream() ).collect( Collectors.toList() ); } private String printArgumentElements( final List argumentElements ) { @@ -115,14 +127,13 @@ public Graph visit( final @Nonnull SWRLObjectPropertyAtom atom ) { } private Graph visitPropertyAtom( final SWRLBinaryAtom atom, - final OWLPropertyExpression predicate ) { + final OWLPropertyExpression predicate ) { final List argumentGraphElements = argumentElements( atom ); final String arguments = printArgumentElements( argumentGraphElements ); final String label = String.format( "%s(%s)", predicate.accept( mappingConfig.getOwlPropertyExpressionPrinter() ), arguments ); - final Node dataProperty = - predicate.accept( mappingConfig.getOwlPropertyExpressionMapper() ).getNode(); + final Node dataProperty = predicate.accept( mappingConfig.getOwlPropertyExpressionMapper() ).getNode(); final Literal literal = new Literal( mappingConfig.getIdentifierMapper() .getSyntheticIdForIri( LITERAL_ID ), label ); final Edge edge = new Edge.Plain( Edge.Type.DASHED_ARROW, literal, dataProperty ); @@ -136,18 +147,19 @@ public Graph visit( final @Nonnull SWRLDataPropertyAtom atom ) { return visitPropertyAtom( atom, atom.getPredicate() ); } + @SuppressWarnings( "SpellCheckingInspection" ) @Override public Graph visit( final @Nonnull SWRLBuiltInAtom atom ) { final List argumentGraphElements = argumentElements( atom ); final String arguments = printArgumentElements( argumentGraphElements ); - final String builtin = Namespaces.SWRLB.inNamespace( atom.getPredicate() ) ? - String.format( "swrlb:%s", atom.getPredicate().getFragment() ) : - mappingConfig.getNameMapper().getName( atom.getPredicate() ); + final String builtin = Namespaces.SWRLB.inNamespace( atom.getPredicate() ) ? String.format( "swrlb:%s", atom.getPredicate() + .getFragment() ) : mappingConfig.getNameMapper().getName( atom.getPredicate() ); final String label = String.format( "%s(%s)", builtin, arguments ); return Graph.of( new Literal( mappingConfig.getIdentifierMapper().getSyntheticIdForIri( LITERAL_ID ), label ) ); } + @SuppressWarnings( "SpellCheckingInspection" ) @Override public Graph visit( final @Nonnull SWRLVariable variable ) { // Do not call namemapper for variable IRI fragment: variable name is not subject to be @@ -196,6 +208,6 @@ public Graph visit( final @Nonnull SWRLSameIndividualAtom atom ) { @Override public Graph visit( final @Nonnull SWRLDifferentIndividualsAtom node ) { - return null; + return TODO(); } } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java similarity index 92% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java index ee9a6cd7..0b1c8f75 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package cool.rdf.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.HasCardinality; import org.semanticweb.owlapi.model.HasFiller; import org.semanticweb.owlapi.model.OWLClass; @@ -50,6 +50,11 @@ public class OWLClassExpressionPrinter implements OWLClassExpressionVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new class expression printer from a given mapping config + * + * @param mappingConfig the config + */ public OWLClassExpressionPrinter( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } @@ -95,7 +100,7 @@ public String visit( final @Nonnull OWLObjectHasValue classExpression ) { } private > - String printQualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { + String printQualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { return String.format( "%s %s %d %s", classExpression.getProperty().accept( mappingConfig.getOwlPropertyExpressionPrinter() ), restrictionType, @@ -104,7 +109,7 @@ String printQualifiedCardinalityRestriction( final T classExpression, final Stri } private - String printUnqualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { + String printUnqualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { return String.format( "%s %s %d", classExpression.getProperty().accept( mappingConfig.getOwlPropertyExpressionPrinter() ), restrictionType, @@ -185,7 +190,7 @@ public String visit( final @Nonnull OWLDataMaxCardinality classExpression ) { } @Override - public String visit( final OWLClass classExpression ) { + public String visit( final @Nonnull OWLClass classExpression ) { return mappingConfig.getNameMapper().getName( classExpression ); } } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java index 7f9526b6..727c782d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package cool.rdf.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLDataComplementOf; import org.semanticweb.owlapi.model.OWLDataIntersectionOf; import org.semanticweb.owlapi.model.OWLDataOneOf; @@ -36,6 +36,11 @@ public class OWLDataPrinter implements OWLDataVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new data printer from a given mapping config + * + * @param mappingConfig the config + */ public OWLDataPrinter( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java similarity index 78% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java index 2fe3e93c..af130c34 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package cool.rdf.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLAnonymousIndividual; import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; import org.semanticweb.owlapi.model.OWLNamedIndividual; @@ -27,8 +27,13 @@ * Serializes {@link org.semanticweb.owlapi.model.OWLIndividual}s into expressions */ public class OWLIndividualPrinter implements OWLIndividualVisitorEx { - MappingConfiguration mappingConfiguration; + final MappingConfiguration mappingConfiguration; + /** + * Creates a new individual printer from a given mapping config + * + * @param mappingConfiguration the config + */ public OWLIndividualPrinter( final MappingConfiguration mappingConfiguration ) { this.mappingConfiguration = mappingConfiguration; } diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java similarity index 85% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java rename to cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java index 23654d76..9e11853f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package cool.rdf.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLDataProperty; import org.semanticweb.owlapi.model.OWLObjectInverseOf; @@ -31,6 +31,11 @@ public class OWLPropertyExpressionPrinter implements OWLPropertyExpressionVisitorEx { private final MappingConfiguration mappingConfig; + /** + * Creates a new property expression printer from a given mapping config + * + * @param mappingConfig the mapping config + */ public OWLPropertyExpressionPrinter( final MappingConfiguration mappingConfig ) { this.mappingConfig = mappingConfig; } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/DiagramGeneratorTest.java similarity index 70% rename from diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/DiagramGeneratorTest.java index 175e3d0e..54d9ce7e 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/DiagramGeneratorTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,47 +14,47 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; -import de.atextor.owlcli.diagram.mappers.DefaultIdentifierMapper; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.DisjointUnion; +import cool.rdf.diagram.owl.graph.node.Disjointness; +import cool.rdf.diagram.owl.graph.node.Equality; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.graph.node.Inequality; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.ObjectExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; +import cool.rdf.diagram.owl.mappers.DefaultIdentifierMapper; +import cool.rdf.diagram.owl.mappers.DefaultMappingConfiguration; +import cool.rdf.diagram.owl.mappers.IdentifierMapper; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import io.vavr.control.Try; import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; @@ -68,11 +68,12 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Set; public class DiagramGeneratorTest { - File workingDir = new File( System.getProperty( "user.dir" ) ); + final File workingDir = new File( System.getProperty( "user.dir" ) ); final Configuration configuration = Configuration.builder().build(); @@ -202,11 +203,18 @@ Arbitrary> anyGraph() { return Arbitraries.oneOf( List.of( anyNode(), anyEdge() ) ).map( Set::of ); } + /** + * Tests that any Graphviz diagram that can be generated is actually syntactically valid, i.e., can be processed + * by Graphviz without errors. + * + * @param graph the input graph + * @return true if it could successfully be rendered + */ @Property public boolean everyGeneratedDiagramIsSyntacticallyValid( @ForAll( "anyGraph" ) final Set graph ) { final String graphvizDocument = graphvizGenerator.apply( graph.stream() ).apply( configuration ); final ThrowingConsumer contentProvider = outputStream -> { - outputStream.write( graphvizDocument.getBytes() ); + outputStream.write( graphvizDocument.getBytes( StandardCharsets.UTF_8 ) ); outputStream.flush(); outputStream.close(); }; @@ -215,6 +223,10 @@ public boolean everyGeneratedDiagramIsSyntacticallyValid( @ForAll( "anyGraph" ) .executeDot( contentProvider, output, workingDir, configuration ); if ( executionResult.isFailure() ) { System.out.println( executionResult.getCause().getMessage() ); + System.out.println( "Found invalid dot diagram" ); + System.out.println( "=======" ); + System.out.println( graphvizDocument ); + System.out.println( "=======" ); } return executionResult.isSuccess(); } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/GraphvizGeneratorTest.java similarity index 79% rename from diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/GraphvizGeneratorTest.java index 9d4866eb..24d71153 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/GraphvizGeneratorTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,39 +14,39 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.DisjointUnion; +import cool.rdf.diagram.owl.graph.node.Disjointness; +import cool.rdf.diagram.owl.graph.node.IRIReference; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.graph.node.ObjectExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Literal; +import cool.rdf.diagram.owl.graph.node.ObjectMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.IRI; @@ -58,10 +58,15 @@ public class GraphvizGeneratorTest { final GraphvizGenerator generator = new GraphvizGenerator( Configuration.builder().build() ); + final Node.Id from1 = new Node.Id( "foo" ); + final Node.Id to1 = new Node.Id( "bar" ); + final String name1 = "baz"; + final int cardinality1 = 5; + final String value1 = "theValue"; Predicate contains( final String needle ) { @@ -133,7 +138,7 @@ private void testValueNode( final Node node ) { } @Test - void testNodeelementsTypeClass() { + void testNodeElementsTypeClass() { testNamedNode( new Class( from1, name1 ) ); } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/MapperTestBase.java similarity index 90% rename from diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/MapperTestBase.java index 3b018f52..4216cf5d 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/MapperTestBase.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.Invisible; +import cool.rdf.diagram.owl.mappers.DefaultMappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.IRI; @@ -43,21 +43,28 @@ import static org.assertj.core.api.Fail.fail; public class MapperTestBase { - protected TestIdentifierMapper testIdentifierMapper = new TestIdentifierMapper(); - protected TestNameMapper testNameMapper = new TestNameMapper(); + protected final TestIdentifierMapper testIdentifierMapper = new TestIdentifierMapper(); + + protected final TestNameMapper testNameMapper = new TestNameMapper(); protected final Predicate hasDefaultArrow = edge -> edge.getType().equals( Edge.Type.DEFAULT_ARROW ); + protected final Predicate hasHollowArrow = edge -> edge.getType().equals( Edge.Type.HOLLOW_ARROW ); + protected final Predicate hasDashedArrow = edge -> edge.getType().equals( Edge.Type.DASHED_ARROW ); + protected final Predicate hasNoArrow = edge -> edge.getType().equals( Edge.Type.NO_ARROW ); + final Predicate hasDomainLabel = edge -> edge.view( Edge.Decorated.class ) .map( decoratedEdge -> decoratedEdge.getLabel().equals( Edge.Decorated.Label.DOMAIN ) ) .findFirst() .orElse( false ); + final Predicate hasRangeLabel = edge -> edge.view( Edge.Decorated.class ) .map( decoratedEdge -> decoratedEdge.getLabel().equals( Edge.Decorated.Label.RANGE ) ) .findFirst() .orElse( false ); + final Predicate hasFromBar = edge -> edge.getFrom().getId().getId().equals( "bar" ); protected MappingConfiguration createTestMappingConfiguration() { @@ -160,7 +167,7 @@ protected Predicate isEdgeWithFromAndTo( final String fromId, final String } protected Predicate isEdgeWithFromAndToAndLabel( final String fromId, final String toId, - final Edge.Decorated.Label label ) { + final Edge.Decorated.Label label ) { return edge -> edge.getFrom().getId().getId().equals( fromId ) && edge.getTo().getId().getId().equals( toId ) && ( (Edge.Decorated) edge ).getLabel().equals( label ); diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAnnotationObjectMapperTest.java similarity index 86% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAnnotationObjectMapperTest.java index aae2f6e5..f886172b 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAnnotationObjectMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.mappers.OWLAnnotationObjectMapper; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.mappers.OWLAnnotationObjectMapper; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAxiomMapperTest.java similarity index 96% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAxiomMapperTest.java index bd97f57a..cc561628 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLAxiomMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,22 +14,22 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLAxiomMapper; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Inequality; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.graph.node.PropertyChain; +import cool.rdf.diagram.owl.mappers.IdentifierMapper; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.OWLAxiomMapper; +import cool.rdf.diagram.owl.graph.node.Datatype; +import cool.rdf.diagram.owl.graph.node.Equality; +import cool.rdf.diagram.owl.graph.node.Key; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.IRI; @@ -78,6 +78,7 @@ public class OWLAxiomMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = createTestMappingConfiguration(); + private final OWLAxiomMapper mapper = new OWLAxiomMapper( mappingConfiguration ); @Test @@ -156,7 +157,7 @@ public void testOWLAsymmetricObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.ASYMMETRIC ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.ASYMMETRIC ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -179,7 +180,7 @@ public void testOWLReflexiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.REFLEXIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.REFLEXIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -500,7 +501,7 @@ public void testOWLFunctionalObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -577,7 +578,7 @@ public void testOWLSymmetricObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.SYMMETRIC ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.SYMMETRIC ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -624,7 +625,7 @@ public void testOWLFunctionalDataPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -770,7 +771,7 @@ public void testOWLTransitiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.TRANSITIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.TRANSITIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -793,7 +794,7 @@ public void testOWLIrreflexiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.IRREFLEXIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.IRREFLEXIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -841,7 +842,7 @@ public void testOWLInverseFunctionalObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.INVERSE_FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.INVERSE_FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -1027,10 +1028,11 @@ public void testOWLSubAnnotationPropertyOfAxiom() { @Test public void testOWLAnnotationPropertyRangeAxiom() { + // TODO } private void assertEquivalentResult( final Set result, final IRI fooIri, final IRI barIri, - final IRI bazIri ) { + final IRI bazIri ) { final List nodes = nodes( result ); assertThat( nodes ).hasSize( 3 ); diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLClassExpressionMapperTest.java similarity index 95% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLClassExpressionMapperTest.java index b44f856c..1a5a068f 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLClassExpressionMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,29 +14,29 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; -import de.atextor.owlcli.diagram.mappers.OWLClassExpressionMapper; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Self; +import cool.rdf.diagram.owl.graph.node.ValueRestriction; +import cool.rdf.diagram.owl.mappers.OWLClassExpressionMapper; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.DataExactCardinality; +import cool.rdf.diagram.owl.graph.node.DataMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.DataMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ExistentialRestriction; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.ObjectMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.graph.node.UniversalRestriction; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLClass; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLDataMapperTest.java similarity index 94% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLDataMapperTest.java index cd771ee8..701a4599 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLDataMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,18 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.mappers.OWLDataMapper; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.ClosedClass; +import cool.rdf.diagram.owl.graph.node.Complement; +import cool.rdf.diagram.owl.graph.node.Intersection; +import cool.rdf.diagram.owl.graph.node.Union; +import cool.rdf.diagram.owl.mappers.OWLDataMapper; +import cool.rdf.diagram.owl.graph.node.Datatype; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLDataComplementOf; @@ -234,10 +234,12 @@ public void testOWLDatatypeRestriction() { @Test public void testOWLFacetRestriction() { + // TODO } @Test public void testOWLDatatype() { + // TODO } @Test diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLEntityMapperTest.java similarity index 80% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLEntityMapperTest.java index 96eb57d7..34befed6 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLEntityMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.mappers.OWLEntityMapper; +import cool.rdf.diagram.owl.mappers.OWLEntityMapper; import org.junit.jupiter.api.Test; public class OWLEntityMapperTest extends MapperTestBase { @@ -24,25 +24,31 @@ public class OWLEntityMapperTest extends MapperTestBase { @Test public void testOWLClass() { + // TODO } @Test public void testOWLDatatype() { + // TODO } @Test public void testOWLNamedIndividual() { + // TODO } @Test public void testOWLObjectProperty() { + // TODO } @Test public void testOWLDataProperty() { + // TODO } @Test public void testOWLAnnotationProperty() { + // TODO } } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLIndividualMapperTest.java similarity index 87% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLIndividualMapperTest.java index e4bdf3ce..3c2cbb38 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLIndividualMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,12 +14,12 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLIndividualMapper; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.mappers.DefaultMappingConfiguration; +import cool.rdf.diagram.owl.mappers.OWLIndividualMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLOntologyMapperTest.java similarity index 92% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLOntologyMapperTest.java index f77aae27..574ba1e3 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLOntologyMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,17 +14,17 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLOntologyMapper; +package cool.rdf.diagram.owl; + +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.Class; +import cool.rdf.diagram.owl.graph.node.Individual; +import cool.rdf.diagram.owl.graph.node.PropertyMarker; +import cool.rdf.diagram.owl.mappers.DefaultMappingConfiguration; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.OWLOntologyMapper; import org.junit.jupiter.api.Test; import java.util.List; @@ -34,6 +34,7 @@ public class OWLOntologyMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = DefaultMappingConfiguration.builder().build(); + private final OWLOntologyMapper mapper = new OWLOntologyMapper( mappingConfiguration ); @Test diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLPropertyExpressionMapperTest.java similarity index 88% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLPropertyExpressionMapperTest.java index 7951cc9e..cf6e0caa 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/OWLPropertyExpressionMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,14 +14,14 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.mappers.OWLPropertyExpressionMapper; +import cool.rdf.diagram.owl.graph.Graph; +import cool.rdf.diagram.owl.graph.node.AnnotationProperty; +import cool.rdf.diagram.owl.graph.node.DataProperty; +import cool.rdf.diagram.owl.graph.node.Inverse; +import cool.rdf.diagram.owl.mappers.OWLPropertyExpressionMapper; +import cool.rdf.diagram.owl.graph.node.ObjectProperty; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAnnotationProperty; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/SWRLObjectMapperTest.java similarity index 95% rename from diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/SWRLObjectMapperTest.java index 87c12e52..bf0e1ab2 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/SWRLObjectMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLAxiomMapper; +import cool.rdf.diagram.owl.graph.Edge; +import cool.rdf.diagram.owl.graph.GraphElement; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import cool.rdf.diagram.owl.graph.node.Rule; +import cool.rdf.diagram.owl.mappers.MappingConfiguration; +import cool.rdf.diagram.owl.mappers.OWLAxiomMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.SWRLRule; @@ -34,6 +34,7 @@ public class SWRLObjectMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = createTestMappingConfiguration(); + private final OWLAxiomMapper mapper = new OWLAxiomMapper( mappingConfiguration ); @Test diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestIdentifierMapper.java similarity index 87% rename from diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestIdentifierMapper.java index da076f41..c498e6d2 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestIdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,10 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; +import cool.rdf.diagram.owl.graph.Node; +import cool.rdf.diagram.owl.mappers.IdentifierMapper; import org.semanticweb.owlapi.model.IRI; import java.util.Stack; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestNameMapper.java similarity index 83% rename from diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java rename to cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestNameMapper.java index f8e987aa..18ae7215 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java +++ b/cool-rdf-diagram-owl/src/test/java/cool/rdf/diagram/owl/TestNameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package cool.rdf.diagram.owl; -import de.atextor.owlcli.diagram.mappers.NameMapper; +import cool.rdf.diagram.owl.mappers.NameMapper; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; diff --git a/cool-rdf-formatter/pom.xml b/cool-rdf-formatter/pom.xml new file mode 100644 index 00000000..4bb8f537 --- /dev/null +++ b/cool-rdf-formatter/pom.xml @@ -0,0 +1,93 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-formatter + Cool RDF Formatter + + + + + cool.rdf + cool-rdf-core + + + + + org.apache.jena + jena-core + + + org.apache.jena + jena-arq + + + org.slf4j + slf4j-api + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + org.apache.jena + apache-jena-libs + pom + test + + + diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java new file mode 100644 index 00000000..1bf5d4f6 --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java @@ -0,0 +1,23 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter; + +public class FMT { + public static final String FMT = "http://purl.org/atextor/ontology/turtle-formatting"; + + public static final String NS = FMT + "#"; +} diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java new file mode 100644 index 00000000..321c31ad --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java @@ -0,0 +1,257 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter; + +import cool.rdf.core.Prefixes; +import cool.rdf.core.model.RdfPrefix; +import lombok.Builder; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.vocabulary.DCTerms; +import org.apache.jena.vocabulary.OWL2; +import org.apache.jena.vocabulary.RDF; +import org.apache.jena.vocabulary.RDFS; +import org.apache.jena.vocabulary.SKOS; +import org.apache.jena.vocabulary.XSD; + +import java.net.URI; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.function.BiFunction; + +@Builder +public class FormattingStyle { + public static final FormattingStyle DEFAULT = builder().build(); + + @Builder.Default + public Set knownPrefixes = Set.of( + Prefixes.RDF, + Prefixes.RDFS, + Prefixes.XSD, + Prefixes.OWL, + Prefixes.DCTERMS ); + + @Builder.Default + public String emptyRdfBase = TurtleFormatter.DEFAULT_EMPTY_BASE; + + @Builder.Default + public GapStyle afterClosingParenthesis = GapStyle.NOTHING; + + @Builder.Default + public GapStyle afterClosingSquareBracket = GapStyle.SPACE; + + @Builder.Default + public GapStyle afterComma = GapStyle.SPACE; + + @Builder.Default + public GapStyle afterDot = GapStyle.NEWLINE; + + @Builder.Default + public GapStyle afterOpeningParenthesis = GapStyle.SPACE; + + @Builder.Default + public GapStyle afterOpeningSquareBracket = GapStyle.NEWLINE; + + @Builder.Default + public GapStyle afterSemicolon = GapStyle.NEWLINE; + + @Builder.Default + public Alignment alignPrefixes = Alignment.OFF; + + @Builder.Default + public GapStyle beforeClosingParenthesis = GapStyle.SPACE; + + @Builder.Default + public GapStyle beforeClosingSquareBracket = GapStyle.NEWLINE; + + @Builder.Default + public GapStyle beforeComma = GapStyle.NOTHING; + + @Builder.Default + public GapStyle beforeDot = GapStyle.SPACE; + + @Builder.Default + public GapStyle beforeOpeningParenthesis = GapStyle.SPACE; + + @Builder.Default + public GapStyle beforeOpeningSquareBracket = GapStyle.SPACE; + + @Builder.Default + public GapStyle beforeSemicolon = GapStyle.SPACE; + + @Builder.Default + public Charset charset = Charset.UTF_8; + + @Builder.Default + public NumberFormat doubleFormat = new DecimalFormat( "0.####E0", DecimalFormatSymbols.getInstance( Locale.US ) ); + + @Builder.Default + public boolean enableDoubleFormatting = false; + + @Builder.Default + public EndOfLineStyle endOfLine = EndOfLineStyle.LF; + + @Builder.Default + public IndentStyle indentStyle = IndentStyle.SPACE; + + @Builder.Default + public QuoteStyle quoteStyle = QuoteStyle.TRIPLE_QUOTES_FOR_MULTILINE; + + @Builder.Default + public WrappingStyle wrapListItems = WrappingStyle.FOR_LONG_LINES; + + @Builder.Default + public boolean firstPredicateInNewLine = false; + + @Builder.Default + public boolean useAForRdfType = true; + + @Builder.Default + public boolean useCommaByDefault = false; + + @Builder.Default + public Set commaForPredicate = Set.of( RDF.type ); + + @Builder.Default + public Set noCommaForPredicate = Set.of(); + + @Builder.Default + public boolean useShortLiterals = true; + + @Builder.Default + public boolean alignBaseIRI = false; + + @Builder.Default + public boolean alignObjects = false; + + @Builder.Default + public boolean alignPredicates = false; + + @Builder.Default + public int continuationIndentSize = 4; + + @Builder.Default + public boolean indentPredicates = true; + + @Builder.Default + public boolean insertFinalNewline = true; + + @Builder.Default + public int indentSize = 2; + + @Builder.Default + public int maxLineLength = 100; + + @Builder.Default + public boolean trimTrailingWhitespace = true; + + @Builder.Default + public boolean keepUnusedPrefixes = false; + + @Builder.Default + public List prefixOrder = List.of( + "rdf", + "rdfs", + "xsd", + "owl" ); + + @Builder.Default + public List subjectOrder = List.of( + OWL2.Ontology, + RDFS.Class, + OWL2.Class, + RDF.Property, + OWL2.ObjectProperty, + OWL2.DatatypeProperty, + OWL2.AnnotationProperty, + OWL2.NamedIndividual, + OWL2.AllDifferent, + OWL2.Axiom ); + + @Builder.Default + public List predicateOrder = List.of( + RDF.type, + RDFS.label, + RDFS.comment, + DCTerms.description ); + + @Builder.Default + public List objectOrder = List.of( + OWL2.NamedIndividual, + OWL2.ObjectProperty, + OWL2.DatatypeProperty, + OWL2.AnnotationProperty, + OWL2.FunctionalProperty, + OWL2.InverseFunctionalProperty, + OWL2.TransitiveProperty, + OWL2.SymmetricProperty, + OWL2.AsymmetricProperty, + OWL2.ReflexiveProperty, + OWL2.IrreflexiveProperty ); + + @Builder.Default + public BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "gen" + integer; + + public enum Alignment { + LEFT, + OFF, + RIGHT + } + + public enum Charset { + LATIN1, + UTF_16_BE, + UTF_16_LE, + UTF_8, + UTF_8_BOM + } + + public enum EndOfLineStyle { + CR, + CRLF, + LF + } + + public enum GapStyle { + NEWLINE, + NOTHING, + SPACE + } + + public enum IndentStyle { + SPACE, + TAB + } + + public enum WrappingStyle { + ALWAYS, + FOR_LONG_LINES, + NEVER + } + + public enum QuoteStyle { + ALWAYS_SINGE_QUOTES, + TRIPLE_QUOTES_FOR_MULTILINE, + ALWAYS_TRIPLE_QUOTES + } + +} diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java new file mode 100644 index 00000000..bc9958b7 --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java @@ -0,0 +1,73 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter; + +import cool.rdf.formatter.blanknode.BlankNodeMetadata; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.shared.PrefixMapping; + +import java.util.Comparator; +import java.util.Optional; + +public class RDFNodeComparatorFactory { + + private final PrefixMapping prefixMapping; + private final BlankNodeMetadata blankNodeOrdering; + private final RDFNodeComparator rdfNodeComparator = new RDFNodeComparator(); + + public RDFNodeComparatorFactory( PrefixMapping prefixMapping, BlankNodeMetadata blankNodeOrdering ) { + this.prefixMapping = prefixMapping; + this.blankNodeOrdering = blankNodeOrdering; + } + + public RDFNodeComparatorFactory( PrefixMapping prefixMapping ) { + this( prefixMapping, null ); + } + + public RDFNodeComparator comparator() { + return rdfNodeComparator; + } + + private class RDFNodeComparator implements Comparator { + @Override + public int compare( RDFNode left, RDFNode right ) { + if ( left.isURIResource() ) { + if ( right.isURIResource() ) { + return prefixMapping.shortForm( left.asResource().getURI() ).compareTo( prefixMapping.shortForm( right.asResource() + .getURI() ) ); + } else if ( right.isAnon() ) { + return -1; // uris first + } + } else if ( left.isAnon() ) { + if ( right.isAnon() ) { + if ( blankNodeOrdering != null ) { + return Optional.ofNullable( blankNodeOrdering.getOrder( left.asResource().asNode() ) ) + .orElse( Long.MAX_VALUE ) + .compareTo( Optional.ofNullable( + blankNodeOrdering.getOrder( right.asResource().asNode() ) ) + .orElse( Long.MAX_VALUE ) ); + } + } else if ( right.isResource() ) { + return 1; // uris first + } + } + // fall-through for all other cases, especially if we don't have a blank node ordering + return left.toString().compareTo( right.toString() ); + } + } +} diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java new file mode 100644 index 00000000..ff36e757 --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java @@ -0,0 +1,981 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter; + +import cool.rdf.core.model.RdfPrefix; +import cool.rdf.formatter.blanknode.BlankNodeMetadata; +import cool.rdf.formatter.blanknode.BlankNodeOrderAwareTurtleParser; +import lombok.AllArgsConstructor; +import lombok.Value; +import lombok.With; +import org.apache.jena.atlas.io.AWriter; +import org.apache.jena.atlas.lib.Pair; +import org.apache.jena.irix.IRIException; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFList; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.riot.out.NodeFormatterTTL; +import org.apache.jena.riot.system.PrefixLib; +import org.apache.jena.riot.system.PrefixMap; +import org.apache.jena.riot.system.PrefixMapAdapter; +import org.apache.jena.riot.system.PrefixMapBase; +import org.apache.jena.shared.PrefixMapping; +import org.apache.jena.vocabulary.RDF; +import org.apache.jena.vocabulary.XSD; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.function.Predicate.not; + +public class TurtleFormatter implements Function, BiConsumer { + + public static final String OUTPUT_ERROR_MESSAGE = "Could not write to stream"; + + public static final String DEFAULT_EMPTY_BASE = "urn:cool-rdf:empty"; + + private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class ); + + private static final Pattern XSD_DECIMAL_UNQUOTED_REGEX = Pattern.compile( "[+-]?\\d*\\.\\d+" ); + + private static final Pattern XSD_DOUBLE_UNQUOTED_REGEX = Pattern.compile( "(([+-]?\\d+\\.\\d+)|([+-]?\\.\\d+)|" + + "([+-]?\\d+))[eE][+-]?\\d+" ); + + /** + * String escape sequences as described in Escape Sequences. + *

+ * ' (single quote) is not in the pattern, because we never write single quoted strings and therefore don't need to + * escape single quotes. + *

+ */ + private static final Pattern STRING_ESCAPE_SEQUENCES = Pattern.compile( "(\r\n)|[\t\b\n\r\f\"\\\\]" ); + + private final FormattingStyle style; + + private final String beforeDot; + + private final String endOfLine; + + private final java.nio.charset.Charset encoding; + + private final Comparator> prefixOrder; + + private final Comparator objectOrder; + + public TurtleFormatter( final FormattingStyle style ) { + this.style = style; + + endOfLine = switch ( style.endOfLine ) { + case CR -> "\r"; + case LF -> "\n"; + case CRLF -> "\r\n"; + }; + + beforeDot = switch ( style.beforeDot ) { + case SPACE -> " "; + case NOTHING -> ""; + case NEWLINE -> endOfLine; + }; + + encoding = switch ( style.charset ) { + case UTF_8, UTF_8_BOM -> StandardCharsets.UTF_8; + case LATIN1 -> StandardCharsets.ISO_8859_1; + case UTF_16_BE -> StandardCharsets.UTF_16BE; + case UTF_16_LE -> StandardCharsets.UTF_16LE; + }; + + prefixOrder = Comparator.>comparingInt( entry -> style.prefixOrder.contains( entry.getKey() ) + ? style.prefixOrder.indexOf( entry.getKey() ) + : Integer.MAX_VALUE ).thenComparing( Map.Entry::getKey ); + + objectOrder = Comparator.comparingInt( object -> style.objectOrder.contains( object ) + ? style.objectOrder.indexOf( object ) + : Integer.MAX_VALUE ); + } + + private static List statements( final Model model ) { + return model.listStatements().toList(); + } + + private static List statements( final Model model, final Property predicate, final RDFNode object ) { + return model.listStatements( null, predicate, object ).toList(); + } + + /** + * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle}.
+ * Note: Using this method, ordering of blank nodes may differ between multiple runs using identical data. + * + * @param model the model to serialize. + * @return the formatted TTL serialization of the model + */ + @Override + public String apply( final Model model ) { + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + accept( model, outputStream ); + return outputStream.toString(); + } + + /** + * Format the specified TTL content according to the {@link TurtleFormatter}'s {@link FormattingStyle}. + * + * @param content RDF content in TTL format. + * @return the formatted content + */ + public String applyToContent( final String content ) { + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + process( content, outputStream ); + return outputStream.toString(); + } + + private void process( final String content, final ByteArrayOutputStream outputStream ) { + if ( style.charset == FormattingStyle.Charset.UTF_8_BOM ) { + writeByteOrderMark( outputStream ); + } + final BlankNodeOrderAwareTurtleParser.ParseResult result = BlankNodeOrderAwareTurtleParser.parseModel( content ); + final Model model = result.getModel(); + final BlankNodeMetadata blankNodeMetadata = result.getBlankNodeMetadata(); + final PrefixMapping prefixMapping = buildPrefixMapping( model ); + final RDFNodeComparatorFactory RDFNodeComparatorFactory = new RDFNodeComparatorFactory( prefixMapping, + blankNodeMetadata ); + doFormat( model, outputStream, prefixMapping, RDFNodeComparatorFactory, blankNodeMetadata ); + } + + private void writeByteOrderMark( final OutputStream outputStream ) { + try { + outputStream.write( new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF } ); + } catch ( final IOException exception ) { + LOG.error( OUTPUT_ERROR_MESSAGE, exception ); + } + } + + /** + * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle} and + * writes it to the specified outputStream.
+ * Note: Using this method, ordering of blank nodes may differ between multiple runs using identical data. + * + * @param model the model to serialize. + * @param outputStream the stream to write to + */ + @Override + public void accept( final Model model, final OutputStream outputStream ) { + if ( style.charset == FormattingStyle.Charset.UTF_8_BOM ) { + writeByteOrderMark( outputStream ); + } + + final PrefixMapping prefixMapping = buildPrefixMapping( model ); + final RDFNodeComparatorFactory RDFNodeComparatorFactory = new RDFNodeComparatorFactory( prefixMapping ); + doFormat( model, outputStream, prefixMapping, RDFNodeComparatorFactory, BlankNodeMetadata.gotNothing() ); + } + + private void doFormat( final Model model, final OutputStream outputStream, final PrefixMapping prefixMapping, + final RDFNodeComparatorFactory RDFNodeComparatorFactory, final BlankNodeMetadata blankNodeMetadata ) { + final Comparator predicateOrder = Comparator.comparingInt( property -> style.predicateOrder.contains( property ) + ? style.predicateOrder.indexOf( property ) + : Integer.MAX_VALUE ).thenComparing( property -> prefixMapping.shortForm( property.getURI() ) ); + final State initialState = buildInitialState( model, outputStream, prefixMapping, predicateOrder, + RDFNodeComparatorFactory, blankNodeMetadata ); + final State prefixesWritten = writePrefixes( initialState ); + final List statements = determineStatements( model, RDFNodeComparatorFactory ); + final State namedResourcesWritten = writeNamedResources( prefixesWritten, statements ); + final State allResourcesWritten = writeAnonymousResources( namedResourcesWritten ); + final State finalState = style.insertFinalNewline ? allResourcesWritten.newLine() : allResourcesWritten; + LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), + finalState.identifiedAnonymousResources.size() ); + } + + private State writeAnonymousResources( final State state ) { + State currentState = state; + final List sortedAnonymousIdentifiedResources = state.identifiedAnonymousResources + .keySet() + .stream() + .sorted( state.getRDFNodeComparatorFactory().comparator() ) + .toList(); + for ( final Resource resource : sortedAnonymousIdentifiedResources ) { + if ( !resource.listProperties().hasNext() ) { + continue; + } + currentState = writeSubject( resource, currentState.withIndentationLevel( 0 ) ); + } + return currentState; + } + + private State writeNamedResources( final State state, final List statements ) { + State currentState = state; + for ( final Statement statement : statements ) { + final Resource resource = statement.getSubject(); + if ( !resource.listProperties().hasNext() || currentState.visitedResources.contains( resource ) ) { + continue; + } + if ( resource.isURIResource() ) { + currentState = writeSubject( resource, currentState.withIndentationLevel( 0 ) ); + continue; + } + final State resourceWritten = writeAnonymousResource( resource, currentState.withIndentationLevel( 0 ) ); + final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.containsKey( resource ); + currentState = writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); + } + return currentState; + } + + private List determineStatements( final Model model, + final RDFNodeComparatorFactory rdfNodeComparatorFactory ) { + final Stream wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> statements( model, RDF.type, + subjectType ) + .stream() + .sorted( Comparator.comparing( Statement::getSubject, rdfNodeComparatorFactory.comparator() ) ) ); + + final Stream otherSubjects = statements( model ).stream() + .filter( statement -> !( statement.getPredicate().equals( RDF.type ) + && statement.getObject().isResource() + && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) + .sorted( Comparator.comparing( Statement::getSubject, rdfNodeComparatorFactory.comparator() ) ); + + return Stream.concat( wellKnownSubjects, otherSubjects ) + .filter( statement -> !( statement.getSubject().isAnon() + && model.contains( null, null, statement.getSubject() ) ) ) + .toList(); + } + + private State buildInitialState( final Model model, final OutputStream outputStream, + final PrefixMapping prefixMapping, final Comparator predicateOrder, + final RDFNodeComparatorFactory RDFNodeComparatorFactory, final BlankNodeMetadata blankNodeMetadata ) { + State currentState = new State( outputStream, model, predicateOrder, prefixMapping, RDFNodeComparatorFactory, + blankNodeMetadata ); + int i = 0; + final Set blankNodeLabelsInInput = blankNodeMetadata.getAllBlankNodeLabels(); + for ( final Resource r : anonymousResourcesThatNeedAnId( model, currentState ) ) { + // use original label if present + String s = blankNodeMetadata.getLabel( r.asNode() ); + if ( s == null ) { + // not a labeled blank node in the input: generate (and avoid collisions) + do { + s = style.anonymousNodeIdGenerator.apply( r, i++ ); + } while ( currentState.identifiedAnonymousResources.containsValue( s ) && blankNodeLabelsInInput.contains( s ) ); + } + currentState = currentState.withIdentifiedAnonymousResource( r, s ); + } + return currentState; + } + + /** + * Anonymous resources that are referred to more than once need to be given an internal id and can not be serialized + * using [ ] notation. + * + * @param model the input model + * @param currentState the state + * @return the set of anonymous resources that are referred to more than once + */ + private Set anonymousResourcesThatNeedAnId( final Model model, final State currentState ) { + final Set identifiedResources = new HashSet<>( currentState.identifiedAnonymousResources.keySet() ); + // needed for cycle detection + final Set candidates = model.listObjects().toList().stream() + .filter( RDFNode::isResource ) + .map( RDFNode::asResource ) + .filter( RDFNode::isAnon ).collect( Collectors.toSet() ); + candidates.removeAll( currentState.getBlankNodeMetadata().getLabeledBlankNodes() ); + final List candidatesInOrder = Stream.concat( + currentState.getBlankNodeMetadata().getLabeledBlankNodes() + .stream() + .sorted( currentState.getRDFNodeComparatorFactory().comparator() ), + candidates + .stream() + .sorted( currentState.getRDFNodeComparatorFactory().comparator() ) ) + .toList(); + for ( final Resource candidate : candidatesInOrder ) { + if ( identifiedResources.contains( candidate ) ) { + continue; + } + if ( statements( model, null, candidate ).size() > 1 || hasBlankNodeCycle( model, candidate, + identifiedResources ) ) { + identifiedResources.add( candidate ); + } + } + identifiedResources.removeAll( currentState.identifiedAnonymousResources.keySet() ); + return identifiedResources; + } + + private boolean hasBlankNodeCycle( final Model model, final Resource start, + final Set identifiedResources ) { + if ( !start.isAnon() ) { + return false; + } + return hasBlankNodeCycle( model, start, start, identifiedResources, new HashSet<>() ); + } + + private boolean hasBlankNodeCycle( final Model model, final Resource resource, final Resource target, + final Set identifiedResources, final Set visited ) { + if ( visited.contains( resource ) ) { + return false; + } + visited.add( resource ); + return model.listStatements( resource, null, (RDFNode) null ) + .toList().stream() + .map( Statement::getObject ) + .filter( RDFNode::isAnon ) + .map( RDFNode::asResource ) + .filter( not( identifiedResources::contains ) ) + .anyMatch( o -> target.equals( o ) || hasBlankNodeCycle( model, o, target, identifiedResources, visited ) ); + } + + private PrefixMapping buildPrefixMapping( final Model model ) { + final Map prefixMap = style.knownPrefixes.stream() + .filter( prefix -> model.getNsPrefixURI( prefix.prefix() ) == null ) + .collect( Collectors.toMap( RdfPrefix::prefix, RdfPrefix::uri ) ); + return PrefixMapping.Factory.create().setNsPrefixes( model.getNsPrefixMap() ) + .setNsPrefixes( prefixMap ); + } + + private State writePrefixes( final State state ) { + final Map prefixes = state.prefixMapping.getNsPrefixMap(); + final int maxPrefixLength = prefixes.keySet().stream().map( String::length ).max( Integer::compareTo ).orElse( 0 ); + final String prefixFormat = switch ( style.alignPrefixes ) { + case OFF -> "@prefix %s: <%s>" + beforeDot + "." + endOfLine; + case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + "." + endOfLine; + case RIGHT -> "@prefix %" + maxPrefixLength + "s: <%s>" + beforeDot + "." + endOfLine; + }; + + final List urisInModel = allUsedUris( state.model ); + + final List> entries = prefixes.entrySet().stream().sorted( prefixOrder ) + .filter( entry -> style.keepUnusedPrefixes || + urisInModel.stream().anyMatch( resource -> resource.startsWith( entry.getValue() ) ) ) + .toList(); + State currentState = state; + for ( final Map.Entry entry : entries ) { + currentState = currentState.write( String.format( prefixFormat, entry.getKey(), entry.getValue() ) ); + } + currentState = currentState.newLine(); + return currentState; + } + + private List allUsedUris( final Model model ) { + return model.listStatements().toList().stream() + .flatMap( statement -> Stream.of( statement.getSubject(), statement.getPredicate(), + statement.getObject() ) ) + .>map( rdfNode -> { + if ( rdfNode.isURIResource() ) { + return Optional.of( rdfNode.asResource().getURI() ); + } + if ( rdfNode.isLiteral() ) { + return Optional.of( rdfNode.asLiteral().getDatatypeURI() ); + } + return Optional.empty(); + } ) + .filter( Optional::isPresent ) + .map( Optional::get ) + .toList(); + } + + private String indent( final int level ) { + final String singleIndent = switch ( style.indentStyle ) { + case SPACE -> " ".repeat( style.indentSize ); + case TAB -> "\t"; + }; + return singleIndent.repeat( Math.max( level, 0 ) ); + } + + private String continuationIndent( final int level ) { + final String continuation = switch ( style.indentStyle ) { + case SPACE -> " ".repeat( style.continuationIndentSize ); + case TAB -> "\t".repeat( 2 ); + }; + return indent( level - 1 ) + continuation; + } + + private State writeDelimiter( final String delimiter, final FormattingStyle.GapStyle before, + final FormattingStyle.GapStyle after, final String indentation, + final State state ) { + final State beforeState = switch ( before ) { + case SPACE -> state.lastCharacter.equals( " " ) ? state : state.write( " " ); + case NOTHING -> state; + case NEWLINE -> state.newLine().write( indentation ); + }; + + return switch ( after ) { + case SPACE -> beforeState.write( delimiter + " " ); + case NOTHING -> beforeState.write( delimiter ); + case NEWLINE -> beforeState.write( delimiter ).newLine().write( indentation ); + }; + } + + private State writeComma( final State state ) { + return writeDelimiter( ",", style.beforeComma, style.afterComma, + continuationIndent( state.indentationLevel ), state ); + } + + private State writeSemicolon( final State state, final boolean omitLineBreak, + final boolean omitSpaceBeforeSemicolon, final String nextLineIndentation ) { + final FormattingStyle.GapStyle beforeSemicolon = omitSpaceBeforeSemicolon + ? FormattingStyle.GapStyle.NOTHING + : style.beforeSemicolon; + final FormattingStyle.GapStyle afterSemicolon = omitLineBreak + ? FormattingStyle.GapStyle.NOTHING + : style.afterSemicolon; + return writeDelimiter( ";", beforeSemicolon, afterSemicolon, nextLineIndentation, state ); + } + + private State writeDot( final State state, final boolean omitSpaceBeforeDot ) { + final FormattingStyle.GapStyle beforeDot = omitSpaceBeforeDot + ? FormattingStyle.GapStyle.NOTHING + : style.beforeDot; + return writeDelimiter( ".", beforeDot, style.afterDot, "", state ); + } + + private State writeOpeningSquareBracket( final State state ) { + final FormattingStyle.GapStyle beforeBracket = state.indentationLevel > 0 + ? style.beforeOpeningSquareBracket + : FormattingStyle.GapStyle.NOTHING; + return writeDelimiter( "[", beforeBracket, style.afterOpeningSquareBracket, + indent( state.indentationLevel ), state ); + } + + private State writeClosingSquareBracket( final State state ) { + return writeDelimiter( "]", style.beforeClosingSquareBracket, style.afterClosingSquareBracket, + indent( state.indentationLevel ), state ); + } + + private boolean isList( final RDFNode node, final State state ) { + if ( !node.isResource() ) { + return false; + } + if ( node.equals( RDF.nil ) ) { + return true; + } + final boolean listNodeHasAdditionalTriples = state.model.listStatements( node.asResource(), null, (RDFNode) null ) + .toList() + .stream() + .map( Statement::getPredicate ) + .filter( p -> !p.equals( RDF.first ) ) + .anyMatch( p -> !p.equals( RDF.rest ) ); + if ( listNodeHasAdditionalTriples ) { + return false; + } + return ( node.isAnon() + && state.model.contains( node.asResource(), RDF.rest, (RDFNode) null ) ); + } + + private State writeResource( final Resource resource, final State state ) { + if ( isList( resource, state ) ) { + return writeList( resource, state ); + } + if ( resource.isURIResource() ) { + return writeUriResource( resource, state ); + } + return writeAnonymousResource( resource, state ); + } + + private State writeList( final Resource resource, final State state ) { + final FormattingStyle.GapStyle afterOpeningParenthesis = style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS + ? FormattingStyle.GapStyle.NOTHING + : style.afterOpeningParenthesis; + final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, afterOpeningParenthesis, + continuationIndent( state.indentationLevel ), state ); + final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); + + int index = 0; + State currentState = opened; + for ( final RDFNode element : elementList ) { + final boolean firstElement = index == 0; + currentState = writeListElement( element, firstElement, currentState ); + index++; + } + + final State finalLineBreakWritten = style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS + ? currentState.newLine().write( indent( currentState.indentationLevel ) ) + : currentState; + + return writeDelimiter( ")", style.beforeClosingParenthesis, style.afterClosingParenthesis, + continuationIndent( state.indentationLevel ), finalLineBreakWritten ); + } + + private State writeListElement( final RDFNode element, final boolean firstElement, final State state ) { + return switch ( style.wrapListItems ) { + case NEVER: + final State spaceWritten = firstElement ? state : state.write( " " ); + yield writeRdfNode( element, spaceWritten ); + case ALWAYS: + yield writeRdfNode( element, state.newLine().write( continuationIndent( state.indentationLevel ) ) ); + case FOR_LONG_LINES: + final int alignmentAfterElementIsWritten = writeRdfNode( element, + state.withOutputStream( OutputStream.nullOutputStream() ) ).alignment; + final boolean wouldElementExceedLineLength = ( alignmentAfterElementIsWritten + 1 ) > style.maxLineLength; + yield writeRdfNode( element, wouldElementExceedLineLength + ? state.newLine().write( continuationIndent( state.indentationLevel ) ) + : ( firstElement || state.getLastCharacter().equals( " " ) ? state : state.write( " " ) ) ); + }; + } + + private State writeAnonymousResource( final Resource resource, final State state ) { + if ( state.identifiedAnonymousResources.containsKey( resource ) ) { + return state.write( "_:" + state.identifiedAnonymousResources.getOrDefault( resource, "" ) ); + } + + if ( !state.model.contains( resource, null, (RDFNode) null ) ) { + return state.write( " []" ); + + } + if ( state.visitedResources.contains( resource ) ) { + return state; + } + final State afterOpeningSquareBracket = writeOpeningSquareBracket( state ); + final State afterContent = writeSubject( resource, afterOpeningSquareBracket ); + return writeClosingSquareBracket( afterContent ).withVisitedResource( resource ); + } + + private String uriResource( final Resource resource, final State state ) { + final String uri = resource.getURI(); + // Workaround to force writing out URIs without a base that is "automatically determined" by Jena: + // when calling model.read(inputStream, base, language) and passing an empty String as base, Jena will + // replace that with something "smart" such as the current directory. + final String uriWithoutEmptyBase = uri.startsWith( style.emptyRdfBase ) + ? uri.substring( style.emptyRdfBase.length() ) + : uri; + final String shortForm = state.prefixMapping.shortForm( uriWithoutEmptyBase ); + if ( shortForm.equals( uriWithoutEmptyBase ) ) { + return "<" + uriWithoutEmptyBase + ">"; + } + // All other cases are delegated to Jena RIOT + final NodeFormatterTTL formatter = new NodeFormatterTTL( "", new CustomPrefixMap( state.prefixMapping ) ); + final NodeFormatterSink sink = new NodeFormatterSink(); + try { + formatter.formatURI( sink, uri ); + } catch ( final IRIException exception ) { + // The formatter encountered an invalid IRI. This should not have happend in the first place, i.e., + // it should not be present in the model. Since this should have been fixed by the parser, we handle + // it the same was as Jena Core: Still print it out. + return "<" + uri + ">"; + } + return sink.buffer.toString(); + } + + /** + * Unfortunately, the logic in {@link PrefixMapAdapter#abbrev(String)} is broken and won't return a prefix even if + * one exists in the wrapped map; and the class is final, so we can't overwrite the method. + */ + static class CustomPrefixMap extends PrefixMapBase implements PrefixMap { + private final PrefixMapping mapping; + + public CustomPrefixMap( final PrefixMapping mapping ) { + this.mapping = mapping; + } + + @Override + public String get( final String prefix ) { + return mapping.getNsPrefixURI( prefix ); + } + + @Override + public Map getMapping() { + return mapping.getNsPrefixMap(); + } + + @Override + public void add( final String prefix, final String iriString ) { + } + + @Override + public void delete( final String prefix ) { + } + + @Override + public void clear() { + } + + @Override + public boolean containsPrefix( final String prefix ) { + return mapping.getNsPrefixMap().containsKey( prefix ); + } + + @Override + public boolean isEmpty() { + return mapping.getNsPrefixMap().isEmpty(); + } + + @Override + public int size() { + return mapping.getNsPrefixMap().size(); + } + + @Override + public Pair abbrev( final String uriStr ) { + return PrefixLib.abbrev( this, uriStr ); + } + } + + private State writeUriResource( final Resource resource, final State state ) { + return state.write( uriResource( resource, state ) ); + } + + private State writeLiteral( final Literal literal, final State state ) { + final String datatypeUri = literal.getDatatypeURI(); + if ( datatypeUri.equals( XSD.xdouble.getURI() ) ) { + if ( style.enableDoubleFormatting ) { + return state.write( style.doubleFormat.format( literal.getDouble() ) ); + } else if ( XSD_DOUBLE_UNQUOTED_REGEX.matcher( literal.getLexicalForm() ).matches() ) { + // only use unquoted form if it will be parsed as an xsd:double + return state.write( literal.getLexicalForm() ); + } + } + if ( datatypeUri.equals( XSD.xboolean.getURI() ) ) { + return state.write( literal.getBoolean() ? "true" : "false" ); + } + if ( datatypeUri.equals( XSD.xstring.getURI() ) ) { + return state.write( quoteAndEscape( literal ) ); + } + if ( datatypeUri.equals( XSD.decimal.getURI() ) ) { + if ( XSD_DECIMAL_UNQUOTED_REGEX.matcher( literal.getLexicalForm() ).matches() ) { + // only use unquoted form if it will be parsed as an xsd:decimal + return state.write( literal.getLexicalForm() ); + } + } + if ( datatypeUri.equals( XSD.integer.getURI() ) ) { + return state.write( literal.getLexicalForm() ); + } + if ( datatypeUri.equals( RDF.langString.getURI() ) ) { + return state.write( quoteAndEscape( literal ) + "@" + literal.getLanguage() ); + } + + final Resource typeResource = ResourceFactory.createResource( datatypeUri ); + final State literalWritten = state.write( quoteAndEscape( literal ) + "^^" ); + return writeUriResource( typeResource, literalWritten ); + } + + private String quoteAndEscape( final RDFNode node ) { + final String value = node.asNode().getLiteralLexicalForm(); + final String quote = switch ( style.quoteStyle ) { + case ALWAYS_SINGE_QUOTES -> "\""; + case ALWAYS_TRIPLE_QUOTES -> "\"\"\""; + case TRIPLE_QUOTES_FOR_MULTILINE -> ( value.contains( "\n" ) || value.contains( "\r" ) ) ? "\"\"\"" : "\""; + }; + + final Map characterReplacements = Map.of( + "\t", "\\\\t", + "\b", "\\\\b", + "\r", quote.equals( "\"" ) ? "\\\\r" : "\n", // in multiline strings that were read with mac style endings, + // replace \r with \n + "\r\n", quote.equals( "\"" ) ? "\\\\r\\\\n" : "\n", // in multiline strings that were read with windows + // style endings, replace \r\n with \n + "\f", "\\\\f", + "\n", quote.equals( "\"" ) ? "\\\\n" : "\n", // Don't escape line breaks in triple-quoted strings + "\"", quote.equals( "\"" ) ? "\\\\\"" : "\"", // Don't escape quotes in triple-quoted strings + "\\", "\\\\\\\\" ); + + final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> characterReplacements.getOrDefault( match + .group(), match.group() ) ); + + // Special case: If the last character in the triple-quoted string is a quote, it must be escaped + // See https://github.com/atextor/turtle-formatter/issues/9 + final String result = quote.equals( "\"\"\"" ) && escapedValue.endsWith( "\"" ) + ? escapedValue.substring( 0, escapedValue.length() - 1 ) + "\\\"" + : escapedValue; + return quote + result + quote; + } + + private State writeRdfNode( final RDFNode node, final State state ) { + if ( node.isResource() ) { + return writeResource( node.asResource(), state ); + } + + if ( node.isLiteral() ) { + return writeLiteral( node.asLiteral(), state ); + } + + return state; + } + + private State writeProperty( final Property property, final State state ) { + if ( property.getURI().equals( RDF.type.getURI() ) && style.useAForRdfType ) { + return state.write( "a" ); + } + return writeUriResource( property, state ); + } + + private State writeSubject( final Resource resource, final State state ) { + if ( state.visitedResources.contains( resource ) ) { + return state; + } + + // indent + final boolean isIdentifiedAnon = state.identifiedAnonymousResources.containsKey( resource ); + final boolean subjectsNeedsIdentation = !resource.isAnon() || isIdentifiedAnon; + final State indentedSubject = subjectsNeedsIdentation ? state.write( indent( state.indentationLevel ) ) : state; + // subject + final State stateWithSubject = resource.isURIResource() || isIdentifiedAnon + ? writeResource( resource, indentedSubject ).withVisitedResource( resource ) + : indentedSubject.withVisitedResource( resource ); + + final State gapAfterSubject = style.firstPredicateInNewLine || ( resource.isAnon() && !isIdentifiedAnon ) + ? stateWithSubject + : stateWithSubject.write( " " ); + + final int predicateAlignment = style.firstPredicateInNewLine ? style.indentSize : gapAfterSubject.alignment; + + // predicates and objects + final Set properties = resource.listProperties().mapWith( Statement::getPredicate ).toSet(); + + final int maxPropertyWidth = properties.stream().map( property -> uriResource( property, state ) ).map( String::length ).max( + Integer::compareTo ).orElse( 0 ); + + int index = 0; + State currentState = gapAfterSubject.addIndentationLevel(); + for ( final Property property : properties.stream().sorted( state.predicateOrder ).toList() ) { + final boolean firstProperty = index == 0; + final boolean lastProperty = index == properties.size() - 1; + final int propertyWidth = uriResource( property, currentState ).length(); + final String gapAfterPredicate = style.alignObjects + ? " ".repeat( maxPropertyWidth - propertyWidth + 1 ) + : " "; + currentState = writeProperty( resource, property, firstProperty, lastProperty, predicateAlignment, + gapAfterPredicate, currentState ); + index++; + } + return currentState; + } + + private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, + final boolean lastProperty, final int alignment, + final String gapAfterPredicate, final State state ) { + final Set objects = subject.listProperties( predicate ).mapWith( Statement::getObject ).toSet(); + + final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) + || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); + + final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine && !subject.isAnon() + ? state.newLine() + : state; + + final boolean isNamedAnon = state.identifiedAnonymousResources.containsKey( subject ); + final boolean inBrackets = subject.isAnon() && !isNamedAnon; + + final boolean shouldIndentFirstPropertyByLevel = firstProperty && + ( ( style.firstPredicateInNewLine && !inBrackets ) + || ( inBrackets && state.indentationLevel <= 1 ) ); + final boolean shouldIndentOtherPropertyByLevel = !firstProperty && + ( inBrackets || isNamedAnon ); + + final State indentedPredicateByLevel = shouldIndentFirstPropertyByLevel || shouldIndentOtherPropertyByLevel + ? wrappedPredicate.write( indent( state.indentationLevel ) ) + : wrappedPredicate; + + final boolean shouldIndentFirstPropertyOnce = firstProperty && + ( inBrackets && state.indentationLevel > 1 ); + + final State indentedPredicate = shouldIndentFirstPropertyOnce + ? indentedPredicateByLevel.write( indent( 1 ) ) + : indentedPredicateByLevel; + + final State predicateAlignment = !firstProperty && style.alignPredicates && !subject.isAnon() + ? indentedPredicate.write( " ".repeat( alignment ) ) + : indentedPredicate; + + final State predicateWrittenOnce = useComma + ? writeProperty( predicate, predicateAlignment ).write( gapAfterPredicate ) + : predicateAlignment; + + int index = 0; + State currentState = predicateWrittenOnce; + for ( final RDFNode object : objects.stream().sorted( objectOrder.thenComparing( + state.getRDFNodeComparatorFactory().comparator() ) ).toList() ) { + final boolean lastObject = index == objects.size() - 1; + final State predicateWritten = useComma ? currentState : writeProperty( predicate, currentState ); + + final boolean isAnonWithBrackets = object.isAnon() + && !predicateWritten.identifiedAnonymousResources.containsKey( object.asResource() ); + final boolean isList = isList( object, predicateWritten ); + final State spaceWritten = !isAnonWithBrackets && !isList && !useComma + ? predicateWritten.write( gapAfterPredicate ) + : predicateWritten; + + final State objectWritten = writeRdfNode( object, spaceWritten ); + if ( useComma && !lastObject ) { + currentState = writeComma( objectWritten ); + index++; + continue; + } + + final boolean listWritten = isList && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING; + final boolean omitSpaceBeforeDelimiter = object.isResource() + && object.isAnon() + && !listWritten + && !currentState.identifiedAnonymousResources.containsKey( object.asResource() ); + if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { + currentState = writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); + index++; + continue; + } + final boolean doAlign = style.alignPredicates || subject.isAnon(); + final boolean moreIdenticalPredicatesRemaining = subject.listProperties( predicate ).toList().size() > 1 && !lastObject; + final boolean isAnonOrLastObject = ( subject.isAnon() || lastObject ) && !moreIdenticalPredicatesRemaining; + final String nextLineIndentation = doAlign && isAnonOrLastObject + ? "" + : indent( objectWritten.indentationLevel ); + final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, + omitSpaceBeforeDelimiter, nextLineIndentation ); + currentState = subject.isAnon() && lastProperty && !moreIdenticalPredicatesRemaining + ? semicolonWritten.removeIndentationLevel() + : semicolonWritten; + index++; + } + return currentState; + } + + class NodeFormatterSink implements AWriter { + StringBuffer buffer = new StringBuffer(); + + @Override + public void write( final char ch ) { + buffer.append( ch ); + } + + @Override + public void write( final char[] cbuf ) { + buffer.append( cbuf ); + } + + @Override + public void write( final String string ) { + buffer.append( string ); + } + + @Override + public void print( final char ch ) { + write( ch ); + } + + @Override + public void print( final char[] cbuf ) { + write( cbuf ); + } + + @Override + public void print( final String string ) { + write( string ); + } + + @Override + public void printf( final String fmt, final Object... arg ) { + write( String.format( fmt, arg ) ); + } + + @Override + public void println( final String object ) { + write( object + endOfLine ); + } + + @Override + public void println() { + write( endOfLine ); + } + + @Override + public void flush() { + } + + @Override + public void close() { + } + } + + @Value + @With + @AllArgsConstructor + private class State { + OutputStream outputStream; + + Model model; + + Set visitedResources; + + Map identifiedAnonymousResources; + + Comparator predicateOrder; + + PrefixMapping prefixMapping; + + RDFNodeComparatorFactory RDFNodeComparatorFactory; + + BlankNodeMetadata blankNodeMetadata; + + int indentationLevel; + + int alignment; + + String lastCharacter; + + public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, + final PrefixMapping prefixMapping, final RDFNodeComparatorFactory RDFNodeComparatorFactory, + final BlankNodeMetadata blankNodeMetadata ) { + this( outputStream, model, Set.of(), Map.of(), predicateOrder, prefixMapping, RDFNodeComparatorFactory, + blankNodeMetadata, 0, 0, "" ); + } + + public State withIdentifiedAnonymousResource( final Resource anonymousResource, final String id ) { + final Map newMap = new HashMap<>( identifiedAnonymousResources ); + newMap.put( anonymousResource, id ); + return withIdentifiedAnonymousResources( newMap ); + } + + public State withVisitedResource( final Resource visitedResource ) { + final Set newSet = new HashSet<>( visitedResources ); + newSet.add( visitedResource ); + return withVisitedResources( newSet ); + } + + public State addIndentationLevel() { + return withIndentationLevel( indentationLevel + 1 ); + } + + public State removeIndentationLevel() { + return withIndentationLevel( indentationLevel - 1 ); + } + + public State newLine() { + return write( endOfLine ).withAlignment( 0 ); + } + + public State write( final String content ) { + final String end = content.length() > 0 ? content.substring( content.length() - 1 ) : ""; + try { + outputStream.write( content.getBytes( encoding ) ); + } catch ( final IOException e ) { + LOG.error( OUTPUT_ERROR_MESSAGE, e ); + } + return withLastCharacter( end ).withAlignment( alignment + content.length() ); + } + } +} diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java new file mode 100644 index 00000000..d95f8b27 --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java @@ -0,0 +1,99 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter.blanknode; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.jena.graph.Node; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; + +/** + * A lookup table for each blank node's order in a TTL file. + */ +public class BlankNodeMetadata { + private final Map blankNodeIndex = new HashMap<>(); + private final Map blankNodeLabels = new HashMap<>(); + private final Set labeledBlankNodes = new HashSet<>(); + private long nextIndex = 0; + + public BlankNodeMetadata() { + } + + public void linkGraphNodesToModelResources( final Model model ) { + labeledBlankNodes.addAll( model.listStatements() + .toList() + .stream() + .flatMap( s -> Stream.of( s.getSubject(), s.getObject() ) ) + .filter( RDFNode::isAnon ) + .filter( a -> blankNodeLabels.containsKey( a.asNode() ) ) + .map( RDFNode::asResource ) + .collect( Collectors.toSet() ) ); + + } + + public static BlankNodeMetadata gotNothing() { + return new BlankNodeMetadata(); + } + + /** + * Returns the order of the specified node, if it has been added previously via {@link #registerNewBlankNode(Node)}, + * or null. + * + * @param node the node to look up + * @return the 0-based order of the {@code node} (or null if it has not been registered) + */ + public Long getOrder( final Node node ) { + return blankNodeIndex.get( node ); + } + + /** + * If the specified {@code node} is a labeled blank node, the label is returned. + * + * @param node + * @return the label or null. + */ + public String getLabel( final Node node ) { + return blankNodeLabels.get( node ); + } + + void registerNewBlankNode( final Node blankNode ) { + if ( blankNode.isBlank() && !blankNodeIndex.containsKey( blankNode ) ) { + blankNodeIndex.put( blankNode, nextIndex++ ); + } + } + + void registerNewBlankNode( final Node blankNode, final String label ) { + registerNewBlankNode( blankNode ); + blankNodeLabels.put( blankNode, label ); + } + + public Set getLabeledBlankNodes() { + return Collections.unmodifiableSet( labeledBlankNodes ); + } + + public Set getAllBlankNodeLabels() { + return Set.copyOf( blankNodeLabels.values() ); + } +} diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java new file mode 100644 index 00000000..a064e0a4 --- /dev/null +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java @@ -0,0 +1,133 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter.blanknode; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.Reader; + +import org.apache.jena.atlas.web.ContentType; +import org.apache.jena.graph.Graph; +import org.apache.jena.graph.Node; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.LangBuilder; +import org.apache.jena.riot.RDFParser; +import org.apache.jena.riot.RDFParserRegistry; +import org.apache.jena.riot.ReaderRIOT; +import org.apache.jena.riot.lang.LabelToNode; +import org.apache.jena.riot.lang.LangRIOT; +import org.apache.jena.riot.lang.LangTurtle; +import org.apache.jena.riot.lang.RiotParsers; +import org.apache.jena.riot.system.ParserProfile; +import org.apache.jena.riot.system.ParserProfileWrapper; +import org.apache.jena.riot.system.StreamRDF; +import org.apache.jena.riot.tokens.Token; +import org.apache.jena.riot.tokens.TokenType; +import org.apache.jena.riot.tokens.Tokenizer; +import org.apache.jena.riot.tokens.TokenizerText; +import org.apache.jena.sparql.util.Context; + +public class BlankNodeOrderAwareTurtleParser { + /** + * Parses the TTL content and returns a {@link ParseResult}, containing the new {@link Model} and a + * {@link BlankNodeMetadata} object that makes the ordering of the blank nodes in the original content + * accessible for further processing. + * + * @param content RDF in TTL format + * @return the parse result and the blank node ordering + */ + public static ParseResult parseModel( final String content ) { + final BlankNodeMetadata bnodeMetadata = new BlankNodeMetadata(); + + final Lang TTL_bn = LangBuilder.create( "TTL_BN", "text/bogus" ) + .build(); + RDFParserRegistry.registerLangTriples( TTL_bn, ( language, profile ) -> { + final ParserProfile profileWrapper = new ParserProfileWrapper( profile ) { + @Override + public Node createBlankNode( final Node scope, final String label, final long line, final long col ) { + final Node blank = get().createBlankNode( scope, label, line, col ); + bnodeMetadata.registerNewBlankNode( blank, label ); + return blank; + } + + @Override + public Node createBlankNode( final Node scope, final long line, final long col ) { + final Node blank = get().createBlankNode( scope, line, col ); + bnodeMetadata.registerNewBlankNode( blank ); + return blank; + } + + @Override + public Node create( final Node currentGraph, final Token token ) { + // Dispatches to the underlying ParserFactory operation + final long line = token.getLine(); + final long col = token.getColumn(); + final String str = token.getImage(); + if ( token.getType() == TokenType.BNODE ) { + return createBlankNode( currentGraph, str, line, col ); + } + return get().create( currentGraph, token ); + } + + }; + return new ReaderRIOT() { + @Override + public void read( final InputStream in, final String baseURI, final ContentType ct, final StreamRDF output, + final Context context ) { + Tokenizer tokenizer = TokenizerText.create().source( in ).errorHandler( profileWrapper.getErrorHandler() ).build(); + LangRIOT parser = new LangTurtle( tokenizer, profileWrapper, output ); + parser.parse(); + } + + @Override + public void read( final Reader reader, final String baseURI, final ContentType ct, final StreamRDF output, + final Context context ) { + Tokenizer tokenizer = TokenizerText.create().source( reader ).errorHandler( profileWrapper.getErrorHandler() ).build(); + LangRIOT parser = new LangTurtle( tokenizer, profileWrapper, output ); + parser.parse(); + } + }; + } ); + final Graph graph = RDFParser.source( new ByteArrayInputStream( content.getBytes() ) ).labelToNode( LabelToNode + .createUseLabelAsGiven() ) + .lang( TTL_bn ).toGraph(); + RDFParserRegistry.removeRegistration( TTL_bn ); + final Model model = ModelFactory.createModelForGraph( graph ); + bnodeMetadata.linkGraphNodesToModelResources( model ); + return new ParseResult( model, bnodeMetadata ); + } + + public static class ParseResult { + private final Model model; + private final BlankNodeMetadata blankNodeMetadata; + + public ParseResult( final Model model, final BlankNodeMetadata blankNodeMetadata ) { + this.model = model; + this.blankNodeMetadata = blankNodeMetadata; + } + + public Model getModel() { + return model; + } + + public BlankNodeMetadata getBlankNodeMetadata() { + return blankNodeMetadata; + } + } +} diff --git a/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterPropertyTest.java b/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterPropertyTest.java new file mode 100644 index 00000000..afd0e21c --- /dev/null +++ b/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterPropertyTest.java @@ -0,0 +1,236 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.formatter; + +import net.jqwik.api.Arbitraries; +import net.jqwik.api.Arbitrary; +import net.jqwik.api.Combinators; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; +import net.jqwik.api.Provide; +import org.apache.jena.datatypes.xsd.XSDDatatype; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; + +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.util.List; +import java.util.function.Supplier; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.fail; + +public class TurtleFormatterPropertyTest { + @Provide + Arbitrary anyString() { + return Arbitraries.strings().all().ofMaxLength( 5 ); + } + + @Provide + Arbitrary anyStringLiteral() { + return anyString().map( ResourceFactory::createStringLiteral ); + } + + @Provide + Arbitrary anyLanguageCode() { + return Arbitraries.of( "en", "de" ); + } + + @Provide + Arbitrary anyLangStringLiteral() { + return Combinators.combine( anyString(), anyLanguageCode() ).as( ResourceFactory::createLangLiteral ); + } + + @Provide + Arbitrary anyFloatLiteral() { + return Arbitraries.floats() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDfloat ) ); + } + + + @Provide + Arbitrary anyDoubleLiteral() { + return Arbitraries.doubles() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDdouble ) ); + } + + // Providing only one for each of the integer number types is sufficient for testing the formatter + // as there is no variation in their serialization, but greatly reduces the test space + @Provide + Arbitrary anyIntegerNumberLiteral() { + return Arbitraries.of( + ResourceFactory.createTypedLiteral( "1", XSDDatatype.XSDint ), + ResourceFactory.createTypedLiteral( "2", XSDDatatype.XSDlong ), + ResourceFactory.createTypedLiteral( "3", XSDDatatype.XSDshort ), + ResourceFactory.createTypedLiteral( "4", XSDDatatype.XSDbyte ), + ResourceFactory.createTypedLiteral( "5", XSDDatatype.XSDunsignedByte ), + ResourceFactory.createTypedLiteral( "6", XSDDatatype.XSDunsignedInt ), + ResourceFactory.createTypedLiteral( "7", XSDDatatype.XSDunsignedLong ), + ResourceFactory.createTypedLiteral( "8", XSDDatatype.XSDunsignedShort ) + ); + } + + @Provide + Arbitrary anyLiteral() { + return Arbitraries.oneOf( List.of( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), + anyDoubleLiteral(), anyIntegerNumberLiteral() ) ); + } + + @Provide + Arbitrary anyAnonymousResource() { + return Arbitraries.of( ResourceFactory.createResource() ); + } + + @Provide + Arbitrary anyUrl() { + return Arbitraries.integers().between( 0, 10 ).map( number -> "http://example.com/" + number ); + } + + @Provide + Arbitrary anyUrn() { + return Arbitraries.integers().between( 0, 10 ).map( number -> "urn:ex:" + number ); + } + + @Provide + Arbitrary anyUri() { + return Arbitraries.oneOf( List.of( anyUrl(), anyUrn() ) ); + } + + @Provide + Arbitrary anyNamedResource() { + return anyUri().map( ResourceFactory::createResource ); + } + + @Provide + Arbitrary anyResource() { + return Arbitraries.oneOf( List.of( anyAnonymousResource(), anyNamedResource() ) ); + } + + @Provide + Arbitrary anyProperty() { + return anyUri().map( ResourceFactory::createProperty ); + } + + @Provide + Arbitrary anyStatement( final Model model ) { + return Combinators.combine( anyResource(), anyProperty(), anyRdfNode( model ) ) + .as( ResourceFactory::createStatement ); + } + + @Provide + Arbitrary anyList( final Model model ) { + final Supplier> elements = () -> anyRdfNode( model ); + return Arbitraries.lazyOf( elements, elements ).list().ofMaxSize( 3 ) + .map( list -> model.createList( list.iterator() ) ); + } + + @Provide + Arbitrary anyRdfNode( final Model model ) { + return Arbitraries.oneOf( List.of( anyLiteral(), anyResource(), anyList( model ) ) ); + } + + @Provide + Arbitrary> anyListOfStatements( final Model model ) { + return anyStatement( model ).list().ofMaxSize( 5 ); + } + + // Creates styles for some of the options that control the actual formatting and are difficult to test + // in isolation. + @Provide + Arbitrary anyStyle() { + final Arbitrary onOff = Arbitraries.of( true, false ); + + return Combinators.combine( onOff, onOff, onOff, onOff, onOff ) + .as( ( firstPredicateInNewLine, useAForRdfType, useComma, alignPredicates, alignObjects ) -> + FormattingStyle.builder() + .firstPredicateInNewLine( firstPredicateInNewLine ) + .useAForRdfType( useAForRdfType ) + .useCommaByDefault( useComma ) + .alignPredicates( alignPredicates ) + .alignObjects( alignObjects ) + .build() ); + } + + @Provide + Arbitrary anyModel() { + final Model model = ModelFactory.createDefaultModel(); + return anyListOfStatements( model ).map( statements -> { + model.add( statements ); + return model; + } ); + } + + @Property( tries = 300 ) + public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model, + @ForAll( "anyStyle" ) final FormattingStyle style ) { + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model newModel = ModelFactory.createDefaultModel(); + try { + newModel.read( new StringReader( result ), "", "TURTLE" ); + } catch ( final RuntimeException e ) { + fail(); + } + } + + private final TurtleFormatter defaultFormatter = new TurtleFormatter( FormattingStyle.DEFAULT ); + + private final Resource subject = ResourceFactory.createResource( "urn:foo" ); + + private final org.apache.jena.rdf.model.Property predicate = ResourceFactory.createProperty( "urn:bar" ); + + @Provide + Arbitrary anyStringLiteralWithSpecialCharacters() { + return Arbitraries.strings().all().map( ResourceFactory::createStringLiteral ); + } + + @Property( tries = 500, seed = "1" ) + public void anyModelContainingSpecialCharactersIsSyntacticallyValid( @ForAll( + "anyStringLiteralWithSpecialCharacters" ) final Literal literal ) { + final Model model = ModelFactory.createDefaultModel(); + model.add( subject, predicate, literal ); + + final ByteArrayOutputStream out = new ByteArrayOutputStream( 128 ); + try { + model.write( out, "TURTLE" ); + } catch ( final Exception e ) { + // If Jena itself can't write it, we don't need to try it + return; + } + + final String result = defaultFormatter.apply( model ); + final Model originalModel = ModelFactory.createDefaultModel(); + final Model newModel = ModelFactory.createDefaultModel(); + try { + originalModel.read( new StringReader( out.toString() ), "", "TURTLE" ); + newModel.read( new StringReader( result ), "", "TURTLE" ); + final Literal originalLiteral = + originalModel.listStatements( subject, predicate, (RDFNode) null ).nextStatement().getLiteral(); + final Literal newLiteral = + newModel.listStatements( subject, predicate, (RDFNode) null ).nextStatement().getLiteral(); + assertThat( newLiteral.asNode().getLiteralLexicalForm() ) + .isEqualTo( originalLiteral.asNode().getLiteralLexicalForm() ); + } catch ( final RuntimeException e ) { + fail( e ); + } + } +} diff --git a/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterTest.java b/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterTest.java new file mode 100644 index 00000000..b230f6fa --- /dev/null +++ b/cool-rdf-formatter/src/test/java/cool/rdf/formatter/TurtleFormatterTest.java @@ -0,0 +1,1334 @@ +package cool.rdf.formatter; + +import cool.rdf.core.model.RdfModel; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.vocabulary.RDF; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import static org.apache.jena.rdf.model.ResourceFactory.createProperty; +import static org.apache.jena.rdf.model.ResourceFactory.createResource; +import static org.assertj.core.api.Assertions.assertThat; + +public class TurtleFormatterTest { + @Test + public void testPrefixAlignmentLeft() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.LEFT ) + .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a : . + @prefix abc : . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testPrefixAlignmentOff() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.OFF ) + .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a: . + @prefix abc: . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testPrefixAlignmentRight() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.RIGHT ) + .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a: . + @prefix abc: . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testLiterals() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo01 :bar 1 . + + :foo02 :bar "2" . + + :foo03 :bar true . + + :foo04 :bar -5.0 . + + :foo05 :bar 4.2E9 . + + :foo06 :bar "2021-01-01"^^xsd:date . + + :foo07 :bar "something"^^:custom . + + :foo08 :bar "something"@en . + + :foo09 :bar "This contains a \\" quote" . + + :foo10 :bar \"""This contains a + linebreak\""" . + """; + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .quoteStyle( FormattingStyle.QuoteStyle.TRIPLE_QUOTES_FOR_MULTILINE ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testQuotedStringsWithSingleQuotes() { + final String modelString = """ + @prefix : . + + :foo :bar "This contains and ends with a \\"quote\\"" ; + :bar2 "This contains a\\nlinebreak" ; + :bar3 "This contains \\t \\\\ \\b" . + """; + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .quoteStyle( FormattingStyle.QuoteStyle.ALWAYS_SINGE_QUOTES ) + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @SuppressWarnings( "TextBlockMigration" ) + @Test + public void testQuotedStringsWithTripleQuotes() { + // We'll put this in a regular string instead of a text block to make the escaping and the + // RDF triple quotes inside the string clearer + final String modelString = "@prefix : .\n" + + "\n:foo :bar \"\"\"This contains and ends with a \"quote\\\"\"\"\" ;\n" + + " :bar2 \"\"\"This contains \\t \\\\ \\b\"\"\" .\n"; + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .quoteStyle( FormattingStyle.QuoteStyle.ALWAYS_TRIPLE_QUOTES ) + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAlignmentWithFirstPredicateInSameLine() { + final String modelString = """ + @prefix : . + + :foo1 :bar1 1 ; + :bar2 2 ; + :bar3 3 . + + :something :bar1 1 ; + :bar2 2 ; + :bar3 3 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .alignPredicates( true ) + .firstPredicateInNewLine( false ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testIndentationWithTabs() { + final String modelString = """ + @prefix : . + + :foo1 :bar1 1 ; + \t:bar2 2 ; + \t:bar3 3 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( false ) + .indentStyle( FormattingStyle.IndentStyle.TAB ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAlignmentWithFirstPredicateInNewLine() { + final String modelString = """ + @prefix : . + + :foo1 + :bar1 1 ; + :bar2 2 ; + :bar3 3 . + + :something + :bar1 1 ; + :bar2 2 ; + :bar3 3 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAndObjectAlignment() { + final String modelString = """ + @prefix : . + + :foo1 :bar 1 ; + :bar234 2 ; + :bar567890 3 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( false ) + .alignPredicates( true ) + .alignObjects( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAndObjectAlignmentWithFirstPredicateInNewLine() { + final String modelString = """ + @prefix : . + + :foo1 + :bar 1 ; + :bar234 2 ; + :bar567890 3 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( true ) + .alignPredicates( true ) + .alignObjects( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testMultipleReferencedAnonNodes() { + // Note how the anonymous node can not be serialized using [ ] because it is referenced multiple times. + final String modelString = """ + @prefix : . + + :a :foo _:gen0 ; + :bar 1 . + + :b :foo _:gen0 . + + _:gen0 :bar 2 . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final String ex = "http://example.com/"; + final Property foo = createProperty( ex + "foo" ); + final Property bar = createProperty( ex + "bar" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( foo, bar ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testTopLevelAnonymousNode() { + final String modelString = """ + @prefix : . + + [ + :foo 1 ; + :bar 2 ; + :baz 3 ; + ] . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final String ex = "http://example.com/"; + final Property foo = createProperty( ex + "foo" ); + final Property bar = createProperty( ex + "bar" ); + final Property baz = createProperty( ex + "baz" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( foo, bar, baz ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testTopLevelIdentifiedAnonymousNodeWithMultiplePredicates() { + final String modelString = """ + @prefix : . + + :a a :type ; + :foo _:gen0 ; + :bar 1 . + + :b :foo _:gen0 . + + _:gen0 a :type ; + :foo "1" ; + :bar "2" . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final String ex = "http://example.com/"; + final Property foo = createProperty( ex + "foo" ); + final Property bar = createProperty( ex + "bar" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( RDF.type, foo, bar ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testListWrappingNever() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.NEVER ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testListWrappingAlways() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.ALWAYS ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + + :foo :bar ( + "foo1" + "foo2" + "foo3" + "foo4" + ) . + """; + assertThat( result.trim() ).isEqualTo( expected.trim() ); + } + + @Test + public void testListWrappingForLongLines() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.FOR_LONG_LINES ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" + "foo3" "foo4" ) . + """; + assertThat( result.trim() ).isEqualTo( expected.trim() ); + } + + @Test + public void testListOfAnonymousNodes() { + final String modelString = """ + @prefix : . + + :foo :bar ( [ + :x 1 ; + ] [ + :x 2 ; + ] ) . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testEmptyUrlWithEmptyBase() { + final String modelString = """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testUtf8BomCharset() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .charset( FormattingStyle.Charset.UTF_8_BOM ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + formatter.accept( model, outputStream ); + assertThat( outputStream.toByteArray() ).startsWith( (byte) 0xEF, (byte) 0xBB, (byte) 0xBF ); + } + + @Test + public void testFormatting() { + final Model model = ModelFactory.createDefaultModel(); + model + .read( "https://raw.githubusercontent.com/atextor/turtle-formatting/main/turtle-formatting.ttl", "TURTLE" ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = RdfModel.fromTurtle( result ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + + } + + @Test + public void testSubjectsNotInSubjectOrder() { + final String modelString = """ + @prefix : . + @prefix rdfs: . + @prefix rdf: . + + :Person a rdfs:Class . + :name a rdf:Property . + :address a rdf:Property . + :city a rdf:Property . + :Max a :Person ; + :name "Max" ; + :address [ + :city "City Z" + ] . + """; + + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = RdfModel.fromTurtle( result ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + } + + @Test + public void testRepeatedPredicates() { + final String modelString = """ + @prefix : . + + :foo :bar [ + :something "x" ; + :something "y" ; + :something "z" ; + ] . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testEscapedLocalNameAndEscapedString() { + final String modelString = """ + @prefix : . + + :foo :something :ab\\/cd . + :bar :something "ab\\\\cd" . + :baz :something "ab\\"cd" . + :baz2 :something \"""ab"cd\""" . + """; + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = RdfModel.fromTurtle( result ); + + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + + final Resource foo = createResource( "http://example.com#foo" ); + final Statement fooStatement = resultModel.listStatements( foo, null, (RDFNode) null ).nextStatement(); + assertThat( fooStatement.getObject().asResource().getURI() ).isEqualTo( "http://example.com#ab/cd" ); + + final Resource bar = createResource( "http://example.com#bar" ); + final Statement barStatement = resultModel.listStatements( bar, null, (RDFNode) null ).nextStatement(); + assertThat( barStatement.getObject().asLiteral().getString() ).isEqualTo( "ab\\cd" ); + + final Resource baz = createResource( "http://example.com#baz" ); + final Statement bazStatement = resultModel.listStatements( baz, null, (RDFNode) null ).nextStatement(); + assertThat( bazStatement.getObject().asLiteral().getString() ).isEqualTo( "ab\"cd" ); + + final Resource baz2 = createResource( "http://example.com#baz2" ); + final Statement baz2Statement = resultModel.listStatements( baz2, null, (RDFNode) null ).nextStatement(); + assertThat( baz2Statement.getObject().asLiteral().getString() ).isEqualTo( "ab\"cd" ); + } + + @Test + public void testPrefixEscapeCharacters() { + final String modelString = """ + @prefix foo-bar: . + @prefix foo_bar: . + @prefix ä_1: . + @prefix foo: . + + foo-bar:foo foo-bar:foo "value1" . + foo_bar:bar foo_bar:bar "value2" . + ä_1:baz ä_1:baz "value3" . + foo:some-thing foo:some-thing "x" . + foo:some.thing foo:some.thing "x" . + foo:some_thing foo:some_thing "x" . + foo:some\\*thing foo:some\\*thing "x" . + foo:some\\?thing foo:some\\?thing "x" . + foo:some\\@thing foo:some\\@thing "x" . + foo:something "x" . + foo::another foo:test "x" . + foo:\\$10 foo:test "x" . + """; + final Model model = RdfModel.fromTurtle( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = RdfModel.fromTurtle( result ); + + // Should not be escaped and should be local names: dashes and underscores in prefix part of local names + assertThat( result ).contains( "foo-bar:foo" ); + assertThat( result ).contains( "foo_bar:bar" ); + assertThat( result ).contains( "foo::another" ); + // Should not be escaped and should be local names: dashes and underscores in name part of local names + assertThat( result ).contains( "foo:some-thing" ); + assertThat( result ).contains( "foo:some_thing" ); + // Should be full URIs, since local names would be invalid + assertThat( result ).contains( "http://example4.com#some*thing" ); + assertThat( result ).contains( "http://example4.com#some?thing" ); + assertThat( result ).contains( "http://example4.com#some@thing" ); + assertThat( result ).contains( "http://example4.com#-10" ); + assertThat( result ).contains( "http://example4.com#$10" ); + + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + + final Resource subject1 = createResource( "http://example.com#foo" ); + final Statement subject1Statement = + resultModel.listStatements( subject1, null, (RDFNode) null ).nextStatement(); + assertThat( subject1Statement.getObject().asLiteral().getString() ).isEqualTo( "value1" ); + + final Resource subject2 = createResource( "http://example2.com#bar" ); + final Statement subject2Statement = resultModel.listStatements( subject2, null, (RDFNode) null ) + .nextStatement(); + assertThat( subject2Statement.getObject().asLiteral().getString() ).isEqualTo( "value2" ); + + final Resource subject3 = createResource( "http://example3.com#baz" ); + final Statement subject3Statement = resultModel.listStatements( subject3, null, (RDFNode) null ) + .nextStatement(); + assertThat( subject3Statement.getObject().asLiteral().getString() ).isEqualTo( "value3" ); + + for ( final String namePart : + List.of( "some-thing", "some_thing", "some*thing", "some?thing", "some@thing" ) ) { + final Resource resource = createResource( "http://example4.com#" + namePart ); + final Statement statement = resultModel.listStatements( resource, null, (RDFNode) null ) + .nextStatement(); + assertThat( statement.getObject().asLiteral().getString() ).isEqualTo( "x" ); + } + } + + @Test + void testRespectEndOfLineConfig() { + final Map expected = Map.of( + FormattingStyle.EndOfLineStyle.LF, "\n", + FormattingStyle.EndOfLineStyle.CR, "\r", + FormattingStyle.EndOfLineStyle.CRLF, "\r\n" ); + final Map> unexpected = Map.of( + FormattingStyle.EndOfLineStyle.LF, List.of( "\r", "\r\n" ), + FormattingStyle.EndOfLineStyle.CR, List.of( "\n", "\r\n" ), + FormattingStyle.EndOfLineStyle.CRLF, List.of() ); + + for ( final FormattingStyle.EndOfLineStyle endOfLine : FormattingStyle.EndOfLineStyle.values() ) { + final FormattingStyle style = FormattingStyle.builder() + .endOfLine( endOfLine ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + + final String expectedLineEnding = expected.get( endOfLine ); + final List unexpectedLineEndings = unexpected.get( endOfLine ); + + final Model onlyPrefixesModel = prefixModel(); + final String onlyPrefixesResult = formatter.apply( onlyPrefixesModel ); + assertThat( onlyPrefixesResult ).contains( expectedLineEnding ); + unexpectedLineEndings.forEach( unexpectedLineEnding -> assertThat( onlyPrefixesResult ).doesNotContain( unexpectedLineEnding ) ); + + final Model modelWithAssertions = RdfModel.fromTurtle( """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """ ); + final String modelWithAssertionsResult = formatter.apply( modelWithAssertions ); + assertThat( modelWithAssertionsResult ).contains( expectedLineEnding ); + unexpectedLineEndings.forEach( unexpectedLineEnding -> assertThat( modelWithAssertionsResult ).doesNotContain( unexpectedLineEnding ) ); + } + } + + @Test + void testRdfTypeAsObjectIsValid() { + final String modelString = """ + @prefix rdf: . + @prefix : . + + :foo a :bar ; + :something rdf:type . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .useAForRdfType( true ) + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + void testRdfListNonAnonymous(){ + final String modelString = """ + @prefix rdf: . + @prefix rdfs: . + @prefix xsd: . + @prefix qudt: . + @prefix sh: . + + qudt:IntegerUnionList a rdf:List ; + rdfs:label "Integer union list" ; + rdf:first [ + sh:datatype xsd:nonNegativeInteger ; + ] ; + rdf:rest ( [ + sh:datatype xsd:positiveInteger ; + ] [ + sh:datatype xsd:integer ; + ] ) . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + void testRdfListAnonymous(){ + final String modelString = """ + @prefix rdf: . + @prefix ex: . + + ex:something a ex:Thing ; + ex:hasList ( ex:one ex:two ) . + """; + final Model model = RdfModel.fromTurtle( modelString ); + + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @ParameterizedTest + @MethodSource + void testConsistentBlankNodeOrdering(String content){ + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + for (int i = 0; i < 1; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(content.trim()); + } + } + + static Stream testConsistentBlankNodeOrdering(){ + return Stream.of( + """ + @prefix rdf: . + @prefix ex: . + + [ + a ex:Something ; + ] . + + [ + a ex:SomethingElse ; + ] . + """, + + """ + @prefix rdf: . + @prefix ex: . + + ex:aThing ex:has [ + a ex:Something ; + ] ; + ex:has [ + a ex:SomethingElse ; + ] . + """ + , + """ + @prefix ex: . + + _:blank1 ex:has [ + ex:has _:blank1 ; + ] .""" + ).map(s -> Arguments.of(s)); + } + + @Test + void testPreviouslyIdentifiedBlankNode(){ + String content = """ + @prefix ex: . + + _:gen0 ex:has [ + ex:has _:gen0 ; + ]."""; + String expected = """ + @prefix ex: . + + _:gen0 ex:has [ + ex:has _:gen0 ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + void testBlankNodeCycle(){ + String content = """ + @prefix ex: . + + _:blank1 ex:has _:blank2 . + + _:blank2 ex:has _:blank1 . + """; + String expected = """ + @prefix ex: . + + _:blank1 ex:has [ + ex:has _:blank1 ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + void testNoBlankNodeCycle(){ + String content = """ + @prefix ex: . + + _:one ex:has ex:A . + ex:A ex:has _:one . + + """; + String expected = """ + @prefix ex: . + + ex:A ex:has [ + ex:has ex:A ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + void testNoBlankNodeCycle2Blanks(){ + String content = """ + @prefix ex: . + + _:one ex:has ex:A . + ex:A ex:has _:two . + _:two ex:has _:three . + _:three ex:has _:one . + + """; + String expected = """ + @prefix ex: . + + ex:A ex:has [ + ex:has [ + ex:has [ + ex:has ex:A ; + ] ; + ] ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + void testBlankNodeCycle1ResBetween(){ + String content = """ + @prefix ex: . + + _:one ex:has ex:A . + ex:A ex:has _:two . + _:two ex:has _:one . + + """; + String expected = """ + @prefix ex: . + + ex:A ex:has [ + ex:has [ + ex:has ex:A ; + ] ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + void testBlankNodeCycle2ResBetween(){ + String content = """ + @prefix ex: . + + _:one ex:has ex:A . + ex:A ex:has _:two . + _:two ex:has ex:B . + ex:B ex:has _:one . + + """; + String expected = """ + @prefix ex: . + + ex:A ex:has [ + ex:has ex:B ; + ] . + + ex:B ex:has [ + ex:has ex:A ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + void testBlankNodeTriangle1(){ + String content = """ + @prefix : . + _:b1 :foo _:b2, _:b3. + _:b2 :foo _:b3. + + """; + String expected = """ + @prefix : . + + [ + :foo [ + :foo _:b3 ; + ] ; + :foo _:b3 ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + void testBlankNodeTriangleWithBlankNodeTriple(){ + String content = """ + @prefix : . + [] :foo [] . + _:b1 :foo _:b2, _:b3. + _:b2 :foo _:b3. + + """; + String expected = """ + @prefix : . + + [ + :foo []; + ] . + + [ + :foo [ + :foo _:b3 ; + ] ; + :foo _:b3 ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + for (int i = 0; i < 20; i++) { + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + } + + @Test + public void testEnableDoubleFormatting() { + final String modelString = """ + @prefix xsd: . + @prefix ex: . + + ex:something ex:decimalProp 0.0000000006241509074460762607776240980930446 ; + ex:doubleProp 6.241509074460762607776240980930446E-10 ."""; + + final FormattingStyle style = FormattingStyle.builder().enableDoubleFormatting(false).build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.applyToContent( modelString ); + assertThat(result.trim()).isEqualTo(modelString); + } + + @Test + public void testDoubleFormattingDefault() { + final String modelString = """ + @prefix xsd: . + @prefix ex: . + + ex:something ex:decimalProp 0.0000000006241509074460762607776240980930446 ; + ex:doubleProp 6.241509074460762607776240980930446E-10 ."""; + + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.applyToContent( modelString ); + assertThat(result.trim()).isEqualTo(modelString); + } + + @Test + public void testDisableDoubleFormatting() { + final String modelString = """ + @prefix xsd: . + @prefix ex: . + + ex:something ex:decimalProp 0.0000000006241509074460762607776240980930446 ; + ex:doubleProp 6.2415E-10 ."""; + + final FormattingStyle style = FormattingStyle.builder().enableDoubleFormatting(true).build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.applyToContent( modelString ); + assertThat(result.trim()).isEqualTo(modelString); + } + + @Test + public void testIntegerLiteralWithLeadingZeros(){ + String content = """ + @prefix : . + :thing :value 060. + + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value 060 ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testDoubleLiteralWithoutFractions(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "40"^^xsd:double. + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value "40"^^xsd:double ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testDoubleLiteralWithFractions(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "4.001E2"^^xsd:double. + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value 4.001E2 ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testDecimalLiteralWithoutFractions(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "40"^^xsd:decimal. + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value "40"^^xsd:decimal ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testDecimalLiteralWithFractions(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "40.0001"^^xsd:decimal. + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value 40.0001 ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + + @Test + public void testListNodeWithAdditionalTriples(){ + String content = """ + @prefix : . + @prefix rdf: . + :thing :hasList [ + a :SomeListClass ; + a rdf:List ; + :comment "a very special list"; + rdf:first 1 ; + rdf:rest ( 2 3 4 ); + ] . + """; + String expected = """ + @prefix rdf: . + @prefix xsd: . + @prefix : . + + :thing :hasList [ + a :SomeListClass, rdf:List ; + :comment "a very special list" ; + rdf:first 1 ; + rdf:rest ( 2 3 4 ) ; + ] ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testEmptyList() { + var content = """ + @prefix rdf: . + @prefix : . + :aThing a :element; + :has (); + :hasNil rdf:nil; + :numbers (1 2 3 ); + :tests (); + :hasList [ + a :SomeListClass ; + a rdf:List ; + :numbersAgain (); + :comment "a very special list"; + rdf:first 1 ; + rdf:rest ( 2 3 4 ) + ]. + """; + + final String expected = """ + @prefix rdf: . + @prefix xsd: . + @prefix : . + + :aThing a :element ; + :has ( ) ; + :hasList [ + a :SomeListClass, rdf:List ; + :comment "a very special list" ; + :numbersAgain ( ) ; + rdf:first 1 ; + rdf:rest ( 2 3 4 ) ; + ] ; + :hasNil ( ) ; + :numbers ( 1 2 3 ) ; + :tests ( ) ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testMultilineStrings(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value \""" + First Line + Second Line + Third Line + \""" . + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value \""" + First Line + Second Line + Third Line + \""" ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testStringsWithUnixStyleNewlinesToMultilineStrings(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "\\n First Line\\n Second Line\\n Third Line\\n" . + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value \""" + First Line + Second Line + Third Line + \""" ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testStringsWithWindowsStyleNewlinesToMultilineStrings(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "\\r\\n First Line\\r\\n Second Line\\r\\n Third Line\\r\\n" . + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value \""" + First Line + Second Line + Third Line + \""" ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + @Test + public void testStringsWithMacStyleNewlinesToMultilineStrings(){ + String content = """ + @prefix xsd: . + @prefix : . + :thing :value "\\r First Line\\r Second Line\\r Third Line\\r" . + """; + String expected = """ + @prefix xsd: . + @prefix : . + + :thing :value \""" + First Line + Second Line + Third Line + \""" ."""; + final FormattingStyle style = FormattingStyle.DEFAULT; + final TurtleFormatter formatter = new TurtleFormatter(style); + final String result = formatter.applyToContent(content); + assertThat(result.trim()).isEqualTo(expected); + } + + private Model prefixModel() { + final Model model = ModelFactory.createDefaultModel(); + model.setNsPrefix( "", "http://example.com/" ); + model.setNsPrefix( "a", "http://example.com/a" ); + model.setNsPrefix( "abc", "http://example.com/abc" ); + model.setNsPrefix( "abcdef", "http://example.com/abc" ); + return model; + } +} diff --git a/cool-rdf-infer/pom.xml b/cool-rdf-infer/pom.xml new file mode 100644 index 00000000..96008188 --- /dev/null +++ b/cool-rdf-infer/pom.xml @@ -0,0 +1,91 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-infer + Cool RDF Infer + + + + + cool.rdf + cool-rdf-formatter + + + + + org.apache.jena + jena + pom + + + org.apache.jena + jena-core + + + org.slf4j + slf4j-api + + + io.vavr + vavr + + + com.github.galigator.openllet + openllet-jena + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + diff --git a/infer/src/main/java/de/atextor/owlcli/infer/Configuration.java b/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java similarity index 64% rename from infer/src/main/java/de/atextor/owlcli/infer/Configuration.java rename to cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java index 902ca84c..45ca2802 100644 --- a/infer/src/main/java/de/atextor/owlcli/infer/Configuration.java +++ b/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,23 +14,52 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package cool.rdf.infer; -import de.atextor.turtle.formatter.TurtleFormatter; +import cool.rdf.formatter.TurtleFormatter; import lombok.Builder; +/** + * The configuration for inferring from models + */ @Builder public class Configuration { + /** + * The format used to parse the input + */ + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format inputFormat = Format.TURTLE; + /** + * The RDF base URL + */ + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String base = TurtleFormatter.DEFAULT_EMPTY_BASE; + /** + * The possible input formats + */ public enum Format { + /** + * RDF/Turtle + */ TURTLE, + + /** + * RDF/XML + */ RDFXML, + + /** + * N-Triple + */ NTRIPLE, + + /** + * N3 format + */ N3; @Override diff --git a/infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java b/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java similarity index 50% rename from infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java rename to cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java index f2bbb819..a0938379 100644 --- a/infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java +++ b/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,10 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package cool.rdf.infer; -import de.atextor.turtle.formatter.FormattingStyle; -import de.atextor.turtle.formatter.TurtleFormatter; +import cool.rdf.formatter.FormattingStyle; +import cool.rdf.formatter.TurtleFormatter; import io.vavr.control.Try; import openllet.jena.PelletReasonerFactory; import org.apache.jena.ontology.OntModel; @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; @@ -35,31 +36,63 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; +/** + * + */ public class Inferrer { + /** + * The default configuration + */ public static final Configuration DEFAULT_CONFIGURATION = Configuration.builder().build(); private static final Logger LOG = LoggerFactory.getLogger( Inferrer.class ); + /** + * Writes an inferred OWL document given by an input URL, to an output stream using a writing/formatting + * configuration + * + * @param inputUrl the input URL + * @param output the output stream + * @param configuration the configuration + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ public Try infer( final URL inputUrl, final OutputStream output, final Configuration configuration ) { - try { - final HttpClient client = HttpClient.newBuilder() - .followRedirects( HttpClient.Redirect.ALWAYS ) - .build(); - final HttpRequest request = HttpRequest.newBuilder() - .uri( inputUrl.toURI() ) - .build(); - final HttpResponse response = client.send( request, HttpResponse.BodyHandlers.ofString() ); - if ( response.statusCode() == HttpURLConnection.HTTP_OK ) { - final ByteArrayInputStream inputStream = new ByteArrayInputStream( response.body().getBytes() ); - return infer( inputStream, output, configuration ); + if ( inputUrl.getProtocol().equals( "http" ) || inputUrl.getProtocol().equals( "https" ) ) { + try { + final HttpClient client = HttpClient.newBuilder() + .followRedirects( HttpClient.Redirect.ALWAYS ) + .build(); + final HttpRequest request = HttpRequest.newBuilder() + .uri( inputUrl.toURI() ) + .build(); + final HttpResponse response = client.send( request, HttpResponse.BodyHandlers.ofString() ); + if ( response.statusCode() == HttpURLConnection.HTTP_OK ) { + final ByteArrayInputStream inputStream = new ByteArrayInputStream( response.body().getBytes() ); + return infer( inputStream, output, configuration ); + } + return Try.failure( new RuntimeException( "Got unexpected HTTP response: " + response.statusCode() ) ); + } catch ( final Exception exception ) { + LOG.debug( "Failure during reading from URL: {}", inputUrl ); + return Try.failure( exception ); } - return Try.failure( new RuntimeException( "Got unexpected HTTP response: " + response.statusCode() ) ); - } catch ( final Exception exception ) { - LOG.debug( "Failure during reading from URL: {}", inputUrl ); + } + + try { + return infer( inputUrl.openStream(), output, configuration ); + } catch ( final IOException exception ) { return Try.failure( exception ); } } + /** + * Writes an inferred OWL document given by an input stream, to an output stream using a writing/formatting + * configuration + * + * @param input the input stream + * @param output the output stream + * @param configuration the configuration + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ public Try infer( final InputStream input, final OutputStream output, final Configuration configuration ) { final OntModel model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC ); try { @@ -71,6 +104,13 @@ public Try infer( final InputStream input, final OutputStream output, fina } } + /** + * Writes an RDF model to and output stream in RDF/Turtle format + * + * @param model the model + * @param output the output stream + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ public Try writeTurtle( final Model model, final OutputStream output ) { final TurtleFormatter formatter = new TurtleFormatter( FormattingStyle.DEFAULT ); formatter.accept( model, output ); @@ -78,7 +118,7 @@ public Try writeTurtle( final Model model, final OutputStream output ) { } /** - * Builds a RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} + * Builds an RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} * * @param format the format * @return the format identifier for the Jena parser diff --git a/infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java b/cool-rdf-infer/src/test/java/cool/rdf/infer/InferrerTest.java similarity index 85% rename from infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java rename to cool-rdf-infer/src/test/java/cool/rdf/infer/InferrerTest.java index 376a2d66..f6081522 100644 --- a/infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java +++ b/cool-rdf-infer/src/test/java/cool/rdf/infer/InferrerTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package cool.rdf.infer; import org.junit.jupiter.api.Test; @@ -23,6 +23,6 @@ public class InferrerTest { @Test public void testFoo() { - + // TODO } } diff --git a/cool-rdf-write/pom.xml b/cool-rdf-write/pom.xml new file mode 100644 index 00000000..a041d4b4 --- /dev/null +++ b/cool-rdf-write/pom.xml @@ -0,0 +1,95 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + cool-rdf-write + Cool RDF Write + + + + + cool.rdf + cool-rdf-core + + + cool.rdf + cool-rdf-formatter + + + + + org.apache.jena + jena + pom + + + org.apache.jena + jena-core + + + org.apache.jena + jena-arq + + + org.slf4j + slf4j-api + + + io.vavr + vavr + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + diff --git a/write/src/main/java/de/atextor/owlcli/write/Configuration.java b/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java similarity index 56% rename from write/src/main/java/de/atextor/owlcli/write/Configuration.java rename to cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java index 67f145ab..ae5100a7 100644 --- a/write/src/main/java/de/atextor/owlcli/write/Configuration.java +++ b/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,27 +14,67 @@ * limitations under the License. */ -package de.atextor.owlcli.write; +package cool.rdf.write; -import de.atextor.turtle.formatter.FormattingStyle; -import de.atextor.turtle.formatter.TurtleFormatter; +import cool.rdf.formatter.FormattingStyle; import lombok.Builder; +/** + * The configuration for writing RDF document + */ @Builder public class Configuration { + /** + * The format used to write the document + */ + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format outputFormat = Format.TURTLE; + /** + * The format used to parse the input + */ + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format inputFormat = Format.TURTLE; + /** + * The formatting style to use + */ @Builder.Default public FormattingStyle formattingStyle = FormattingStyle.DEFAULT; + @Override + public String toString() { + return "Configuration{" + + "outputFormat=" + outputFormat + + ", inputFormat=" + inputFormat + + ", formattingStyle=" + formattingStyle + + '}'; + } + + /** + * The possible input/output formats + */ public enum Format { + /** + * RDF/Turtle + */ TURTLE, + + /** + * RDF/XML + */ RDFXML, + + /** + * N-Triple + */ NTRIPLE, + + /** + * N3 format + */ N3; @Override diff --git a/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java b/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java new file mode 100644 index 00000000..e2b13136 --- /dev/null +++ b/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java @@ -0,0 +1,153 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cool.rdf.write; + +import cool.rdf.core.model.RdfModel; +import cool.rdf.formatter.FormattingStyle; +import cool.rdf.formatter.TurtleFormatter; +import io.vavr.control.Try; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.riot.Lang; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * The RDF Writer is used to serialize RDF documents into various formats, while using configurable formatting for + * RDF/Turtle specifically, using the {@link TurtleFormatter}. + */ +public class RdfWriter { + /** + * The default configuration + */ + public static final Configuration DEFAULT_CONFIGURATION = Configuration.builder().build(); + + private static final Logger LOG = LoggerFactory.getLogger( RdfWriter.class ); + + /** + * Writes an RDF document given by an input URL, to an output stream using a writing/formatting configuration + * + * @param inputUrl the input URL + * @param output the output stream + * @param configuration the configuration + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ + public Try write( final URL inputUrl, final OutputStream output, final Configuration configuration ) { + if ( inputUrl.getProtocol().equals( "http" ) || inputUrl.getProtocol().equals( "https" ) ) { + try { + final HttpClient client = HttpClient.newBuilder() + .followRedirects( HttpClient.Redirect.ALWAYS ) + .build(); + final HttpRequest request = HttpRequest.newBuilder() + .uri( inputUrl.toURI() ) + .build(); + final HttpResponse response = client.send( request, HttpResponse.BodyHandlers.ofString() ); + if ( response.statusCode() == HttpURLConnection.HTTP_OK ) { + final ByteArrayInputStream inputStream = new ByteArrayInputStream( response.body().getBytes() ); + return write( inputStream, output, configuration ); + } + return Try.failure( new RuntimeException( "Got unexpected HTTP response: " + response.statusCode() ) ); + } catch ( final Exception exception ) { + LOG.debug( "Failure during reading from URL: {}", inputUrl ); + return Try.failure( exception ); + } + } + + try { + return write( inputUrl.openStream(), output, configuration ); + } catch ( final IOException exception ) { + return Try.failure( exception ); + } + } + + /** + * Writes an RDF document given by an input stream, to an output stream using a writing/formatting configuration + * + * @param input the input stream + * @param output the output stream + * @param configuration the configuration + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ + public Try write( final InputStream input, final OutputStream output, final Configuration configuration ) { + LOG.debug( "Load model" ); + final Model model = RdfModel.fromDocument( input, configurationFormatToJenaSyntax( configuration.inputFormat ), + configuration.formattingStyle.emptyRdfBase ); + try { + if ( configuration.outputFormat == Configuration.Format.TURTLE ) { + return writeTurtle( model, output, configuration.formattingStyle ); + } + LOG.debug( "Writing model using Jena" ); + model.write( output, configurationFormatToJenaFormat( configuration.outputFormat ) ); + } catch ( final Exception exception ) { + LOG.debug( "Failure during RDF I/O", exception ); + return Try.failure( exception ); + } + return Try.success( null ); + } + + /** + * Writes an RDF model to and output stream in RDF/Turtle format, using a formatting configuration + * + * @param model the model + * @param output the output stream + * @param style the formatting style + * @return {@link io.vavr.control.Try.Success} if writing succeeded + */ + public Try writeTurtle( final Model model, final OutputStream output, final FormattingStyle style ) { + LOG.debug( "Create turtle formatter" ); + final TurtleFormatter formatter = new TurtleFormatter( style ); + LOG.debug( "Writing model using TurtleFormatter" ); + formatter.accept( model, output ); + return Try.success( null ); + } + + /** + * Builds an RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} + * + * @param format the format + * @return the format identifier for the Jena parser + */ + private String configurationFormatToJenaFormat( final Configuration.Format format ) { + return switch ( format ) { + case TURTLE -> "TURTLE"; + case RDFXML -> "RDF/XML"; + case NTRIPLE -> "N-TRIPLE"; + case N3 -> "N3"; + }; + } + + private Lang configurationFormatToJenaSyntax( final Configuration.Format format ) { + LOG.debug( "Determining syntax for {}", format ); + final Lang result = switch ( format ) { + case TURTLE -> Lang.TURTLE; + case RDFXML -> Lang.RDFXML; + case NTRIPLE -> Lang.NTRIPLES; + case N3 -> Lang.N3; + }; + LOG.debug( "Target syntax: {}", result ); + return result; + } +} diff --git a/write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java b/cool-rdf-write/src/test/java/cool/rdf/write/RdfWriterTest.java similarity index 68% rename from write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java rename to cool-rdf-write/src/test/java/cool/rdf/write/RdfWriterTest.java index 7a68b4ca..f494390d 100644 --- a/write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java +++ b/cool-rdf-write/src/test/java/cool/rdf/write/RdfWriterTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,24 +14,26 @@ * limitations under the License. */ -package de.atextor.owlcli.write; +package cool.rdf.write; -import de.atextor.turtle.formatter.TurtleFormatter; +import cool.rdf.core.model.RdfModel; +import cool.rdf.formatter.TurtleFormatter; import io.vavr.control.Try; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.riot.Lang; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.net.URL; import java.nio.charset.StandardCharsets; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class RdfWriterTest { private final RdfWriter writer = new RdfWriter(); @@ -54,21 +56,6 @@ private InputStream turtleInputStream() { return new ByteArrayInputStream( turtleDocument.getBytes() ); } - private Model parseModel( final String document, final String format ) { - final Model model = ModelFactory.createDefaultModel(); - try { - model.read( new StringReader( document ), "", format ); - return model; - } catch ( final Throwable t ) { - return null; - } - } - - private boolean canBeParsedAs( final String document, final String format, final int expectedNumberOfStatements ) { - final Model model = parseModel( document, format ); - return model != null && model.listStatements().toList().size() == expectedNumberOfStatements; - } - @Test public void testWriteTurtle() { final Configuration configuration = Configuration.builder() @@ -79,9 +66,9 @@ public void testWriteTurtle() { final Try result = writer.write( turtleInputStream(), out, configuration ); assertThat( result ).hasSize( 1 ); - assertThat( canBeParsedAs( out.toString(), "TURTLE", 8 ) ).isTrue(); - assertThat( canBeParsedAs( out.toString(), "N-TRIPLE", 8 ) ).isFalse(); - assertThat( canBeParsedAs( out.toString(), "RDF/XML", 8 ) ).isFalse(); + assertThatCode( () -> RdfModel.fromDocument( out.toString(), Lang.TURTLE ) ).doesNotThrowAnyException(); + assertThatThrownBy( () -> RdfModel.fromDocument( out.toString(), Lang.NTRIPLES ) ).hasMessageContaining( "line:" ); + assertThatThrownBy( () -> RdfModel.fromDocument( out.toString(), Lang.RDFXML ) ).hasMessageContaining( "line:" ); } @Test @@ -94,10 +81,10 @@ public void testWriteNTriples() { final Try result = writer.write( turtleInputStream(), out, configuration ); assertThat( result ).hasSize( 1 ); + assertThatCode( () -> RdfModel.fromDocument( out.toString(), Lang.TURTLE ) ).doesNotThrowAnyException(); // N-TRIPLES is also valid Turtle - assertThat( canBeParsedAs( out.toString(), "TURTLE", 8 ) ).isTrue(); - assertThat( canBeParsedAs( out.toString(), "N-TRIPLE", 8 ) ).isTrue(); - assertThat( canBeParsedAs( out.toString(), "RDF/XML", 8 ) ).isFalse(); + assertThatCode( () -> RdfModel.fromDocument( out.toString(), Lang.NTRIPLES ) ).doesNotThrowAnyException(); + assertThatThrownBy( () -> RdfModel.fromDocument( out.toString(), Lang.RDFXML ) ).hasMessageContaining( "line:" ); } @Test @@ -110,15 +97,14 @@ public void testWriteRdfXml() { final Try result = writer.write( turtleInputStream(), out, configuration ); assertThat( result ).hasSize( 1 ); - assertThat( canBeParsedAs( out.toString(), "TURTLE", 8 ) ).isFalse(); - assertThat( canBeParsedAs( out.toString(), "N-TRIPLE", 8 ) ).isFalse(); - assertThat( canBeParsedAs( out.toString(), "RDF/XML", 8 ) ).isTrue(); + assertThatThrownBy( () -> RdfModel.fromDocument( out.toString(), Lang.TURTLE ) ).hasMessageContaining( "line:" ); + assertThatThrownBy( () -> RdfModel.fromDocument( out.toString(), Lang.NTRIPLES ) ).hasMessageContaining( "line:" ); + assertThatCode( () -> RdfModel.fromDocument( out.toString(), Lang.RDFXML ) ).doesNotThrowAnyException(); } @Test public void testReadFromUrl() throws IOException { - final URL url = new URL( "https://raw.githubusercontent.com/atextor/turtle-formatting/main/turtle-formatting" + - ".ttl" ); + final URL url = new URL( "https://raw.githubusercontent.com/atextor/turtle-formatting/main/turtle-formatting.ttl" ); final Configuration configuration = Configuration.builder() .inputFormat( Configuration.Format.TURTLE ) .outputFormat( Configuration.Format.TURTLE ).build(); @@ -127,7 +113,7 @@ public void testReadFromUrl() throws IOException { final Try result = writer.write( url, out, configuration ); assertThat( result ).hasSize( 1 ); - assertThat( parseModel( out.toString(), "TURTLE" ) ).isNotNull(); + assertThatCode( () -> RdfModel.fromDocument( out.toString(), Lang.TURTLE ) ).doesNotThrowAnyException(); } @Test @@ -148,11 +134,4 @@ public void testParsingEscapedUri() { model.read( stream, TurtleFormatter.DEFAULT_EMPTY_BASE, "TURTLE" ); } ).doesNotThrowAnyException(); } - - private Model modelFromString( final String content ) { - final Model model = ModelFactory.createDefaultModel(); - final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); - model.read( stream, TurtleFormatter.DEFAULT_EMPTY_BASE, "TURTLE" ); - return model; - } } diff --git a/dependencies.gradle b/dependencies.gradle deleted file mode 100644 index ec3ad6cc..00000000 --- a/dependencies.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -ext.deps = [ - caffeine: 'com.github.ben-manes.caffeine:caffeine:2.9.2', - commons_codec: 'commons-codec:commons-codec:1.16.0', - commons_io: 'org.apache.commons:commons-io:1.3.2', - commons_text: 'org.apache.commons:commons-text:1.10.0', - guava: 'com.google.guava:guava:32.1.2-jre', - httpclient: 'org.apache.httpcomponents:httpclient:4.5.14', - jackson_databind: 'com.fasterxml.jackson.core:jackson-databind:2.15.2', - jena: 'org.apache.jena:jena:4.9.0', - jena_core: 'org.apache.jena:jena-core:4.9.0', - jena_arq: 'org.apache.jena:jena-arq:4.9.0', - logback: 'ch.qos.logback:logback-classic:1.4.11', - openllet: 'com.github.galigator.openllet:openllet-jena:2.6.5', - owlapi: 'net.sourceforge.owlapi:owlapi-distribution:5.5.0', - picocli: 'info.picocli:picocli:4.7.5', - picocli_codegen: 'info.picocli:picocli-codegen:4.7.5', - slf4j_api: 'org.slf4j:slf4j-api:2.0.9', - svm: 'org.graalvm.nativeimage:svm:23.1.0', - turtle_formatter: 'de.atextor:turtle-formatter:1.2.9', - vavr: 'io.vavr:vavr:0.10.4', - - // Test - junit_jupiter_api: 'org.junit.jupiter:junit-jupiter-api:5.10.0', - junit_jupiter_params: 'org.junit.jupiter:junit-jupiter-params:5.10.0', - junit_jupiter_engine: 'org.junit.jupiter:junit-jupiter-engine:5.10.0', - assertj: 'org.assertj:assertj-core:3.24.2', - jqwik: 'net.jqwik:jqwik:1.8.0', - classgraph: 'io.github.classgraph:classgraph:4.8.162', - - // Documentation - nodejs: '12.13.1', - npm: '6.9.0' -] diff --git a/diagram/build.gradle b/diagram/build.gradle deleted file mode 100644 index 8363ef48..00000000 --- a/diagram/build.gradle +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.guava) - implementation(deps.owlapi) { - exclude group: 'org.slf4j', module: 'slf4j-simple' - } - implementation(deps.slf4j_api) - implementation(deps.vavr) - implementation(deps.commons_text) - - // Override transitive dependency versions due to features - implementation(deps.caffeine) - - // Override transitive dependency versions due to vulns - implementation(deps.jackson_databind) - implementation(deps.httpclient) - implementation(deps.commons_codec) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java b/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java deleted file mode 100644 index 55b5cb5f..00000000 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli.diagram.diagram; - -import lombok.Builder; - -/** - * The configuration that controls the visual output - */ -@Builder -public class Configuration { - @Builder.Default - public String dotBinary = "dot"; - - @Builder.Default - public String fontname = "Verdana"; - - @Builder.Default - public int fontsize = 12; - - @Builder.Default - public String nodeFontname = "Verdana"; - - @Builder.Default - public int nodeFontsize = 12; - - @Builder.Default - public String nodeShape = "box"; - - @Builder.Default - public String nodeMargin = "0.05,0.0"; - - @Builder.Default - public String nodeStyle = "rounded"; - - @Builder.Default - public String bgColor = "white"; - - @Builder.Default - public String fgColor = "black"; - - @Builder.Default - public Format format = Format.SVG; - - @Builder.Default - public LayoutDirection layoutDirection = LayoutDirection.LEFT_TO_RIGHT; - - public enum Format { - PNG, - SVG; - - public String getExtension() { - return toString().toLowerCase(); - } - - @Override - public String toString() { - return switch ( this ) { - case PNG -> "png"; - case SVG -> "svg"; - }; - } - } - - public enum LayoutDirection { - TOP_TO_BOTTOM, - LEFT_TO_RIGHT; - - @Override - public String toString() { - return switch ( this ) { - case TOP_TO_BOTTOM -> "top_to_bottom"; - case LEFT_TO_RIGHT -> "left_to_right"; - }; - } - } -} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java b/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java deleted file mode 100644 index 3157b917..00000000 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli.diagram.graph; - -import java.util.stream.Stream; - -/** - * An element of the graph - */ -public interface GraphElement { - interface Visitor { - T visit( Edge.Plain edge ); - - T visit( Edge.Decorated decoratedEdge ); - - T visit( Node nodeType ); - } - - default boolean isEdge() { - return false; - } - - default boolean isNode() { - return false; - } - - default boolean is( final Class class_ ) { - return class_.isAssignableFrom( getClass() ); - } - - default T as( final Class class_ ) { - return class_.cast( this ); - } - - default Stream view( final Class class_ ) { - return is( class_ ) ? Stream.of( as( class_ ) ) : Stream.empty(); - } - - default Node asNode() { - throw new UnsupportedOperationException(); - } - - default Edge asEdge() { - throw new UnsupportedOperationException(); - } - - T accept( Visitor visitor ); -} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java b/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java deleted file mode 100644 index 5c5db841..00000000 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli.diagram.graph; - -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.FieldDefaults; -import org.semanticweb.owlapi.model.IRI; - -import java.util.Optional; - -/** - * Sealed class that contains the different types of nodes of the ontology graph. - */ -@ToString -@EqualsAndHashCode -@FieldDefaults( makeFinal = true, level = AccessLevel.PRIVATE ) -@Getter -public abstract class Node implements GraphElement { - /** - * Visitor for the nodes - * - * @param the resulting type of the visit operation - */ - public interface Visitor { - T visit( Class class_ ); - - T visit( DataProperty dataProperty ); - - T visit( ObjectProperty objectProperty ); - - T visit( AnnotationProperty annotationProperty ); - - T visit( Individual individual ); - - T visit( Literal literal ); - - T visit( PropertyChain propertyChain ); - - T visit( Datatype datatype ); - - T visit( ExistentialRestriction existentialRestriction ); - - T visit( ValueRestriction valueRestriction ); - - T visit( UniversalRestriction universalRestriction ); - - T visit( Intersection intersection ); - - T visit( Union union ); - - T visit( Disjointness disjointness ); - - T visit( DisjointUnion disjointness ); - - T visit( Equality inequality ); - - T visit( Inverse inverse ); - - T visit( Inequality inequality ); - - T visit( ClosedClass closedClass ); - - T visit( Complement complement ); - - T visit( Self self ); - - T visit( ObjectMinimalCardinality objectMinimalCardinality ); - - T visit( ObjectQualifiedMinimalCardinality objectQualifiedMinimalCardinality ); - - T visit( ObjectMaximalCardinality objectMaximalCardinality ); - - T visit( ObjectQualifiedMaximalCardinality objectQualifiedMaximalCardinality ); - - T visit( ObjectExactCardinality objectExactCardinality ); - - T visit( ObjectQualifiedExactCardinality objectQualifiedExactCardinality ); - - T visit( DataMinimalCardinality dataMinimalCardinality ); - - T visit( DataMaximalCardinality dataMaximalCardinality ); - - T visit( DataExactCardinality dataExactCardinality ); - - T visit( Invisible invisible ); - - T visit( IRIReference iriReference ); - - T visit( PropertyMarker propertyMarker ); - - T visit( Key key ); - - T visit( Rule rule ); - } - - /** - * Id of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the - * ontology element that is represented by the node having this Id. - */ - @Getter - @EqualsAndHashCode - public static class Id { - String id; - Optional iri; - - public Id( final String id, final IRI iri ) { - this.id = id; - this.iri = Optional.of( iri ); - } - - public Id( final String id ) { - this.id = id; - iri = Optional.empty(); - } - - @Override - public String toString() { - return "Id{" + "id='" + id + '\'' + ", iri=" + iri.map( IRI::toString ).orElse( "" ) + '}'; - } - } - - public abstract static class NamedNode extends Node { - public abstract String getName(); - } - - public abstract static class CardinalityNode extends Node { - public abstract int getCardinality(); - } - - public abstract static class InvisibleNode extends Node { - } - - @Override - public T accept( final GraphElement.Visitor visitor ) { - return visitor.visit( this ); - } - - public abstract Node.Id getId(); - - public abstract T accept( final Visitor visitor ); - - public abstract Node withId( Node.Id newId ); - - @Override - public boolean isNode() { - return true; - } - - @Override - public Node asNode() { - return this; - } -} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java b/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java deleted file mode 100644 index 4d99f46d..00000000 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli.diagram.mappers; - -import de.atextor.owlcli.diagram.graph.Graph; -import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; -import org.semanticweb.owlapi.model.OWLAnnotationSubjectVisitorEx; -import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; -import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; -import org.semanticweb.owlapi.model.OWLDataVisitorEx; -import org.semanticweb.owlapi.model.OWLEntityVisitorEx; -import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; -import org.semanticweb.owlapi.model.OWLObjectVisitorEx; -import org.semanticweb.owlapi.model.OWLPropertyExpressionVisitorEx; -import org.semanticweb.owlapi.model.SWRLObjectVisitorEx; - -/** - * Captures the different parts of the ontology-to-graph mapping operation - */ -public interface MappingConfiguration { - OWLAxiomVisitorEx getOwlAxiomMapper(); - - OWLClassExpressionVisitorEx getOwlClassExpressionMapper(); - - OWLIndividualVisitorEx getOwlIndividualMapper(); - - OWLPropertyExpressionVisitorEx getOwlPropertyExpressionMapper(); - - OWLObjectVisitorEx getOwlObjectMapper(); - - OWLDataVisitorEx getOwlDataMapper(); - - OWLEntityVisitorEx getOwlEntityMapper(); - - OWLAnnotationObjectVisitorEx getOwlAnnotationObjectMapper(); - - OWLAnnotationSubjectVisitorEx getOwlAnnotationSubjectMapper(); - - SWRLObjectVisitorEx getSwrlObjectMapper(); - - IdentifierMapper getIdentifierMapper(); - - NameMapper getNameMapper(); - - OWLDataVisitorEx getOwlDataPrinter(); - - OWLPropertyExpressionVisitorEx getOwlPropertyExpressionPrinter(); - - OWLIndividualVisitorEx getOwlIndividualPrinter(); - - OWLClassExpressionVisitorEx getOwlClassExpressionPrinter(); -} diff --git a/docs/build.gradle b/docs/build.gradle deleted file mode 100644 index 1331678f..00000000 --- a/docs/build.gradle +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'com.github.node-gradle.node' version '7.0.0' -} - -apply from: file("${rootDir}/dependencies.gradle") -node { - version = deps.nodejs - npmVersion = deps.npm - download = true - workDir = file("${project.buildDir}/nodejs") - npmWorkDir = file("${project.buildDir}/npm") - nodeProjectDir = file("${project.buildDir}") -} - -task installAntoraCli(type: NpmTask) { - args = ['install', '@antora/cli'] - outputs.file file("${project.buildDir}/node_modules/@antora/cli/bin/antora") -} - -task installAntoraSiteGeneratorLunr(type: NpmTask) { - args = ['install', 'antora-site-generator-lunr'] - outputs.file file("${project.buildDir}/node_modules/antora-site-generator-lunr/lib/index.js") -} - -task installAsciidoctorMathjax(type: NpmTask) { - args = ['install', '@djencks/asciidoctor-mathjax'] - outputs.file file("${project.buildDir}/node_modules/@djencks/asciidoctor-mathjax/lib/asciidoctor-mathjax.js") -} - -task setAntoraVersion(type: Copy) { - ant.replaceregexp(match:'version: .*', replace:"version: ${version}", flags:'g', byline:true) { - fileset(dir: "${project.projectDir}", includes: 'antora.yml') - } -} - -task generateImages() { -} - -task antora(type: NodeTask) { - dependsOn 'installAntoraCli' - dependsOn 'installAntoraSiteGeneratorLunr' - dependsOn 'installAsciidoctorMathjax' - dependsOn 'setAntoraVersion' - dependsOn 'generateImages' - environment = [ - 'DOCSEARCH_ENABLED': 'true', - 'DOCSEARCH_ENGINE': 'lunr' - ] - workingDir = rootProject.projectDir - script = file("${project.buildDir}/node_modules/@antora/cli/bin/antora") - args = ['--generator', 'antora-site-generator-lunr', 'site.yml', '--stacktrace'] -} - -def ontologyDir = 'modules/ROOT/examples' -project.fileTree(dir: ontologyDir, include: '*.ttl').files.each { ttlFile -> - def baseName = ttlFile.name.replaceFirst("[.][^.]+\$", "") - def imageFile = "${project.projectDir}/modules/ROOT/assets/images/${baseName}.svg" - def diagramArgs = ttlFile.getText().contains("top_to_bottom") ? - ['diagram', '--direction', 'top_to_bottom', "${baseName}.ttl", imageFile] : - ['diagram', "${baseName}.ttl", imageFile] - def command = [project(':cli').file('build/bin/owl').getCanonicalPath()] + diagramArgs - tasks.create(name: "${baseName}", type: Exec) { - commandLine command - workingDir = file("${project.projectDir}/${ontologyDir}") - inputs.file file(ttlFile) - outputs.file file(imageFile) - doLast { - if( !project(':cli').file('build/bin/owl').exists() ) { - ant.fail("owlcli binary is not present. Run gradlew nativeImage") - } - } - } - generateImages.dependsOn("${baseName}") -} diff --git a/docs/pom.xml b/docs/pom.xml new file mode 100644 index 00000000..59db9bb7 --- /dev/null +++ b/docs/pom.xml @@ -0,0 +1,372 @@ + + + + + + cool-rdf-parent + cool.rdf + DEV-SNAPSHOT + ../pom.xml + + 4.0.0 + + docs + Cool RDF Docs + + + false + false + true + true + + 2.0.0 + 16.18.0 + 9.6.0 + 3.0.0 + + ${project.build.directory}/node + ${project.build.directory}/node_modules + 1.0.0-alpha.1 + 0.0.9 + ${node-modules-directory}/@antora/cli/bin/antora + + + + + + cool.rdf + cool-rdf-cli + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + + + + + maven-resources-plugin + + + default-resources + process-resources + + resources + + + ${project.build.directory} + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-antora-sources + initialize + + add-resource + + + + + src/docs/antora + + + + + + add-antora-generated-sources + initialize + + add-resource + + + + + src-gen/docs/antora + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + generate-sources + generate-diagrams + + + + + + + + + + + + + + + + + run + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + default-jar + none + + + + + + org.apache.maven.plugins + maven-source-plugin + + true + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + org.apache.maven.plugins + maven-install-plugin + + + default-install + none + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + sign-artifacts + none + + + + + + + + + download-nodejs + + + ${basedir}/target/node + + + + + + com.github.eirslett + frontend-maven-plugin + + + install-node + initialize + + install-node-and-npm + + + + false + + + + target + v${nodejs.version} + ${npm.version} + + + + + + + + + + + download-antora + + + + ${basedir}/target/node_modules + + + + + + com.github.eirslett + frontend-maven-plugin + + target + target + + + + install-antora + initialize + + npm + + + + install @antora/cli@${antora.version} + + + + install-antora-site-generator + initialize + + npm + + + + install @antora/site-generator@${antora.version} + + + + install-antora-lunr-extension + initialize + + npm + + + + install @antora/lunr-extension@${antora-lunr-extension.version} + + + + + install-asciidoctor-mathjax + initialize + + npm + + + + install + @djencks/asciidoctor-mathjax@${antora-mathjax-extension.version} + + + + + + + + + + + antora + + + + org.codehaus.mojo + exec-maven-plugin + + + run-antora + compile + + exec + + + ${project.build.directory} + ${antora-cli} + antora-playbook.yml --stacktrace --fetch + true + + + + + + + + + + + antora-local + + + + org.codehaus.mojo + exec-maven-plugin + + + run-antora + compile + + exec + + + ${project.build.directory} + ${antora-cli} + antora-local.yml --stacktrace --fetch + true + + + + + + + + + diff --git a/docs/src/docs/antora/antora-playbook.yml b/docs/src/docs/antora/antora-playbook.yml new file mode 100644 index 00000000..2c969650 --- /dev/null +++ b/docs/src/docs/antora/antora-playbook.yml @@ -0,0 +1,32 @@ +site: + title: "Cool RDF" + url: https://rdf.cool + start_page: cool-rdf::index.adoc +content: + sources: + - url: ../.. + branches: HEAD + start_path: docs/src/docs/antora +ui: + bundle: + url: https://github.com/cool-rdf/docs-antora-ui/releases/download/v1.0.0/ui-bundle.zip + snapshot: true + supplemental_files: + - path: ui.yml + contents: | + static_files: [ .nojekyll ] + - path: .nojekyll +runtime: + cache_dir: ./.cache/antora +antora: + extensions: + - require: '@antora/lunr-extension' + index_latest_only: true +asciidoc: + extensions: + - '@djencks/asciidoctor-mathjax' + attributes: + doctype: book + sectanchors: true + idprefix: '' + idseparator: '-' \ No newline at end of file diff --git a/docs/antora.yml b/docs/src/docs/antora/antora.yml similarity index 54% rename from docs/antora.yml rename to docs/src/docs/antora/antora.yml index 3db45cdb..72e47e3f 100644 --- a/docs/antora.yml +++ b/docs/src/docs/antora/antora.yml @@ -1,11 +1,12 @@ -name: main -title: owl-cli -version: snapshot +name: cool-rdf +title: Cool RDF +version: master +start_page: ROOT:index.adoc asciidoc: attributes: release-version: snapshot release-tag: snapshot page-component-version: snapshot nav: -- modules/ROOT/nav.adoc + - modules/ROOT/nav.adoc diff --git a/docs/src/docs/antora/modules/ROOT/assets/images/generated/.keep b/docs/src/docs/antora/modules/ROOT/assets/images/generated/.keep new file mode 100644 index 00000000..e69de29b diff --git a/docs/modules/ROOT/assets/images/icon-apple.png b/docs/src/docs/antora/modules/ROOT/assets/images/icon-apple.png similarity index 100% rename from docs/modules/ROOT/assets/images/icon-apple.png rename to docs/src/docs/antora/modules/ROOT/assets/images/icon-apple.png diff --git a/docs/modules/ROOT/assets/images/icon-linux.png b/docs/src/docs/antora/modules/ROOT/assets/images/icon-linux.png similarity index 100% rename from docs/modules/ROOT/assets/images/icon-linux.png rename to docs/src/docs/antora/modules/ROOT/assets/images/icon-linux.png diff --git a/docs/modules/ROOT/assets/images/icon-windows.png b/docs/src/docs/antora/modules/ROOT/assets/images/icon-windows.png similarity index 100% rename from docs/modules/ROOT/assets/images/icon-windows.png rename to docs/src/docs/antora/modules/ROOT/assets/images/icon-windows.png diff --git a/docs/modules/ROOT/assets/images/splash.svg b/docs/src/docs/antora/modules/ROOT/assets/images/splash.svg similarity index 100% rename from docs/modules/ROOT/assets/images/splash.svg rename to docs/src/docs/antora/modules/ROOT/assets/images/splash.svg diff --git a/docs/modules/ROOT/examples/asymmetric-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/asymmetric-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/asymmetric-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/asymmetric-object-property.ttl diff --git a/docs/modules/ROOT/examples/class-assertion.ttl b/docs/src/docs/antora/modules/ROOT/examples/class-assertion.ttl similarity index 100% rename from docs/modules/ROOT/examples/class-assertion.ttl rename to docs/src/docs/antora/modules/ROOT/examples/class-assertion.ttl diff --git a/docs/modules/ROOT/examples/class-intersection.ttl b/docs/src/docs/antora/modules/ROOT/examples/class-intersection.ttl similarity index 100% rename from docs/modules/ROOT/examples/class-intersection.ttl rename to docs/src/docs/antora/modules/ROOT/examples/class-intersection.ttl diff --git a/docs/modules/ROOT/examples/class-union.ttl b/docs/src/docs/antora/modules/ROOT/examples/class-union.ttl similarity index 100% rename from docs/modules/ROOT/examples/class-union.ttl rename to docs/src/docs/antora/modules/ROOT/examples/class-union.ttl diff --git a/docs/modules/ROOT/examples/data-all-values-from.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-all-values-from.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-all-values-from.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-all-values-from.ttl diff --git a/docs/modules/ROOT/examples/data-complement-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-complement-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-complement-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-complement-of.ttl diff --git a/docs/modules/ROOT/examples/data-exact-cardinality.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-exact-cardinality.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-exact-cardinality.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-exact-cardinality.ttl diff --git a/docs/modules/ROOT/examples/data-has-value.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-has-value.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-has-value.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-has-value.ttl diff --git a/docs/modules/ROOT/examples/data-intersection-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-intersection-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-intersection-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-intersection-of.ttl diff --git a/docs/modules/ROOT/examples/data-max-cardinality.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-max-cardinality.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-max-cardinality.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-max-cardinality.ttl diff --git a/docs/modules/ROOT/examples/data-min-cardinality.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-min-cardinality.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-min-cardinality.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-min-cardinality.ttl diff --git a/docs/modules/ROOT/examples/data-one-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-one-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-one-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-one-of.ttl diff --git a/docs/modules/ROOT/examples/data-property-assertion.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-property-assertion.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-property-assertion.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-property-assertion.ttl diff --git a/docs/modules/ROOT/examples/data-property-domain.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-property-domain.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-property-domain.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-property-domain.ttl diff --git a/docs/modules/ROOT/examples/data-property-range.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-property-range.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-property-range.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-property-range.ttl diff --git a/docs/modules/ROOT/examples/data-some-values-from.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-some-values-from.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-some-values-from.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-some-values-from.ttl diff --git a/docs/modules/ROOT/examples/data-union-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/data-union-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/data-union-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/data-union-of.ttl diff --git a/docs/modules/ROOT/examples/datarange-expression.ttl b/docs/src/docs/antora/modules/ROOT/examples/datarange-expression.ttl similarity index 100% rename from docs/modules/ROOT/examples/datarange-expression.ttl rename to docs/src/docs/antora/modules/ROOT/examples/datarange-expression.ttl diff --git a/docs/modules/ROOT/examples/datatype-definition.ttl b/docs/src/docs/antora/modules/ROOT/examples/datatype-definition.ttl similarity index 100% rename from docs/modules/ROOT/examples/datatype-definition.ttl rename to docs/src/docs/antora/modules/ROOT/examples/datatype-definition.ttl diff --git a/docs/modules/ROOT/examples/declaration-annotation-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-annotation-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-annotation-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-annotation-property.ttl diff --git a/docs/modules/ROOT/examples/declaration-class.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-class.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-class.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-class.ttl diff --git a/docs/modules/ROOT/examples/declaration-data-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-data-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-data-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-data-property.ttl diff --git a/docs/modules/ROOT/examples/declaration-datatype.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-datatype.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-datatype.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-datatype.ttl diff --git a/docs/modules/ROOT/examples/declaration-individual.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-individual.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-individual.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-individual.ttl diff --git a/docs/modules/ROOT/examples/declaration-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/declaration-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/declaration-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/declaration-object-property.ttl diff --git a/docs/modules/ROOT/examples/different-individuals.ttl b/docs/src/docs/antora/modules/ROOT/examples/different-individuals.ttl similarity index 100% rename from docs/modules/ROOT/examples/different-individuals.ttl rename to docs/src/docs/antora/modules/ROOT/examples/different-individuals.ttl diff --git a/docs/modules/ROOT/examples/disjoint-classes.ttl b/docs/src/docs/antora/modules/ROOT/examples/disjoint-classes.ttl similarity index 100% rename from docs/modules/ROOT/examples/disjoint-classes.ttl rename to docs/src/docs/antora/modules/ROOT/examples/disjoint-classes.ttl diff --git a/docs/modules/ROOT/examples/disjoint-data-properties.ttl b/docs/src/docs/antora/modules/ROOT/examples/disjoint-data-properties.ttl similarity index 100% rename from docs/modules/ROOT/examples/disjoint-data-properties.ttl rename to docs/src/docs/antora/modules/ROOT/examples/disjoint-data-properties.ttl diff --git a/docs/modules/ROOT/examples/disjoint-object-properties.ttl b/docs/src/docs/antora/modules/ROOT/examples/disjoint-object-properties.ttl similarity index 100% rename from docs/modules/ROOT/examples/disjoint-object-properties.ttl rename to docs/src/docs/antora/modules/ROOT/examples/disjoint-object-properties.ttl diff --git a/docs/modules/ROOT/examples/disjoint-union.ttl b/docs/src/docs/antora/modules/ROOT/examples/disjoint-union.ttl similarity index 100% rename from docs/modules/ROOT/examples/disjoint-union.ttl rename to docs/src/docs/antora/modules/ROOT/examples/disjoint-union.ttl diff --git a/docs/modules/ROOT/examples/equivalent-classes.ttl b/docs/src/docs/antora/modules/ROOT/examples/equivalent-classes.ttl similarity index 100% rename from docs/modules/ROOT/examples/equivalent-classes.ttl rename to docs/src/docs/antora/modules/ROOT/examples/equivalent-classes.ttl diff --git a/docs/modules/ROOT/examples/equivalent-data-properties.ttl b/docs/src/docs/antora/modules/ROOT/examples/equivalent-data-properties.ttl similarity index 100% rename from docs/modules/ROOT/examples/equivalent-data-properties.ttl rename to docs/src/docs/antora/modules/ROOT/examples/equivalent-data-properties.ttl diff --git a/docs/modules/ROOT/examples/equivalent-object-properties.ttl b/docs/src/docs/antora/modules/ROOT/examples/equivalent-object-properties.ttl similarity index 100% rename from docs/modules/ROOT/examples/equivalent-object-properties.ttl rename to docs/src/docs/antora/modules/ROOT/examples/equivalent-object-properties.ttl diff --git a/docs/modules/ROOT/examples/functional-data-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/functional-data-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/functional-data-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/functional-data-property.ttl diff --git a/docs/modules/ROOT/examples/functional-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/functional-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/functional-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/functional-object-property.ttl diff --git a/docs/modules/ROOT/examples/has-key.ttl b/docs/src/docs/antora/modules/ROOT/examples/has-key.ttl similarity index 100% rename from docs/modules/ROOT/examples/has-key.ttl rename to docs/src/docs/antora/modules/ROOT/examples/has-key.ttl diff --git a/docs/modules/ROOT/examples/inverse-functional-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/inverse-functional-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/inverse-functional-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/inverse-functional-object-property.ttl diff --git a/docs/modules/ROOT/examples/inverse-object-properties.ttl b/docs/src/docs/antora/modules/ROOT/examples/inverse-object-properties.ttl similarity index 100% rename from docs/modules/ROOT/examples/inverse-object-properties.ttl rename to docs/src/docs/antora/modules/ROOT/examples/inverse-object-properties.ttl diff --git a/docs/modules/ROOT/examples/irreflexive-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/irreflexive-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/irreflexive-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/irreflexive-object-property.ttl diff --git a/docs/modules/ROOT/examples/negative-data-property-assertion.ttl b/docs/src/docs/antora/modules/ROOT/examples/negative-data-property-assertion.ttl similarity index 100% rename from docs/modules/ROOT/examples/negative-data-property-assertion.ttl rename to docs/src/docs/antora/modules/ROOT/examples/negative-data-property-assertion.ttl diff --git a/docs/modules/ROOT/examples/negative-object-property-assertion.ttl b/docs/src/docs/antora/modules/ROOT/examples/negative-object-property-assertion.ttl similarity index 100% rename from docs/modules/ROOT/examples/negative-object-property-assertion.ttl rename to docs/src/docs/antora/modules/ROOT/examples/negative-object-property-assertion.ttl diff --git a/docs/modules/ROOT/examples/object-all-values-from.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-all-values-from.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-all-values-from.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-all-values-from.ttl diff --git a/docs/modules/ROOT/examples/object-complement-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-complement-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-complement-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-complement-of.ttl diff --git a/docs/modules/ROOT/examples/object-exact-cardinality-qualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-exact-cardinality-qualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-exact-cardinality-qualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-exact-cardinality-qualified.ttl diff --git a/docs/modules/ROOT/examples/object-exact-cardinality-unqualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-exact-cardinality-unqualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-exact-cardinality-unqualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-exact-cardinality-unqualified.ttl diff --git a/docs/modules/ROOT/examples/object-has-self.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-has-self.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-has-self.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-has-self.ttl diff --git a/docs/modules/ROOT/examples/object-has-value.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-has-value.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-has-value.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-has-value.ttl diff --git a/docs/modules/ROOT/examples/object-inverse-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-inverse-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-inverse-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-inverse-of.ttl diff --git a/docs/modules/ROOT/examples/object-max-cardinality-qualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-max-cardinality-qualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-max-cardinality-qualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-max-cardinality-qualified.ttl diff --git a/docs/modules/ROOT/examples/object-max-cardinality-unqualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-max-cardinality-unqualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-max-cardinality-unqualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-max-cardinality-unqualified.ttl diff --git a/docs/modules/ROOT/examples/object-min-cardinality-qualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-min-cardinality-qualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-min-cardinality-qualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-min-cardinality-qualified.ttl diff --git a/docs/modules/ROOT/examples/object-min-cardinality-unqualified.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-min-cardinality-unqualified.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-min-cardinality-unqualified.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-min-cardinality-unqualified.ttl diff --git a/docs/modules/ROOT/examples/object-one-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-one-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-one-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-one-of.ttl diff --git a/docs/modules/ROOT/examples/object-property-assertion.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-property-assertion.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-property-assertion.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-property-assertion.ttl diff --git a/docs/modules/ROOT/examples/object-property-chain.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-property-chain.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-property-chain.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-property-chain.ttl diff --git a/docs/modules/ROOT/examples/object-property-domain.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-property-domain.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-property-domain.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-property-domain.ttl diff --git a/docs/modules/ROOT/examples/object-property-range.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-property-range.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-property-range.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-property-range.ttl diff --git a/docs/modules/ROOT/examples/object-some-values-from.ttl b/docs/src/docs/antora/modules/ROOT/examples/object-some-values-from.ttl similarity index 100% rename from docs/modules/ROOT/examples/object-some-values-from.ttl rename to docs/src/docs/antora/modules/ROOT/examples/object-some-values-from.ttl diff --git a/docs/modules/ROOT/examples/reflexive-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/reflexive-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/reflexive-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/reflexive-object-property.ttl diff --git a/docs/modules/ROOT/examples/same-individuals.ttl b/docs/src/docs/antora/modules/ROOT/examples/same-individuals.ttl similarity index 100% rename from docs/modules/ROOT/examples/same-individuals.ttl rename to docs/src/docs/antora/modules/ROOT/examples/same-individuals.ttl diff --git a/docs/modules/ROOT/examples/sub-data-property-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/sub-data-property-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/sub-data-property-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/sub-data-property-of.ttl diff --git a/docs/modules/ROOT/examples/sub-object-property-of.ttl b/docs/src/docs/antora/modules/ROOT/examples/sub-object-property-of.ttl similarity index 100% rename from docs/modules/ROOT/examples/sub-object-property-of.ttl rename to docs/src/docs/antora/modules/ROOT/examples/sub-object-property-of.ttl diff --git a/docs/modules/ROOT/examples/subclassof.ttl b/docs/src/docs/antora/modules/ROOT/examples/subclassof.ttl similarity index 100% rename from docs/modules/ROOT/examples/subclassof.ttl rename to docs/src/docs/antora/modules/ROOT/examples/subclassof.ttl diff --git a/docs/modules/ROOT/examples/swrl-rule-builtin-atom.ttl b/docs/src/docs/antora/modules/ROOT/examples/swrl-rule-builtin-atom.ttl similarity index 100% rename from docs/modules/ROOT/examples/swrl-rule-builtin-atom.ttl rename to docs/src/docs/antora/modules/ROOT/examples/swrl-rule-builtin-atom.ttl diff --git a/docs/modules/ROOT/examples/swrl-rule-class-atom-with-expression.ttl b/docs/src/docs/antora/modules/ROOT/examples/swrl-rule-class-atom-with-expression.ttl similarity index 100% rename from docs/modules/ROOT/examples/swrl-rule-class-atom-with-expression.ttl rename to docs/src/docs/antora/modules/ROOT/examples/swrl-rule-class-atom-with-expression.ttl diff --git a/docs/modules/ROOT/examples/swrl-rule-class-atom.ttl b/docs/src/docs/antora/modules/ROOT/examples/swrl-rule-class-atom.ttl similarity index 100% rename from docs/modules/ROOT/examples/swrl-rule-class-atom.ttl rename to docs/src/docs/antora/modules/ROOT/examples/swrl-rule-class-atom.ttl diff --git a/docs/modules/ROOT/examples/swrl-rule-data-range-atom.ttl b/docs/src/docs/antora/modules/ROOT/examples/swrl-rule-data-range-atom.ttl similarity index 100% rename from docs/modules/ROOT/examples/swrl-rule-data-range-atom.ttl rename to docs/src/docs/antora/modules/ROOT/examples/swrl-rule-data-range-atom.ttl diff --git a/docs/modules/ROOT/examples/swrl-rule-object-property-atom.ttl b/docs/src/docs/antora/modules/ROOT/examples/swrl-rule-object-property-atom.ttl similarity index 100% rename from docs/modules/ROOT/examples/swrl-rule-object-property-atom.ttl rename to docs/src/docs/antora/modules/ROOT/examples/swrl-rule-object-property-atom.ttl diff --git a/docs/modules/ROOT/examples/symmetric-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/symmetric-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/symmetric-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/symmetric-object-property.ttl diff --git a/docs/modules/ROOT/examples/transitive-object-property.ttl b/docs/src/docs/antora/modules/ROOT/examples/transitive-object-property.ttl similarity index 100% rename from docs/modules/ROOT/examples/transitive-object-property.ttl rename to docs/src/docs/antora/modules/ROOT/examples/transitive-object-property.ttl diff --git a/docs/modules/ROOT/nav.adoc b/docs/src/docs/antora/modules/ROOT/nav.adoc similarity index 100% rename from docs/modules/ROOT/nav.adoc rename to docs/src/docs/antora/modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/diagram-notation.adoc b/docs/src/docs/antora/modules/ROOT/pages/diagram-notation.adoc similarity index 73% rename from docs/modules/ROOT/pages/diagram-notation.adoc rename to docs/src/docs/antora/modules/ROOT/pages/diagram-notation.adoc index 1939f0e8..62c44b92 100644 --- a/docs/modules/ROOT/pages/diagram-notation.adoc +++ b/docs/src/docs/antora/modules/ROOT/pages/diagram-notation.adoc @@ -1,89 +1,79 @@ // -*- fill-column: 100; -*- = OWL Diagram Notation - == Introduction -This page describes the graphical notation for ontology diagrams generated by *owl-cli*. There is no -standard diagram notation for OWL, but a number of tools provide their own notation. Popular options -are the https://protege.stanford.edu/[Protégé] plugins +This page describes the graphical notation for ontology diagrams generated by *owl-cli*. +There is no standard diagram notation for OWL, but a number of tools provide their own notation. +Popular options are the https://protege.stanford.edu/[Protégé] plugins https://protegewiki.stanford.edu/wiki/OWLViz[OWLViz] and https://protegewiki.stanford.edu/wiki/OntoGraf[OntoGraf], as well as the https://www.topquadrant.com/graphical-ontology-editing-with-topbraid-composers-diagram-tab/[graphical -notation] of https://www.topquadrant.com/products/topbraid-composer/[Topbraid Composer]. Most -notations have a strong focus on class and instance relationships, which is well-suited for -visualizing this particular kind of ontology. However, other types of axioms, in particular more -complex class expressions, are usually not represented. For this reason, during the writing of the -https://kobra.uni-kassel.de/handle/123456789/2018051455498[PhD thesis], a more general graphical -notation for ontologies was developed. +notation] of https://www.topquadrant.com/products/topbraid-composer/[Topbraid Composer]. +Most notations have a strong focus on class and instance relationships, which is well-suited for visualizing this particular kind of ontology. +However, other types of axioms, in particular more complex class expressions, are usually not represented. +For this reason, during the writing of the +https://kobra.uni-kassel.de/handle/123456789/2018051455498[PhD thesis], a more general graphical notation for ontologies was developed. The notation by *owl-cli* is influenced by the following other notations for OWL ontologies: -* The symbols and colors for classes, properties and data types as popularized by the Protégé - ontology editor and also used by Topbraid Composer. -* The notation from the https://kobra.uni-kassel.de/handle/123456789/2018051455498[PhD thesis] (as - shown on pages 43 and 44), but with less focus on Description Logics notation and instead using - the expressions syntax from Protégé. +* The symbols and colors for classes, properties and data types as popularized by the Protégé ontology editor and also used by Topbraid Composer. +* The notation from the https://kobra.uni-kassel.de/handle/123456789/2018051455498[PhD thesis] (as shown on pages 43 and 44), but with less focus on Description Logics notation and instead using the expressions syntax from Protégé. * Arrows from UML (hollow arrow for inheritance, solid arrow for relations). * Representation of OWL class restrictions and other elements in the specification of the - https://www.omg.org/spec/ODM[OMG Ontology Definition Metamodel 1.1], cf. for example Figures - 14.25, 14.26 and 14.27. +https://www.omg.org/spec/ODM[OMG Ontology Definition Metamodel 1.1], cf. for example Figures 14.25, 14.26 and 14.27. * The symbol for disjoint unions that is used in http://vowl.visualdataweb.org/[VOWL]. The notation was designed with the following goals in mind: * It must be possible to represent all OWL axioms in a meaningful way. -* The diagrams are used mainly for visualizing in documents, not necessarily for interactively - editing an ontology. -* The diagram should be understandable for people familiar with the Protégé editor, because it is - probably the most popular ontology editor. -* The semantics should be unambiguous from the visual representation: For example, using a UML-like - class diagram for an OWL class that includes properties in its box like class attributes in UML is - not self-explanatory: Are the properties restrictions on the class (existential? universal? - both?), is the class the domain of the properties? Both have very different meanings than what a - UML-like representation suggests. +* The diagrams are used mainly for visualizing in documents, not necessarily for interactively editing an ontology. +* The diagram should be understandable for people familiar with the Protégé editor, because it is probably the most popular ontology editor. +* The semantics should be unambiguous from the visual representation: For example, using a UML-like class diagram for an OWL class that includes properties in its box like class attributes in UML is not self-explanatory: Are the properties restrictions on the class (existential? universal? +both?), is the class the domain of the properties? +Both have very different meanings than what a UML-like representation suggests. The following sections describe the graphical notation using examples. -TIP: All diagrams on this page were generated with *owl-cli*. Each diagram links to the RDF/Turtle -file it was generated from. +TIP: All diagrams on this page were generated with *owl-cli*. +Each diagram links to the RDF/Turtle file it was generated from. == Element Types .Mapping Syntax for OWL Element Types -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Element|Description Logics Notation|Diagram |Class(latexmath:[C]) |latexmath:[C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-class.ttl] -image::declaration-class.svg[Class Declaration] +image::generated/declaration-class.svg[Class Declaration] |ObjectProperty(latexmath:[P]) |latexmath:[P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-object-property.ttl] -image::declaration-object-property.svg[Object Property Declaration] +image::generated/declaration-object-property.svg[Object Property Declaration] |DataProperty(latexmath:[P]) |latexmath:[P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-data-property.ttl] -image::declaration-data-property.svg[Data Property Declaration] +image::generated/declaration-data-property.svg[Data Property Declaration] |AnnotationProperty(latexmath:[P]) |_no notation_ |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-annotation-property.ttl] -image::declaration-annotation-property.svg[Annotation Property Declaration] +image::generated/declaration-annotation-property.svg[Annotation Property Declaration] |NamedIndividual(latexmath:[o]) |latexmath:[o] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-individual.ttl] -image::declaration-individual.svg[Named Individual Declaration] +image::generated/declaration-individual.svg[Named Individual Declaration] |Datatype(latexmath:[D]) |_no notation_ |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/declaration-datatype.ttl] -image::declaration-datatype.svg[Datatype Declaration] +image::generated/declaration-datatype.svg[Datatype Declaration] |=== @@ -92,34 +82,34 @@ image::declaration-datatype.svg[Datatype Declaration] NOTE: This section is aligned to the https://www.w3.org/TR/owl2-syntax/#Data_Ranges[corresponding section] in the OWL 2 Specification. .Mapping Syntax for Data Ranges -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Intersection_of_Data_Ranges[DataIntersectionOf](latexmath:[U_1\,\dots\,U_n]) |latexmath:[U_1\,\sqcap\,\cdots\,\sqcap\,U_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-intersection-of.ttl] -image::data-intersection-of.svg[Intersection of Data Ranges] +image::generated/data-intersection-of.svg[Intersection of Data Ranges] |https://www.w3.org/TR/owl2-syntax/#Union_of_Data_Ranges[DataUnionOf](latexmath:[U_1\,\dots\,U_n]) |latexmath:[U_1\,\sqcup\,\cdots\,\sqcup\,U_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-union-of.ttl] -image::data-union-of.svg[Union of Data Ranges] +image::generated/data-union-of.svg[Union of Data Ranges] |https://www.w3.org/TR/owl2-syntax/#Complement_of_Class_Expressions[DataComplementOf](latexmath:[U]) |latexmath:[\neg\,U] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-complement-of.ttl] -image::data-complement-of.svg[Complement of Data Ranges] +image::generated/data-complement-of.svg[Complement of Data Ranges] |https://www.w3.org/TR/owl2-syntax/#Enumeration_of_Literals[DataOneOf](latexmath:[v_1\,\dots\,v_n]) |latexmath:[\{v_1\}\,\sqcup\,\cdots\,\sqcup\,\{v_n\}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-one-of.ttl] -image::data-one-of.svg[Enumeration of Literals] +image::generated/data-one-of.svg[Enumeration of Literals] |https://www.w3.org/TR/owl2-syntax/#Datatype_Restrictions[DatatypeRestriction]( int minExclusive 4 maxInclusive 10 ) |_no notation_ |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/datarange-expression.ttl] -image::datarange-expression.svg[Data Range with Numeric Restriction] +image::generated/datarange-expression.svg[Data Range with Numeric Restriction] |=== @@ -130,149 +120,149 @@ NOTE: The outline of this section is aligned to the https://www.w3.org/TR/owl2-s === Propositional Connectives and Enumeration of Individuals .Mapping Syntax for Propositional Connectives and Enumeration of Individuals -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Intersection_of_Class_Expressions[ObjectIntersectionOf](latexmath:[C_1\,\dots\,C_n]) |latexmath:[C_1\,\sqcap\,\cdots\,\sqcap\,C_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/class-intersection.ttl] -image::class-intersection.svg[Class Intersection] +image::generated/class-intersection.svg[Class Intersection] |https://www.w3.org/TR/owl2-syntax/#Union_of_Class_Expressions[ObjectUnionOf](latexmath:[C_1\,\dots\,C_n]) |latexmath:[C_1\,\sqcup\,\cdots\,\sqcup\,C_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/class-union.ttl] -image::class-union.svg[Class Union] +image::generated/class-union.svg[Class Union] |https://www.w3.org/TR/owl2-syntax/#Complement_of_Class_Expressions[ObjectComplementOf](latexmath:[C]) |latexmath:[\neg\,C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-complement-of.ttl] -image::object-complement-of.svg[Complement of a Class Expression] +image::generated/object-complement-of.svg[Complement of a Class Expression] |https://www.w3.org/TR/owl2-syntax/#Enumeration_of_Individuals[ObjectOneOf](latexmath:[o_1\,\dots\,o_n]) |latexmath:[\{o_1\}\,\sqcup\,\cdots\,\sqcup\,\{o_n\}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-one-of.ttl] -image::object-one-of.svg[Enumeration of Individuals] +image::generated/object-one-of.svg[Enumeration of Individuals] |=== === Object Property Restrictions .Mapping Syntax for Object Property Restrictions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Existential_Quantification[ObjectSomeValuesFrom](latexmath:[P\,C]) |latexmath:[\exists\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-some-values-from.ttl] -image::object-some-values-from.svg[Object Some-Values-From Property Restriction] +image::generated/object-some-values-from.svg[Object Some-Values-From Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Universal_Quantification[ObjectAllValuesFrom](latexmath:[P\,C]) |latexmath:[\forall\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-all-values-from.ttl] -image::object-all-values-from.svg[Object All-Values-From Property Restriction] +image::generated/object-all-values-from.svg[Object All-Values-From Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Individual_Value_Restriction[ObjectHasValue](latexmath:[P\,o]) |latexmath:[P\,\ni\,o] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-has-value.ttl] -image::object-has-value.svg[Object Has-Value Property Restriction] +image::generated/object-has-value.svg[Object Has-Value Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Inverse_Object_Properties[ObjectInverseOf](latexmath:[P]) |latexmath:[P^{-}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-inverse-of.ttl] -image::object-inverse-of.svg[Object Inverse-Of Property Restriction] +image::generated/object-inverse-of.svg[Object Inverse-Of Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Self-Restriction[ObjectHasSelf](latexmath:[P]) |latexmath:[\text{Self}(P)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-has-self.ttl] -image::object-has-self.svg[Object Has-Self Property Restriction] +image::generated/object-has-self.svg[Object Has-Self Property Restriction] |=== === Object Property Cardinality Restrictions .Mapping Syntax for Object Property Cardinality Restrictions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality[ObjectMinCardinality](latexmath:[n\,P]) |latexmath:[\geq\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-min-cardinality-unqualified.ttl] -image::object-min-cardinality-unqualified.svg[Object Mininum Cardinality Restriction] +image::generated/object-min-cardinality-unqualified.svg[Object Mininum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality[ObjectMinCardinality](latexmath:[n\,P\,C]) |latexmath:[\geq\,n\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-min-cardinality-qualified.ttl] -image::object-min-cardinality-qualified.svg[Object Qualified Mininum Cardinality Restriction] +image::generated/object-min-cardinality-qualified.svg[Object Qualified Mininum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Maximum_Cardinality[ObjectMaxCardinality](latexmath:[n\,P]) |latexmath:[\leq\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-max-cardinality-unqualified.ttl] -image::object-max-cardinality-unqualified.svg[Object Maximum Cardinality Restriction] +image::generated/object-max-cardinality-unqualified.svg[Object Maximum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Maximum_Cardinality[ObjectMaxCardinality](latexmath:[n\,P\,C]) |latexmath:[\leq\,n\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-max-cardinality-qualified.ttl] -image::object-max-cardinality-qualified.svg[Object Qualified Maximum Cardinality Restriction] +image::generated/object-max-cardinality-qualified.svg[Object Qualified Maximum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Exact_Cardinality[ObjectExactCardinality](latexmath:[n\,P]) |latexmath:[=\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-exact-cardinality-unqualified.ttl] -image::object-exact-cardinality-unqualified.svg[Object Exact Cardinality Restriction] +image::generated/object-exact-cardinality-unqualified.svg[Object Exact Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Exact_Cardinality[ObjectExactCardinality](latexmath:[n\,P\,C]) |latexmath:[=\,n\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-exact-cardinality-qualified.ttl] -image::object-exact-cardinality-qualified.svg[Object Qualified Exact Cardinality Restriction] +image::generated/object-exact-cardinality-qualified.svg[Object Qualified Exact Cardinality Restriction] |=== === Data Property Restrictions .Mapping Syntax for Data Property Restrictions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Existential_Quantification_2[DataSomeValuesFrom](latexmath:[P\,C]) |latexmath:[\exists\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-some-values-from.ttl] -image::data-some-values-from.svg[Data Some-Values-From Property Restriction] +image::generated/data-some-values-from.svg[Data Some-Values-From Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Universal_Quantification_2[DataAllValuesFrom](latexmath:[P\,C]) |latexmath:[\forall\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-all-values-from.ttl] -image::data-all-values-from.svg[Data All-Values-From Property Restriction] +image::generated/data-all-values-from.svg[Data All-Values-From Property Restriction] |https://www.w3.org/TR/owl2-syntax/#Literal_Value_Restriction[DataHasValue](latexmath:[P\,v]) |latexmath:[P\,\ni\,v] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-has-value.ttl] -image::data-has-value.svg[Data Has-Value Property Restriction] +image::generated/data-has-value.svg[Data Has-Value Property Restriction] |=== === Data Property Cardinality Restrictions .Mapping Syntax for Data Property Cardinality Restrictions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Expression|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality_2[DataMinCardinality](latexmath:[n\,P]) |latexmath:[\geq\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-min-cardinality.ttl] -image::data-min-cardinality.svg[Data Minimum Cardinality Restriction] +image::generated/data-min-cardinality.svg[Data Minimum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Maximum_Cardinality_2[DataMaxCardinality](latexmath:[n\,P]) |latexmath:[\leq\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-max-cardinality.ttl] -image::data-max-cardinality.svg[Data Maximum Cardinality Restriction] +image::generated/data-max-cardinality.svg[Data Maximum Cardinality Restriction] |https://www.w3.org/TR/owl2-syntax/#Exact_Cardinality_2[DataExactCardinality](latexmath:[n\,P]) |latexmath:[=\,n\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-exact-cardinality.ttl] -image::data-exact-cardinality.svg[Data Exact Cardinality Restriction] +image::generated/data-exact-cardinality.svg[Data Exact Cardinality Restriction] |=== @@ -283,254 +273,253 @@ NOTE: The outline of this section is aligned to the https://www.w3.org/TR/owl2-s === Class Expression Axioms .Mapping Syntax for Class Expression Axioms -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Subclass_Axioms[SubClassOf](latexmath:[C_1\,C_2]) |latexmath:[C_1\,\sqsubseteq\,C_2] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/subclassof.ttl] -image::subclassof.svg[Subclasses] +image::generated/subclassof.svg[Subclasses] |https://www.w3.org/TR/owl2-syntax/#Equivalent_Classes[EquivalentClasses](latexmath:[C_1\,\dots\,C_n]) |latexmath:[C_1\,\equiv\,\cdots\,\equiv\,C_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/equivalent-classes.ttl] -image::equivalent-classes.svg[Equivalent Classes] +image::generated/equivalent-classes.svg[Equivalent Classes] |https://www.w3.org/TR/owl2-syntax/#Disjoint_Classes[DisjointClasses](latexmath:[C_1\,\dots\,C_n]) |latexmath:[C_i\,\sqcap\,C_j\,\sqsubseteq\,\bot,\,i\,\neq\,j] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/disjoint-classes.ttl] -image::disjoint-classes.svg[Disjoint Classes] +image::generated/disjoint-classes.svg[Disjoint Classes] |https://www.w3.org/TR/owl2-syntax/#Disjoint_Union_of_Class_Expressions[DisjointUnion](latexmath:[C\,C_1\,\dots\,C_n]) a|latexmath:[C\,\equiv\,C_1\,\sqcup\,\cdots\,\sqcup\,C_n,] latexmath:[C_i\,\sqcap\,C_j\,\sqsubseteq\,\bot,\,i\,\neq\,j] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/disjoint-union.ttl] -image::disjoint-union.svg[Disjoint Union] +image::generated/disjoint-union.svg[Disjoint Union] |=== === Object Property Axioms .Mapping Syntax for Object Property Axioms -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Object_Subproperties[SubObjectPropertyOf](latexmath:[P_1\,P_2]) |latexmath:[P_1\,\sqsubseteq\,P_2] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/sub-object-property-of.ttl] -image::sub-object-property-of.svg[Sub-Object-Properties] +image::generated/sub-object-property-of.svg[Sub-Object-Properties] |https://www.w3.org/TR/owl2-syntax/#Object_Subproperties[ObjectPropertyChain](latexmath:[P_1\,\dots\,P_n]) |latexmath:[P_1\,\circ\,\cdots\,\circ\,P_n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-property-chain.ttl] -image::object-property-chain.svg[Object Property Chains] +image::generated/object-property-chain.svg[Object Property Chains] |https://www.w3.org/TR/owl2-syntax/#Equivalent_Object_Properties[EquivalentObjectProperties](latexmath:[P_1\,P_2]) |latexmath:[P_1\,\equiv\,P_2] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/equivalent-object-properties.ttl] -image::equivalent-object-properties.svg[Equivalent Object Properties] +image::generated/equivalent-object-properties.svg[Equivalent Object Properties] |https://www.w3.org/TR/owl2-syntax/#Disjoint_Object_Properties[DisjointObjectProperties](latexmath:[P_1\,P_2]) |latexmath:[\text{Disjoint}(P_1,P_2)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/disjoint-object-properties.ttl] -image::disjoint-object-properties.svg[Disjoint Object Properties] +image::generated/disjoint-object-properties.svg[Disjoint Object Properties] |https://www.w3.org/TR/owl2-syntax/#Inverse_Object_Properties_2[InverseObjectProperties](latexmath:[P_1\,P_2]) |latexmath:[P_1\,\equiv\,P_2^{-}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/inverse-object-properties.ttl] -image::inverse-object-properties.svg[Inverse Object Properties] +image::generated/inverse-object-properties.svg[Inverse Object Properties] |https://www.w3.org/TR/owl2-syntax/#Object_Property_Domain[ObjectPropertyDomain](latexmath:[C\,P]) |latexmath:[\geq\,1\,P\,\sqsubseteq\,C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-property-domain.ttl] -image::object-property-domain.svg[Object Property Domain] +image::generated/object-property-domain.svg[Object Property Domain] |https://www.w3.org/TR/owl2-syntax/#Object_Property_Range[ObjectPropertyRange](latexmath:[C\,P]) |latexmath:[\top\,\sqsubseteq\,\forall\,P.C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-property-range.ttl] -image::object-property-range.svg[Object Property Range] +image::generated/object-property-range.svg[Object Property Range] |https://www.w3.org/TR/owl2-syntax/#Functional_Object_Properties[FunctionalObjectProperty](latexmath:[P]) |latexmath:[\top\,\sqsubseteq\,\leq\,1\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/functional-object-property.ttl] -image::functional-object-property.svg[Functional Object Property] +image::generated/functional-object-property.svg[Functional Object Property] |https://www.w3.org/TR/owl2-syntax/#Inverse-Functional_Object_Properties[InverseFunctionalObjectProperty](latexmath:[P]) |latexmath:[\top\,\sqsubseteq\,\leq\,1\,P^{-}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/inverse-functional-object-property.ttl] -image::inverse-functional-object-property.svg[Inverse Functional Object Property] +image::generated/inverse-functional-object-property.svg[Inverse Functional Object Property] |https://www.w3.org/TR/owl2-syntax/#Reflexive_Object_Properties[ReflexiveObjectProperty](latexmath:[P]) |latexmath:[\top\,\sqsubseteq\,\exists\,P.\text{Self}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/reflexive-object-property.ttl] -image::reflexive-object-property.svg[Reflexive Object Property] +image::generated/reflexive-object-property.svg[Reflexive Object Property] |https://www.w3.org/TR/owl2-syntax/#Irreflexive_Object_Properties[IrreflexiveObjectProperty](latexmath:[P]) |latexmath:[\top\,\sqsubseteq\,\neg\exists\,P.\text{Self}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/irreflexive-object-property.ttl] -image::irreflexive-object-property.svg[Irreflexive Object Property] +image::generated/irreflexive-object-property.svg[Irreflexive Object Property] |https://www.w3.org/TR/owl2-syntax/#Symmetric_Object_Properties[SymmetricObjectProperty](latexmath:[P]) |latexmath:[P\,\equiv\,P^{-}] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/symmetric-object-property.ttl] -image::symmetric-object-property.svg[Symmetric Object Property] +image::generated/symmetric-object-property.svg[Symmetric Object Property] |https://www.w3.org/TR/owl2-syntax/#Asymmetric_Object_Properties[AsymmetricObjectProperty](latexmath:[P]) |latexmath:[\text{Disjoint}(P,P^{-})] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/asymmetric-object-property.ttl] -image::asymmetric-object-property.svg[Symmetric Object Property] +image::generated/asymmetric-object-property.svg[Symmetric Object Property] |https://www.w3.org/TR/owl2-syntax/#Transitive_Object_Properties[TransitiveObjectProperty](latexmath:[P]) |latexmath:[P\,\circ\,P\,\sqsubseteq\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/transitive-object-property.ttl] -image::transitive-object-property.svg[Transitive Object Property] +image::generated/transitive-object-property.svg[Transitive Object Property] |=== === Data Property Axioms .Mapping Syntax for Data Property Axioms -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Data_Subproperties[SubDataPropertyOf](latexmath:[P_1\,P_2]) |latexmath:[P_1\,\sqsubseteq\,P_2] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/sub-data-property-of.ttl] -image::sub-data-property-of.svg[Sub-Data-Properties] +image::generated/sub-data-property-of.svg[Sub-Data-Properties] |https://www.w3.org/TR/owl2-syntax/#Equivalent_Data_Properties[EquivalentDataProperties](latexmath:[P_1\,P_2]) |latexmath:[P_1\,\equiv\,P_2] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/equivalent-data-properties.ttl] -image::equivalent-data-properties.svg[Equivalent Data Properties] +image::generated/equivalent-data-properties.svg[Equivalent Data Properties] |https://www.w3.org/TR/owl2-syntax/#Disjoint_Data_Properties[DisjointDataProperties](latexmath:[P_1\,P_2]) |latexmath:[\text{Disjoint}(P_1,P_2)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/disjoint-data-properties.ttl] -image::disjoint-data-properties.svg[Disjoint Data Properties] +image::generated/disjoint-data-properties.svg[Disjoint Data Properties] |https://www.w3.org/TR/owl2-syntax/#Data_Property_Domain[DataPropertyDomain](latexmath:[C\,P]) |latexmath:[\geq\,1\,P\,\sqsubseteq\,C] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-property-domain.ttl] -image::data-property-domain.svg[Data Property Domain] +image::generated/data-property-domain.svg[Data Property Domain] |https://www.w3.org/TR/owl2-syntax/#Data_Property_Range[DataPropertyRange](latexmath:[D\,P]) |latexmath:[\top\,\sqsubseteq\,\forall\,P.D] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-property-range.ttl] -image::data-property-range.svg[Data Property Range] +image::generated/data-property-range.svg[Data Property Range] |https://www.w3.org/TR/owl2-syntax/#Functional_Data_Properties[FunctionalDataProperty](latexmath:[P]) |latexmath:[\top\,\sqsubseteq\,\leq\,1D] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/functional-data-property.ttl] -image::functional-data-property.svg[Functional Data Property] +image::generated/functional-data-property.svg[Functional Data Property] |=== === Datatype Definitions .Mapping Syntax for Datatype Definitions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Datatype_Definitions[DatatypeDefinition](latexmath:[D\,\text{range}]) |_no notation_ |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/datatype-definition.ttl] -image::datatype-definition.svg[Datatype Definition] +image::generated/datatype-definition.svg[Datatype Definition] |=== === Keys .Mapping Syntax for Keys -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Keys[HasKeys](latexmath:[C\,P_1\,\dots\,P_n]) |_no notation_ |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/has-key.ttl] -image::has-key.svg[Has Keys] +image::generated/has-key.svg[Has Keys] |=== === Assertions .Mapping Syntax for Assertions -[cols="^.^,^.^,^.^a", options="header"] +[cols="^.^,^.^,^.^a",options="header"] |=== |OWL Axiom|Description Logics Notation|Diagram |https://www.w3.org/TR/owl2-syntax/#Individual_Equality[SameIndividuals](latexmath:[o_1\,\dots\,o_n]) |latexmath:[o_i\,=\,o_j,1 \leq i \lt j \leq n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/same-individuals.ttl] -image::same-individuals.svg[Same Individuals Assertion] +image::generated/same-individuals.svg[Same Individuals Assertion] |https://www.w3.org/TR/owl2-syntax/#Individual_Inequality[DifferentIndividuals](latexmath:[o_1\,\dots\,o_n]) |latexmath:[o_i\,\not=\,o_j,1 \leq i \lt j \leq n] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/different-individuals.ttl] -image::different-individuals.svg[Different Individuals Assertion] +image::generated/different-individuals.svg[Different Individuals Assertion] |https://www.w3.org/TR/owl2-syntax/#Class_Assertions[ClassAssertion](latexmath:[C\,o]) |latexmath:[C(o)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/class-assertion.ttl] -image::class-assertion.svg[Class Assertion] +image::generated/class-assertion.svg[Class Assertion] |https://www.w3.org/TR/owl2-syntax/#Positive_Object_Property_Assertions[ObjectPropertyAssertion](latexmath:[P\,o_1\,o_2]) |latexmath:[P(o_1,o_2)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/object-property-assertion.ttl] -image::object-property-assertion.svg[Object Property Assertion] +image::generated/object-property-assertion.svg[Object Property Assertion] |https://www.w3.org/TR/owl2-syntax/#Negative_Object_Property_Assertions[NegativeObjectPropertyAssertion](latexmath:[P\,o_1\,o_2]) |latexmath:[(o_1,o_2):\neg\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/negative-object-property-assertion.ttl] -image::negative-object-property-assertion.svg[Negative Object Property Assertion] +image::generated/negative-object-property-assertion.svg[Negative Object Property Assertion] |https://www.w3.org/TR/owl2-syntax/#Positive_Data_Property_Assertions[DataPropertyAssertion](latexmath:[P\,o\,v]) |latexmath:[P(o,v)] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/data-property-assertion.ttl] -image::data-property-assertion.svg[Data Property Assertion] +image::generated/data-property-assertion.svg[Data Property Assertion] |https://www.w3.org/TR/owl2-syntax/#Negative_Data_Property_Assertions[NegativeDataPropertyAssertion](latexmath:[P\,o\,v]) |latexmath:[(o,v):\neg\,P] |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/negative-data-property-assertion.ttl] -image::negative-data-property-assertion.svg[Negative Data Property Assertion] +image::generated/negative-data-property-assertion.svg[Negative Data Property Assertion] |=== == SWRL Rules -Rules defined in the https://www.w3.org/Submission/SWRL/[Semantic Web Rule Language] (SWRL) can be -embedded in an OWL ontology. Rules are rendered as described in -https://www.w3.org/Submission/SWRL/#2.2[Human Readable Syntax], and are linked with the ontology -entities they refer to. The following table shows rendering examples for the different kinds of -rule atoms. +Rules defined in the https://www.w3.org/Submission/SWRL/[Semantic Web Rule Language] (SWRL) can be embedded in an OWL ontology. +Rules are rendered as described in +https://www.w3.org/Submission/SWRL/#2.2[Human Readable Syntax], and are linked with the ontology entities they refer to. +The following table shows rendering examples for the different kinds of rule atoms. .Mapping Syntax for SWRL Rules -[cols="^.^,^.^a", options="header"] +[cols="^.^,^.^a",options="header"] |=== |Atom Type|Diagram |Class |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/swrl-rule-class-atom.ttl] -image::swrl-rule-class-atom.svg[SWRL Rule with Class Atoms] +image::generated/swrl-rule-class-atom.svg[SWRL Rule with Class Atoms] |Class with Expression |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/swrl-rule-class-atom-with-expression.ttl] -image::swrl-rule-class-atom-with-expression.svg[SWRL Rule with Class Atoms with Class Expression] +image::generated/swrl-rule-class-atom-with-expression.svg[SWRL Rule with Class Atoms with Class Expression] |Object Property |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/swrl-rule-object-property-atom.ttl] -image::swrl-rule-object-property-atom.svg[SWRL Rule with Object Property Atom] +image::generated/swrl-rule-object-property-atom.svg[SWRL Rule with Object Property Atom] |Data Property, Data Range |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/swrl-rule-data-range-atom.ttl] -image::swrl-rule-data-range-atom.svg[SWRL Rule with Data Property Atom and Data Range Atom] +image::generated/swrl-rule-data-range-atom.svg[SWRL Rule with Data Property Atom and Data Range Atom] |Data Property, Builtin |[link=https://github.com/atextor/owl-cli/blob/{release-tag}/docs/modules/ROOT/examples/swrl-rule-builtin-atom.ttl] -image::swrl-rule-builtin-atom.svg[SWRL Rule with Data Property Atom and Builtin Atom] +image::generated/swrl-rule-builtin-atom.svg[SWRL Rule with Data Property Atom and Builtin Atom] |=== diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/src/docs/antora/modules/ROOT/pages/index.adoc similarity index 100% rename from docs/modules/ROOT/pages/index.adoc rename to docs/src/docs/antora/modules/ROOT/pages/index.adoc diff --git a/docs/modules/ROOT/pages/release-notes.adoc b/docs/src/docs/antora/modules/ROOT/pages/release-notes.adoc similarity index 78% rename from docs/modules/ROOT/pages/release-notes.adoc rename to docs/src/docs/antora/modules/ROOT/pages/release-notes.adoc index db0547d6..5c0101d4 100644 --- a/docs/modules/ROOT/pages/release-notes.adoc +++ b/docs/src/docs/antora/modules/ROOT/pages/release-notes.adoc @@ -1,6 +1,15 @@ // -*- fill-column: 100; -*- = Release Notes +== Version 1.2.6 +* Changes in xref:usage.adoc#write-command[write] command: Correct formatting of `rdf:Lists` with + additional properties; fixed decimal formatting in locales other than US, deterministic ordering + of blank nodes. Double values are now by default formatted like in the source model. + +== Version 1.2.5 +* Changes in xref:usage.adoc#write-command[write] command: `rdf:type` used as an object in a triple + is not rendered as `a` any more. + == Version 1.2.4 * Changes in xref:usage.adoc#write-command[write] command: Triple-quotes strings that happen to end with a quote are escaped correctly. diff --git a/docs/modules/ROOT/pages/usage.adoc b/docs/src/docs/antora/modules/ROOT/pages/usage.adoc similarity index 100% rename from docs/modules/ROOT/pages/usage.adoc rename to docs/src/docs/antora/modules/ROOT/pages/usage.adoc diff --git a/docs/ui-bundle.zip b/docs/src/docs/resources/ui-bundle.zip similarity index 100% rename from docs/ui-bundle.zip rename to docs/src/docs/resources/ui-bundle.zip diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 7d521816..00000000 --- a/gradle.properties +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright 2021 Andreas Textor -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -version=snapshot \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index c1962a79..00000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index bdc9a83b..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip -networkTimeout=10000 -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index aeb74cbb..00000000 --- a/gradlew +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 6689b85b..00000000 --- a/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/infer/build.gradle b/infer/build.gradle deleted file mode 100644 index ab4a5579..00000000 --- a/infer/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.jena) - implementation(deps.jena_core) - implementation(deps.slf4j_api) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - implementation(deps.openllet) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..20793e54 --- /dev/null +++ b/pom.xml @@ -0,0 +1,746 @@ + + + + + 4.0.0 + + cool.rdf + cool-rdf-parent + DEV-SNAPSHOT + pom + + Cool RDF + Cool RDF provides APIs and a command line interface to transform, manipulate, + validate and visualize RDF and OWL documents. + + 2019 + https://rdf.cool + + + GitHub Issues + https://github.com/cool-rdf/cool-rdf/issues + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Andreas Textor + mail@atextor.de + + + + + scm:git:https://github.com/cool-rdf/cool-rdf.git + scm:git:https://github.com/cool-rdf/cool-rdf.git + https://github.com/cool-rdf/cool-rdf/tree/main + + + + + UTF-8 + 25 + 25 + false + false + false + false + false + 4.38 + + + 3.0.1 + 0.0.16 + 3.2.3 + 4.8.184 + 1.20.0 + 2.21.0 + 1.15.0 + 23.0.1 + 33.5.0-jre + 4.5.14 + 5.6.0 + 2.20.1 + 10.0.2.0 + 1.5.23 + 1.18.42 + 1.0.3 + 2.6.5 + 5.5.1 + 4.7.7 + 2.0.17 + 0.11.0 + + + 3.27.6 + 6.0.1 + 1.9.3 + 5.21.0 + + + 3.2.0 + 3.6.1 + 0.9.0 + 3.6.3 + 1.7.3 + 2.0.1 + 9.0.2 + 2.1.1 + 0.8.14 + 3.2.0 + 3.5.0 + 3.14.1 + 3.1.4 + 3.5.4 + 3.2.8 + 3.1.4 + 3.12.0 + 3.5.0 + 3.3.1 + 3.4.0 + 3.6.1 + 3.4.0 + 1.5.1 + 3.5.4 + 0.11.3 + 2.20.1 + 3.1.0 + + + + cool-rdf-core + cool-rdf-diagram-owl + cool-rdf-infer + cool-rdf-formatter + cool-rdf-write + cool-rdf-cli + docs + + + + + + + cool.rdf + cool-rdf-core + ${project.version} + + + cool.rdf + cool-rdf-diagram-owl + ${project.version} + + + cool.rdf + cool-rdf-infer + ${project.version} + + + cool.rdf + cool-rdf-formatter + ${project.version} + + + cool.rdf + cool-rdf-write + ${project.version} + + + cool.rdf + cool-rdf-cli + ${project.version} + + + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + + + io.github.classgraph + classgraph + ${classgraph.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + com.google.guava + guava + ${guava.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + org.apache.jena + jena + ${jena.version} + pom + + + org.apache.jena + jena-arq + ${jena.version} + + + org.apache.jena + jena-core + ${jena.version} + + + org.apache.jena + apache-jena-libs + ${jena.version} + pom + + + org.jruby + jruby + ${jruby.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.github.galigator.openllet + openllet-jena + ${openllet.version} + + + net.sourceforge.owlapi + owlapi-distribution + ${owlapi.version} + + + info.picocli + picocli + ${picocli.version} + + + info.picocli + picocli-codegen + ${picocli.version} + + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + org.graalvm.nativeimage + svm + ${graalvm.version} + + + io.vavr + vavr + ${vavr.version} + + + + + org.assertj + assertj-core + ${assertj.version} + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + + + net.jqwik + jqwik + ${jqwik.version} + + + org.mockito + mockito-core + ${mockito.version} + + + + + + + + + org.mockito + mockito-core + compile + + + + + + + + org.asciidoctor + asciidoctor-maven-plugin + ${asciidoctor-maven-plugin.version} + + + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} + + + org.codehaus.mojo + build-helper-maven-plugin + ${build-helper-maven-plugin.version} + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + + de.saumya.mojo + gem-maven-plugin + ${gem-maven-plugin.version} + + + io.github.git-commit-id + git-commit-id-maven-plugin + ${git-commit-id-maven-plugin.version} + + + org.codehaus.gmaven + groovy-maven-plugin + ${groovy-maven-plugin.version} + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin.version} + + + com.diffplug.spotless + spotless-maven-plugin + ${spotless-maven-plugin.version} + + + org.codehaus.mojo + versions-maven-plugin + ${versions-maven-plugin.version} + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + default-prepare-agent + + prepare-agent + + + ${project.build.directory}/jacoco.exec + + + + create-report + + report + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + me.fabriciorby + maven-surefire-junit5-tree-reporter + ${maven-surefire-junit5-tree-reporter.version} + + + + ${maven.surefire.skip} + ${project.build.directory}/surefire-reports + + **/*Tests.java + **/*Test.java + + plain + + true + + + ASCII + true + true + true + true + false + true + true + false + + @{argLine} + -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar -Xshare:off + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + ${maven.failsafe.skip} + + + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + + true + clean verify + [Release] + true + @{prefix} reset version to snapshot + + @{prefix} release @{releaseLabel} + v@{project.version} + true + DEV-SNAPSHOT + + prepare-release,maven-central + + + + + org.codehaus.mojo + versions-maven-plugin + ${versions-maven-plugin.version} + + .*[\.-](?i)(alpha|beta|(rc[0-9]+)|(m\d+)).* + graalvm.version,jena.version + + + + + com.diffplug.spotless + spotless-maven-plugin + + + + + + .gitattributes + .gitignore + + + + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + + + ${eclipse-code-formatter.version} + ${maven.multiModuleProjectDirectory}/.development/coolrdf-eclipse-code-style.xml + + + ${maven.multiModuleProjectDirectory}/.development/coolrdf-eclipse.importorder + + + ${maven.multiModuleProjectDirectory}/.development/coolrdf-license-header.txt + + + + + + + + + + + + + prepare-release + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + + ossrh + + + + flatten + process-resources + + flatten + + + + clean-flatten + clean + + clean + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + attach-javadocs + + jar + + + + + ${maven.compiler.source} + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + attach-sources + + jar-no-fork + + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} + true + + central + true + all + false + + docs + + + + + + + + diff --git a/scripts/do-release.sh b/scripts/do-release.sh deleted file mode 100755 index 09a0407f..00000000 --- a/scripts/do-release.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -# -# Copyright 2021 Andreas Textor -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -set -ue - -if [ ! -e docs/antora.yml ]; then - echo "Run the script from the project root" - exit 1 -fi - -release_notes=docs/modules/ROOT/pages/release-notes.adoc -branchname=release -latest_version_from_release_notes=$(grep '^==' ${release_notes} | cut -d' ' -f3 | head -1) - -git tag -d snapshot -git fetch --tags -echo "Current tags:" -git --no-pager tag -echo -read -p "Version [${latest_version_from_release_notes}]: " version -version=${version:-${latest_version_from_release_notes}} - -grep "${version}" "${release_notes}" &>/dev/null -if [ $? != 0 ]; then - echo "Version ${version} not found in release notes, stopping" - exit 1 -fi - -echo Releasing version $version -tag="v${version}" -git branch -D $branchname 2>/dev/null || true -git checkout -b $branchname - -# Generate documentation images. The generated images that are not present in -# the normal source repository (because during a snapshot build they are -# generated) need to be actually present in the source tree in the tagged -# release commit, because this is what Antora will check out at a later time in -# order to build the respective module version. So generate them, remove the -# corresponding entry from .gitignore and commit them. -./gradlew generateImages -sed -i -e '/docs\/modules\/ROOT\/assets\/images/d' .gitignore -git add .gitignore -git add docs/modules/ROOT/assets/images/*.svg - -# Set versions -sed -i -e 's/version: snapshot/version: '$version'/g' docs/antora.yml -sed -i -e 's/page-component-version: snapshot/page-component-version: '$tag'/g' docs/antora.yml -sed -i -e 's/release-version: snapshot/release-version: '$version'/g' docs/antora.yml -sed -i -e 's/release-tag: snapshot/release-tag: v'$version'/g' docs/antora.yml -sed -i -e 's/snapshot/'$version'/g' gradle.properties -git add docs/antora.yml -git add gradle.properties - -git commit -m "Release version $version" -git tag ${tag} -echo Pushing branch -git push origin --delete ${branchname} 2>/dev/null || true -git push -u origin ${branchname} -echo Pushing tag ${tag} -git push origin ${tag} -git checkout main diff --git a/site.yml b/site.yml deleted file mode 100644 index 9aab3407..00000000 --- a/site.yml +++ /dev/null @@ -1,34 +0,0 @@ -site: - title: owl-cli Documentation - url: https://atextor.de/owl-cli/ - start_page: main::index.adoc -content: - sources: - - url: . - branches: HEAD - start_path: docs - - url: https://github.com/atextor/owl-cli.git - tags: [v*] - branches: ~ - start_path: docs -ui: - bundle: - # UI bundle is built from here: https://github.com/atextor/docs-antora-ui - url: ./docs/ui-bundle.zip - snapshot: true - supplemental_files: - - path: ui.yml - contents: | - static_files: [ .nojekyll ] - - path: .nojekyll -runtime: - cache_dir: ./.cache/antora -asciidoc: - attributes: - doctype: book - sectanchors: true - idprefix: '' - idseparator: '-' - stem: 'asciimath' - extensions: - - "@djencks/asciidoctor-mathjax" diff --git a/write/build.gradle b/write/build.gradle deleted file mode 100644 index bfd95d12..00000000 --- a/write/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.jena) - implementation(deps.jena_core) - implementation(deps.jena_arq) - implementation(deps.slf4j_api) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - diff --git a/write/src/main/java/de/atextor/owlcli/write/RdfWriter.java b/write/src/main/java/de/atextor/owlcli/write/RdfWriter.java deleted file mode 100644 index 2900a6ae..00000000 --- a/write/src/main/java/de/atextor/owlcli/write/RdfWriter.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.owlcli.write; - -import de.atextor.turtle.formatter.FormattingStyle; -import de.atextor.turtle.formatter.TurtleFormatter; -import io.vavr.control.Try; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; - -public class RdfWriter { - public static final Configuration DEFAULT_CONFIGURATION = Configuration.builder().build(); - - private static final Logger LOG = LoggerFactory.getLogger( RdfWriter.class ); - - public Try write( final URL inputUrl, final OutputStream output, final Configuration configuration ) { - try { - final HttpClient client = HttpClient.newBuilder() - .followRedirects( HttpClient.Redirect.ALWAYS ) - .build(); - final HttpRequest request = HttpRequest.newBuilder() - .uri( inputUrl.toURI() ) - .build(); - final HttpResponse response = client.send( request, HttpResponse.BodyHandlers.ofString() ); - if ( response.statusCode() == HttpURLConnection.HTTP_OK ) { - final ByteArrayInputStream inputStream = new ByteArrayInputStream( response.body().getBytes() ); - return write( inputStream, output, configuration ); - } - return Try.failure( new RuntimeException( "Got unexpected HTTP response: " + response.statusCode() ) ); - } catch ( final Exception exception ) { - LOG.debug( "Failure during reading from URL: {}", inputUrl ); - return Try.failure( exception ); - } - } - - public Try write( final InputStream input, final OutputStream output, final Configuration configuration ) { - final Model model = ModelFactory.createDefaultModel(); - - try { - model.read( input, configuration.formattingStyle.emptyRdfBase, - configurationFormatToJenaFormat( configuration.inputFormat ) ); - if ( configuration.outputFormat == Configuration.Format.TURTLE ) { - return writeTurtle( model, output, configuration.formattingStyle ); - } - model.write( output, configurationFormatToJenaFormat( configuration.outputFormat ) ); - } catch ( final Exception exception ) { - LOG.debug( "Failure during RDF I/O", exception ); - return Try.failure( exception ); - } - return Try.success( null ); - } - - public Try writeTurtle( final Model model, final OutputStream output, final FormattingStyle style ) { - final TurtleFormatter formatter = new TurtleFormatter( style ); - formatter.accept( model, output ); - return Try.success( null ); - } - - /** - * Builds a RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} - * - * @param format the format - * @return the format identifier for the Jena parser - */ - private String configurationFormatToJenaFormat( final Configuration.Format format ) { - return switch ( format ) { - case TURTLE -> "TURTLE"; - case RDFXML -> "RDF/XML"; - case NTRIPLE -> "N-TRIPLE"; - case N3 -> "N3"; - }; - } -}