mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge branch 'main' into fix-issue-10536_relation-field-requiredissue-main
This commit is contained in:
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
@@ -13,6 +13,7 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
time: "02:00"
|
||||||
# Allow up to 10 open PRs for dependencies
|
# Allow up to 10 open PRs for dependencies
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
# Group together some upgrades in a single PR
|
# Group together some upgrades in a single PR
|
||||||
|
9
.github/workflows/reusable-docker-build.yml
vendored
9
.github/workflows/reusable-docker-build.yml
vendored
@@ -86,17 +86,16 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
# Architectures / Platforms for which we will build Docker images
|
# Architectures / Platforms for which we will build Docker images
|
||||||
arch: [ 'linux/amd64', 'linux/arm64' ]
|
arch: [ 'linux/amd64', 'linux/arm64' ]
|
||||||
os: [ ubuntu-latest ]
|
|
||||||
isPr:
|
isPr:
|
||||||
- ${{ github.event_name == 'pull_request' }}
|
- ${{ github.event_name == 'pull_request' }}
|
||||||
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
|
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
|
||||||
# The below exclude therefore ensures we do NOT build ARM64 for PRs.
|
# The below exclude therefore ensures we do NOT build ARM64 for PRs.
|
||||||
exclude:
|
exclude:
|
||||||
- isPr: true
|
- isPr: true
|
||||||
os: ubuntu-latest
|
|
||||||
arch: linux/arm64
|
arch: linux/arm64
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
# If ARM64, then use the Ubuntu ARM64 runner. Otherwise, use the Ubuntu AMD64 runner
|
||||||
|
runs-on: ${{ matrix.arch == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# This step converts the slashes in the "arch" matrix values above into dashes & saves to env.ARCH_NAME
|
# This step converts the slashes in the "arch" matrix values above into dashes & saves to env.ARCH_NAME
|
||||||
@@ -122,10 +121,6 @@ jobs:
|
|||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# https://github.com/docker/setup-qemu-action
|
|
||||||
- name: Set up QEMU emulation to build for multiple architectures
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
|
|
||||||
# https://github.com/docker/setup-buildx-action
|
# https://github.com/docker/setup-buildx-action
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
@@ -21,67 +21,67 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
Apache Software License, Version 2.0:
|
Apache Software License, Version 2.0:
|
||||||
|
|
||||||
* Ant-Contrib Tasks (ant-contrib:ant-contrib:1.0b3 - http://ant-contrib.sourceforge.net)
|
* Ant-Contrib Tasks (ant-contrib:ant-contrib:1.0b3 - http://ant-contrib.sourceforge.net)
|
||||||
* AWS SDK for Java - Core (com.amazonaws:aws-java-sdk-core:1.12.261 - https://aws.amazon.com/sdkforjava)
|
* AWS SDK for Java - Core (com.amazonaws:aws-java-sdk-core:1.12.781 - https://aws.amazon.com/sdkforjava)
|
||||||
* AWS Java SDK for AWS KMS (com.amazonaws:aws-java-sdk-kms:1.12.261 - https://aws.amazon.com/sdkforjava)
|
* AWS Java SDK for AWS KMS (com.amazonaws:aws-java-sdk-kms:1.12.781 - https://aws.amazon.com/sdkforjava)
|
||||||
* AWS Java SDK for Amazon S3 (com.amazonaws:aws-java-sdk-s3:1.12.261 - https://aws.amazon.com/sdkforjava)
|
* AWS Java SDK for Amazon S3 (com.amazonaws:aws-java-sdk-s3:1.12.781 - https://aws.amazon.com/sdkforjava)
|
||||||
* JMES Path Query library (com.amazonaws:jmespath-java:1.12.261 - https://aws.amazon.com/sdkforjava)
|
* JMES Path Query library (com.amazonaws:jmespath-java:1.12.781 - https://aws.amazon.com/sdkforjava)
|
||||||
* Titanium JSON-LD 1.1 (JRE11) (com.apicatalog:titanium-json-ld:1.3.2 - https://github.com/filip26/titanium-json-ld)
|
* Titanium JSON-LD 1.1 (JRE11) (com.apicatalog:titanium-json-ld:1.3.2 - https://github.com/filip26/titanium-json-ld)
|
||||||
* HPPC Collections (com.carrotsearch:hppc:0.8.1 - http://labs.carrotsearch.com/hppc.html/hppc)
|
* HPPC Collections (com.carrotsearch:hppc:0.8.1 - http://labs.carrotsearch.com/hppc.html/hppc)
|
||||||
* com.drewnoakes:metadata-extractor (com.drewnoakes:metadata-extractor:2.19.0 - https://drewnoakes.com/code/exif/)
|
* com.drewnoakes:metadata-extractor (com.drewnoakes:metadata-extractor:2.19.0 - https://drewnoakes.com/code/exif/)
|
||||||
* parso (com.epam:parso:2.0.14 - https://github.com/epam/parso)
|
* parso (com.epam:parso:2.0.14 - https://github.com/epam/parso)
|
||||||
* ClassMate (com.fasterxml:classmate:1.6.0 - https://github.com/FasterXML/java-classmate)
|
* Internet Time Utility (com.ethlo.time:itu:1.7.0 - https://github.com/ethlo/itu)
|
||||||
* Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.16.0 - https://github.com/FasterXML/jackson)
|
* ClassMate (com.fasterxml:classmate:1.5.1 - https://github.com/FasterXML/java-classmate)
|
||||||
* Jackson-core (com.fasterxml.jackson.core:jackson-core:2.16.0 - https://github.com/FasterXML/jackson-core)
|
* Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.18.2 - https://github.com/FasterXML/jackson)
|
||||||
* jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.16.0 - https://github.com/FasterXML/jackson)
|
* Jackson-core (com.fasterxml.jackson.core:jackson-core:2.18.2 - https://github.com/FasterXML/jackson-core)
|
||||||
* Jackson dataformat: CBOR (com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.12.6 - http://github.com/FasterXML/jackson-dataformats-binary)
|
* jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.18.2 - https://github.com/FasterXML/jackson)
|
||||||
|
* Jackson dataformat: CBOR (com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.17.2 - https://github.com/FasterXML/jackson-dataformats-binary)
|
||||||
* Jackson dataformat: Smile (com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.15.2 - https://github.com/FasterXML/jackson-dataformats-binary)
|
* Jackson dataformat: Smile (com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.15.2 - https://github.com/FasterXML/jackson-dataformats-binary)
|
||||||
* Jackson-dataformat-TOML (com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.15.2 - https://github.com/FasterXML/jackson-dataformats-text)
|
* Jackson-dataformat-TOML (com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.15.2 - https://github.com/FasterXML/jackson-dataformats-text)
|
||||||
* Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.2 - https://github.com/FasterXML/jackson-dataformats-text)
|
* Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.2 - https://github.com/FasterXML/jackson-dataformats-text)
|
||||||
* Jackson datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.4 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8)
|
* Jackson datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8)
|
||||||
* Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.0 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
|
* Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
|
||||||
* Jackson Jakarta-RS: base (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.16.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base)
|
* Jackson Jakarta-RS: base (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.16.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base)
|
||||||
* Jackson Jakarta-RS: JSON (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.16.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider)
|
* Jackson Jakarta-RS: JSON (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.16.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider)
|
||||||
* Jackson module: Jakarta XML Bind Annotations (jakarta.xml.bind) (com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.16.2 - https://github.com/FasterXML/jackson-modules-base)
|
* Jackson module: Jakarta XML Bind Annotations (jakarta.xml.bind) (com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.16.2 - https://github.com/FasterXML/jackson-modules-base)
|
||||||
* Jackson-module-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.15.4 - https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names)
|
* Jackson-module-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.18.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names)
|
||||||
* Java UUID Generator (com.fasterxml.uuid:java-uuid-generator:4.0.1 - https://github.com/cowtowncoder/java-uuid-generator)
|
* Java UUID Generator (com.fasterxml.uuid:java-uuid-generator:4.1.0 - https://github.com/cowtowncoder/java-uuid-generator)
|
||||||
* Woodstox (com.fasterxml.woodstox:woodstox-core:6.5.1 - https://github.com/FasterXML/woodstox)
|
* Woodstox (com.fasterxml.woodstox:woodstox-core:6.5.1 - https://github.com/FasterXML/woodstox)
|
||||||
* zjsonpatch (com.flipkart.zjsonpatch:zjsonpatch:0.4.16 - https://github.com/flipkart-incubator/zjsonpatch/)
|
* zjsonpatch (com.flipkart.zjsonpatch:zjsonpatch:0.4.16 - https://github.com/flipkart-incubator/zjsonpatch/)
|
||||||
* Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.9.3 - https://github.com/ben-manes/caffeine)
|
* Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.9.3 - https://github.com/ben-manes/caffeine)
|
||||||
* Caffeine cache (com.github.ben-manes.caffeine:caffeine:3.1.6 - https://github.com/ben-manes/caffeine)
|
* Caffeine cache (com.github.ben-manes.caffeine:caffeine:3.1.8 - https://github.com/ben-manes/caffeine)
|
||||||
|
* JSON.simple (com.github.cliftonlabs:json-simple:3.0.2 - https://cliftonlabs.github.io/json-simple/)
|
||||||
* btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
|
* btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
|
||||||
* jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
|
* jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
|
||||||
* jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
|
* jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
|
||||||
|
* json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
|
||||||
* json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
|
* json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
|
||||||
* json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
|
* json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
|
||||||
* msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
|
* msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
|
||||||
* uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
|
* uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
|
||||||
* JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
|
* JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
|
||||||
* Google APIs Client Library for Java (com.google.api-client:google-api-client:1.23.0 - https://github.com/google/google-api-java-client/google-api-client)
|
|
||||||
* Google Analytics API v3-rev145-1.23.0 (com.google.apis:google-api-services-analytics:v3-rev145-1.23.0 - http://nexus.sonatype.org/oss-repository-hosting.html/google-api-services-analytics)
|
|
||||||
* FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/)
|
* FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/)
|
||||||
* Gson (com.google.code.gson:gson:2.10.1 - https://github.com/google/gson/gson)
|
* Gson (com.google.code.gson:gson:2.12.1 - https://github.com/google/gson)
|
||||||
* error-prone annotations (com.google.errorprone:error_prone_annotations:2.10.0 - https://errorprone.info/error_prone_annotations)
|
* error-prone annotations (com.google.errorprone:error_prone_annotations:2.36.0 - https://errorprone.info/error_prone_annotations)
|
||||||
* Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess)
|
* Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess)
|
||||||
* Guava: Google Core Libraries for Java (com.google.guava:guava:32.0.0-jre - https://github.com/google/guava)
|
* Guava: Google Core Libraries for Java (com.google.guava:guava:32.1.3-jre - https://github.com/google/guava)
|
||||||
* Guava: Google Core Libraries for Java (JDK5 Backport) (com.google.guava:guava-jdk5:17.0 - http://code.google.com/p/guava-libraries/guava-jdk5)
|
|
||||||
* Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
|
* Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
|
||||||
* Google HTTP Client Library for Java (com.google.http-client:google-http-client:1.23.0 - https://github.com/google/google-http-java-client/google-http-client)
|
* Google Guice - Core Library (com.google.inject:guice:7.0.0 - https://github.com/google/guice/guice)
|
||||||
* GSON extensions to the Google HTTP Client Library for Java. (com.google.http-client:google-http-client-gson:1.41.7 - https://github.com/googleapis/google-http-java-client/google-http-client-gson)
|
* Google Guice - Extensions - AssistedInject (com.google.inject.extensions:guice-assistedinject:7.0.0 - https://github.com/google/guice/extensions-parent/guice-assistedinject)
|
||||||
* Jackson 2 extensions to the Google HTTP Client Library for Java. (com.google.http-client:google-http-client-jackson2:1.23.0 - https://github.com/google/google-http-java-client/google-http-client-jackson2)
|
|
||||||
* J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
|
* J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
|
||||||
* J2ObjC Annotations (com.google.j2objc:j2objc-annotations:2.8 - https://github.com/google/j2objc/)
|
* J2ObjC Annotations (com.google.j2objc:j2objc-annotations:2.8 - https://github.com/google/j2objc/)
|
||||||
* Google OAuth Client Library for Java (com.google.oauth-client:google-oauth-client:1.33.3 - https://github.com/googleapis/google-oauth-java-client/google-oauth-client)
|
|
||||||
* ConcurrentLinkedHashMap (com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2 - http://code.google.com/p/concurrentlinkedhashmap)
|
* ConcurrentLinkedHashMap (com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2 - http://code.google.com/p/concurrentlinkedhashmap)
|
||||||
* libphonenumber (com.googlecode.libphonenumber:libphonenumber:8.11.1 - https://github.com/google/libphonenumber/)
|
* libphonenumber (com.googlecode.libphonenumber:libphonenumber:8.11.1 - https://github.com/google/libphonenumber/)
|
||||||
* Jackcess (com.healthmarketscience.jackcess:jackcess:4.0.5 - https://jackcess.sourceforge.io)
|
* Jackcess (com.healthmarketscience.jackcess:jackcess:4.0.8 - https://jackcess.sourceforge.io)
|
||||||
* Jackcess Encrypt (com.healthmarketscience.jackcess:jackcess-encrypt:4.0.2 - http://jackcessencrypt.sf.net)
|
* Jackcess Encrypt (com.healthmarketscience.jackcess:jackcess-encrypt:4.0.2 - http://jackcessencrypt.sf.net)
|
||||||
* json-path (com.jayway.jsonpath:json-path:2.9.0 - https://github.com/jayway/JsonPath)
|
* json-path (com.jayway.jsonpath:json-path:2.9.0 - https://github.com/jayway/JsonPath)
|
||||||
* json-path-assert (com.jayway.jsonpath:json-path-assert:2.9.0 - https://github.com/jayway/JsonPath)
|
* json-path-assert (com.jayway.jsonpath:json-path-assert:2.9.0 - https://github.com/jayway/JsonPath)
|
||||||
* Disruptor Framework (com.lmax:disruptor:3.4.2 - http://lmax-exchange.github.com/disruptor)
|
* Disruptor Framework (com.lmax:disruptor:3.4.2 - http://lmax-exchange.github.com/disruptor)
|
||||||
* MaxMind DB Reader (com.maxmind.db:maxmind-db:2.1.0 - http://dev.maxmind.com/)
|
* MaxMind DB Reader (com.maxmind.db:maxmind-db:2.1.0 - http://dev.maxmind.com/)
|
||||||
* MaxMind GeoIP2 API (com.maxmind.geoip2:geoip2:2.17.0 - https://dev.maxmind.com/geoip?lang=en)
|
* MaxMind GeoIP2 API (com.maxmind.geoip2:geoip2:2.17.0 - https://dev.maxmind.com/geoip?lang=en)
|
||||||
* Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:9.37.3 - https://bitbucket.org/connect2id/nimbus-jose-jwt)
|
* JsonSchemaValidator (com.networknt:json-schema-validator:1.0.76 - https://github.com/networknt/json-schema-validator)
|
||||||
* opencsv (com.opencsv:opencsv:5.9 - http://opencsv.sf.net)
|
* Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:9.28 - https://bitbucket.org/connect2id/nimbus-jose-jwt)
|
||||||
|
* Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:9.48 - https://bitbucket.org/connect2id/nimbus-jose-jwt)
|
||||||
|
* opencsv (com.opencsv:opencsv:5.10 - http://opencsv.sf.net)
|
||||||
* java-libpst (com.pff:java-libpst:0.9.3 - https://github.com/rjohnsondev/java-libpst)
|
* java-libpst (com.pff:java-libpst:0.9.3 - https://github.com/rjohnsondev/java-libpst)
|
||||||
* rome (com.rometools:rome:1.19.0 - http://rometools.com/rome)
|
* rome (com.rometools:rome:1.19.0 - http://rometools.com/rome)
|
||||||
* rome-modules (com.rometools:rome-modules:1.19.0 - http://rometools.com/rome-modules)
|
* rome-modules (com.rometools:rome-modules:1.19.0 - http://rometools.com/rome-modules)
|
||||||
@@ -98,102 +98,111 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* scala-logging (com.typesafe.scala-logging:scala-logging_2.13:3.9.2 - https://github.com/lightbend/scala-logging)
|
* scala-logging (com.typesafe.scala-logging:scala-logging_2.13:3.9.2 - https://github.com/lightbend/scala-logging)
|
||||||
* JSON library from Android SDK (com.vaadin.external.google:android-json:0.0.20131108.vaadin1 - http://developer.android.com/sdk)
|
* JSON library from Android SDK (com.vaadin.external.google:android-json:0.0.20131108.vaadin1 - http://developer.android.com/sdk)
|
||||||
* SparseBitSet (com.zaxxer:SparseBitSet:1.3 - https://github.com/brettwooldridge/SparseBitSet)
|
* SparseBitSet (com.zaxxer:SparseBitSet:1.3 - https://github.com/brettwooldridge/SparseBitSet)
|
||||||
* Apache Commons BeanUtils (commons-beanutils:commons-beanutils:1.9.4 - https://commons.apache.org/proper/commons-beanutils/)
|
* Apache Commons BeanUtils (commons-beanutils:commons-beanutils:1.10.1 - https://commons.apache.org/proper/commons-beanutils)
|
||||||
* Apache Commons CLI (commons-cli:commons-cli:1.6.0 - https://commons.apache.org/proper/commons-cli/)
|
* Apache Commons CLI (commons-cli:commons-cli:1.9.0 - https://commons.apache.org/proper/commons-cli/)
|
||||||
* Apache Commons Codec (commons-codec:commons-codec:1.16.0 - https://commons.apache.org/proper/commons-codec/)
|
* Apache Commons Codec (commons-codec:commons-codec:1.18.0 - https://commons.apache.org/proper/commons-codec/)
|
||||||
* Apache Commons Collections (commons-collections:commons-collections:3.2.2 - http://commons.apache.org/collections/)
|
* Apache Commons Collections (commons-collections:commons-collections:3.2.2 - http://commons.apache.org/collections/)
|
||||||
* Commons Digester (commons-digester:commons-digester:2.1 - http://commons.apache.org/digester/)
|
* Commons Digester (commons-digester:commons-digester:2.1 - http://commons.apache.org/digester/)
|
||||||
* Apache Commons IO (commons-io:commons-io:2.15.1 - https://commons.apache.org/proper/commons-io/)
|
* Apache Commons IO (commons-io:commons-io:2.18.0 - https://commons.apache.org/proper/commons-io/)
|
||||||
* Commons Lang (commons-lang:commons-lang:2.6 - http://commons.apache.org/lang/)
|
* Commons Lang (commons-lang:commons-lang:2.6 - http://commons.apache.org/lang/)
|
||||||
* Apache Commons Logging (commons-logging:commons-logging:1.3.0 - https://commons.apache.org/proper/commons-logging/)
|
* Apache Commons Logging (commons-logging:commons-logging:1.3.5 - https://commons.apache.org/proper/commons-logging/)
|
||||||
* Apache Commons Validator (commons-validator:commons-validator:1.7 - http://commons.apache.org/proper/commons-validator/)
|
* Apache Commons Validator (commons-validator:commons-validator:1.9.0 - http://commons.apache.org/proper/commons-validator/)
|
||||||
* GeoJson POJOs for Jackson (de.grundid.opendatalab:geojson-jackson:1.14 - https://github.com/opendatalab-de/geojson-jackson)
|
* GeoJson POJOs for Jackson (de.grundid.opendatalab:geojson-jackson:1.14 - https://github.com/opendatalab-de/geojson-jackson)
|
||||||
* broker-client (eu.openaire:broker-client:1.1.2 - http://api.openaire.eu/broker/broker-client)
|
* broker-client (eu.openaire:broker-client:1.1.2 - http://api.openaire.eu/broker/broker-client)
|
||||||
* OpenAIRE Funders Model (eu.openaire:funders-model:2.0.0 - https://api.openaire.eu)
|
* OpenAIRE Funders Model (eu.openaire:funders-model:2.0.0 - https://api.openaire.eu)
|
||||||
* Metrics Core (io.dropwizard.metrics:metrics-core:4.1.5 - https://metrics.dropwizard.io/metrics-core)
|
* Metrics Core (io.dropwizard.metrics:metrics-core:4.1.5 - https://metrics.dropwizard.io/metrics-core)
|
||||||
|
* Metrics Core (io.dropwizard.metrics:metrics-core:4.2.25 - https://metrics.dropwizard.io/metrics-core)
|
||||||
* Graphite Integration for Metrics (io.dropwizard.metrics:metrics-graphite:4.1.5 - https://metrics.dropwizard.io/metrics-graphite)
|
* Graphite Integration for Metrics (io.dropwizard.metrics:metrics-graphite:4.1.5 - https://metrics.dropwizard.io/metrics-graphite)
|
||||||
* Metrics Integration for Jetty 9.3 and higher (io.dropwizard.metrics:metrics-jetty9:4.1.5 - https://metrics.dropwizard.io/metrics-jetty9)
|
* Metrics Integration for Jetty 9.3 and higher (io.dropwizard.metrics:metrics-jetty9:4.1.5 - https://metrics.dropwizard.io/metrics-jetty9)
|
||||||
* Metrics Integration with JMX (io.dropwizard.metrics:metrics-jmx:4.1.5 - https://metrics.dropwizard.io/metrics-jmx)
|
* Metrics Integration with JMX (io.dropwizard.metrics:metrics-jmx:4.1.5 - https://metrics.dropwizard.io/metrics-jmx)
|
||||||
* JVM Integration for Metrics (io.dropwizard.metrics:metrics-jvm:4.1.5 - https://metrics.dropwizard.io/metrics-jvm)
|
* JVM Integration for Metrics (io.dropwizard.metrics:metrics-jvm:4.1.5 - https://metrics.dropwizard.io/metrics-jvm)
|
||||||
* SWORD v2 Common Server Library (forked) (io.gdcc:sword2-server:2.0.0 - https://github.com/gdcc/sword2-server)
|
* SWORD v2 Common Server Library (forked) (io.gdcc:sword2-server:2.0.0 - https://github.com/gdcc/sword2-server)
|
||||||
* micrometer-commons (io.micrometer:micrometer-commons:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
* micrometer-commons (io.micrometer:micrometer-commons:1.14.5 - https://github.com/micrometer-metrics/micrometer)
|
||||||
* micrometer-core (io.micrometer:micrometer-core:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
* micrometer-core (io.micrometer:micrometer-core:1.14.4 - https://github.com/micrometer-metrics/micrometer)
|
||||||
* micrometer-jakarta9 (io.micrometer:micrometer-jakarta9:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
* micrometer-jakarta9 (io.micrometer:micrometer-jakarta9:1.14.4 - https://github.com/micrometer-metrics/micrometer)
|
||||||
* micrometer-observation (io.micrometer:micrometer-observation:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
* micrometer-observation (io.micrometer:micrometer-observation:1.14.5 - https://github.com/micrometer-metrics/micrometer)
|
||||||
* Netty/Buffer (io.netty:netty-buffer:4.1.106.Final - https://netty.io/netty-buffer/)
|
|
||||||
* Netty/Buffer (io.netty:netty-buffer:4.1.99.Final - https://netty.io/netty-buffer/)
|
* Netty/Buffer (io.netty:netty-buffer:4.1.99.Final - https://netty.io/netty-buffer/)
|
||||||
* Netty/Codec (io.netty:netty-codec:4.1.106.Final - https://netty.io/netty-codec/)
|
|
||||||
* Netty/Codec (io.netty:netty-codec:4.1.99.Final - https://netty.io/netty-codec/)
|
* Netty/Codec (io.netty:netty-codec:4.1.99.Final - https://netty.io/netty-codec/)
|
||||||
* Netty/Codec/HTTP (io.netty:netty-codec-http:4.1.53.Final - https://netty.io/netty-codec-http/)
|
* Netty/Codec/HTTP (io.netty:netty-codec-http:4.1.86.Final - https://netty.io/netty-codec-http/)
|
||||||
* Netty/Codec/Socks (io.netty:netty-codec-socks:4.1.53.Final - https://netty.io/netty-codec-socks/)
|
* Netty/Codec/HTTP2 (io.netty:netty-codec-http2:4.1.86.Final - https://netty.io/netty-codec-http2/)
|
||||||
* Netty/Common (io.netty:netty-common:4.1.106.Final - https://netty.io/netty-common/)
|
* Netty/Codec/Socks (io.netty:netty-codec-socks:4.1.86.Final - https://netty.io/netty-codec-socks/)
|
||||||
* Netty/Common (io.netty:netty-common:4.1.99.Final - https://netty.io/netty-common/)
|
* Netty/Common (io.netty:netty-common:4.1.99.Final - https://netty.io/netty-common/)
|
||||||
* Netty/Handler (io.netty:netty-handler:4.1.106.Final - https://netty.io/netty-handler/)
|
|
||||||
* Netty/Handler (io.netty:netty-handler:4.1.99.Final - https://netty.io/netty-handler/)
|
* Netty/Handler (io.netty:netty-handler:4.1.99.Final - https://netty.io/netty-handler/)
|
||||||
* Netty/Handler/Proxy (io.netty:netty-handler-proxy:4.1.53.Final - https://netty.io/netty-handler-proxy/)
|
* Netty/Handler/Proxy (io.netty:netty-handler-proxy:4.1.86.Final - https://netty.io/netty-handler-proxy/)
|
||||||
* Netty/Resolver (io.netty:netty-resolver:4.1.99.Final - https://netty.io/netty-resolver/)
|
* Netty/Resolver (io.netty:netty-resolver:4.1.99.Final - https://netty.io/netty-resolver/)
|
||||||
* Netty/Transport (io.netty:netty-transport:4.1.106.Final - https://netty.io/netty-transport/)
|
* Netty/TomcatNative [BoringSSL - Static] (io.netty:netty-tcnative-boringssl-static:2.0.56.Final - https://github.com/netty/netty-tcnative/netty-tcnative-boringssl-static/)
|
||||||
|
* Netty/TomcatNative [OpenSSL - Classes] (io.netty:netty-tcnative-classes:2.0.56.Final - https://github.com/netty/netty-tcnative/netty-tcnative-classes/)
|
||||||
* Netty/Transport (io.netty:netty-transport:4.1.99.Final - https://netty.io/netty-transport/)
|
* Netty/Transport (io.netty:netty-transport:4.1.99.Final - https://netty.io/netty-transport/)
|
||||||
|
* Netty/Transport/Classes/Epoll (io.netty:netty-transport-classes-epoll:4.1.99.Final - https://netty.io/netty-transport-classes-epoll/)
|
||||||
* Netty/Transport/Native/Epoll (io.netty:netty-transport-native-epoll:4.1.99.Final - https://netty.io/netty-transport-native-epoll/)
|
* Netty/Transport/Native/Epoll (io.netty:netty-transport-native-epoll:4.1.99.Final - https://netty.io/netty-transport-native-epoll/)
|
||||||
* Netty/Transport/Native/Unix/Common (io.netty:netty-transport-native-unix-common:4.1.106.Final - https://netty.io/netty-transport-native-unix-common/)
|
|
||||||
* Netty/Transport/Native/Unix/Common (io.netty:netty-transport-native-unix-common:4.1.99.Final - https://netty.io/netty-transport-native-unix-common/)
|
* Netty/Transport/Native/Unix/Common (io.netty:netty-transport-native-unix-common:4.1.99.Final - https://netty.io/netty-transport-native-unix-common/)
|
||||||
* OpenTracing API (io.opentracing:opentracing-api:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-api)
|
* OpenTracing API (io.opentracing:opentracing-api:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-api)
|
||||||
* OpenTracing-noop (io.opentracing:opentracing-noop:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-noop)
|
* OpenTracing-noop (io.opentracing:opentracing-noop:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-noop)
|
||||||
* OpenTracing-util (io.opentracing:opentracing-util:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-util)
|
* OpenTracing-util (io.opentracing:opentracing-util:0.33.0 - https://github.com/opentracing/opentracing-java/opentracing-util)
|
||||||
|
* Prometheus Java Simpleclient (io.prometheus:simpleclient:0.16.0 - http://github.com/prometheus/client_java/simpleclient)
|
||||||
|
* Prometheus Java Simpleclient Common (io.prometheus:simpleclient_common:0.16.0 - http://github.com/prometheus/client_java/simpleclient_common)
|
||||||
|
* Prometheus Java Simpleclient Httpserver (io.prometheus:simpleclient_httpserver:0.16.0 - http://github.com/prometheus/client_java/simpleclient_httpserver)
|
||||||
|
* Prometheus Java Span Context Supplier - Common (io.prometheus:simpleclient_tracer_common:0.16.0 - http://github.com/prometheus/client_java/simpleclient_tracer/simpleclient_tracer_common)
|
||||||
|
* Prometheus Java Span Context Supplier - OpenTelemetry (io.prometheus:simpleclient_tracer_otel:0.16.0 - http://github.com/prometheus/client_java/simpleclient_tracer/simpleclient_tracer_otel)
|
||||||
|
* Prometheus Java Span Context Supplier - OpenTelemetry Agent (io.prometheus:simpleclient_tracer_otel_agent:0.16.0 - http://github.com/prometheus/client_java/simpleclient_tracer/simpleclient_tracer_otel_agent)
|
||||||
* Google S2 geometry library (io.sgr:s2-geometry-library-java:1.0.0 - https://github.com/sgr-io/s2-geometry-library-java)
|
* Google S2 geometry library (io.sgr:s2-geometry-library-java:1.0.0 - https://github.com/sgr-io/s2-geometry-library-java)
|
||||||
* Jandex: Core (io.smallrye:jandex:3.1.2 - https://smallrye.io)
|
* Jandex: Core (io.smallrye:jandex:3.1.2 - https://smallrye.io)
|
||||||
* swagger-annotations (io.swagger:swagger-annotations:1.6.2 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations)
|
* swagger-annotations (io.swagger:swagger-annotations:1.6.9 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations)
|
||||||
* swagger-compat-spec-parser (io.swagger:swagger-compat-spec-parser:1.0.52 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-compat-spec-parser)
|
* swagger-compat-spec-parser (io.swagger:swagger-compat-spec-parser:1.0.64 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-compat-spec-parser)
|
||||||
* swagger-core (io.swagger:swagger-core:1.6.2 - https://github.com/swagger-api/swagger-core/modules/swagger-core)
|
* swagger-core (io.swagger:swagger-core:1.6.9 - https://github.com/swagger-api/swagger-core/modules/swagger-core)
|
||||||
* swagger-models (io.swagger:swagger-models:1.6.2 - https://github.com/swagger-api/swagger-core/modules/swagger-models)
|
* swagger-models (io.swagger:swagger-models:1.6.9 - https://github.com/swagger-api/swagger-core/modules/swagger-models)
|
||||||
* swagger-parser (io.swagger:swagger-parser:1.0.52 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser)
|
* swagger-parser (io.swagger:swagger-parser:1.0.64 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser)
|
||||||
* swagger-annotations (io.swagger.core.v3:swagger-annotations:2.1.5 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations)
|
* swagger-annotations (io.swagger.core.v3:swagger-annotations:2.2.8 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations)
|
||||||
* swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations-jakarta)
|
* swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations-jakarta)
|
||||||
* swagger-core (io.swagger.core.v3:swagger-core:2.1.5 - https://github.com/swagger-api/swagger-core/modules/swagger-core)
|
* swagger-core (io.swagger.core.v3:swagger-core:2.2.8 - https://github.com/swagger-api/swagger-core/modules/swagger-core)
|
||||||
* swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-core-jakarta)
|
* swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-core-jakarta)
|
||||||
* swagger-integration-jakarta (io.swagger.core.v3:swagger-integration-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-integration-jakarta)
|
* swagger-integration-jakarta (io.swagger.core.v3:swagger-integration-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-integration-jakarta)
|
||||||
* swagger-jaxrs2-jakarta (io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-jakarta)
|
* swagger-jaxrs2-jakarta (io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-jakarta)
|
||||||
* swagger-models (io.swagger.core.v3:swagger-models:2.1.5 - https://github.com/swagger-api/swagger-core/modules/swagger-models)
|
* swagger-models (io.swagger.core.v3:swagger-models:2.2.8 - https://github.com/swagger-api/swagger-core/modules/swagger-models)
|
||||||
* swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-models-jakarta)
|
* swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.21 - https://github.com/swagger-api/swagger-core/modules/swagger-models-jakarta)
|
||||||
* swagger-parser (io.swagger.parser.v3:swagger-parser:2.0.23 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser)
|
* swagger-parser (io.swagger.parser.v3:swagger-parser:2.1.10 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser)
|
||||||
* swagger-parser (io.swagger.parser.v3:swagger-parser-core:2.0.23 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-core)
|
* swagger-parser (io.swagger.parser.v3:swagger-parser-core:2.1.10 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-core)
|
||||||
* swagger-parser-v2-converter (io.swagger.parser.v3:swagger-parser-v2-converter:2.0.23 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-v2-converter)
|
* swagger-parser-v2-converter (io.swagger.parser.v3:swagger-parser-v2-converter:2.1.10 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-v2-converter)
|
||||||
* swagger-parser-v3 (io.swagger.parser.v3:swagger-parser-v3:2.0.23 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-v3)
|
* swagger-parser-v3 (io.swagger.parser.v3:swagger-parser-v3:2.1.10 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser-v3)
|
||||||
* Jakarta Dependency Injection (jakarta.inject:jakarta.inject-api:2.0.1 - https://github.com/eclipse-ee4j/injection-api)
|
* Jakarta Dependency Injection (jakarta.inject:jakarta.inject-api:2.0.1 - https://github.com/eclipse-ee4j/injection-api)
|
||||||
* Jakarta Bean Validation API (jakarta.validation:jakarta.validation-api:3.0.2 - https://beanvalidation.org)
|
* Jakarta Bean Validation API (jakarta.validation:jakarta.validation-api:3.0.2 - https://beanvalidation.org)
|
||||||
* JSR107 API and SPI (javax.cache:cache-api:1.1.1 - https://github.com/jsr107/jsr107spec)
|
* JSR107 API and SPI (javax.cache:cache-api:1.1.1 - https://github.com/jsr107/jsr107spec)
|
||||||
* javax.inject (javax.inject:javax.inject:1 - http://code.google.com/p/atinject/)
|
|
||||||
* Bean Validation API (javax.validation:validation-api:1.1.0.Final - http://beanvalidation.org)
|
|
||||||
* jdbm (jdbm:jdbm:1.0 - no url defined)
|
* jdbm (jdbm:jdbm:1.0 - no url defined)
|
||||||
* Joda-Time (joda-time:joda-time:2.12.5 - https://www.joda.org/joda-time/)
|
* Joda-Time (joda-time:joda-time:2.12.7 - https://www.joda.org/joda-time/)
|
||||||
* Byte Buddy (without dependencies) (net.bytebuddy:byte-buddy:1.11.13 - https://bytebuddy.net/byte-buddy)
|
* Byte Buddy (without dependencies) (net.bytebuddy:byte-buddy:1.11.13 - https://bytebuddy.net/byte-buddy)
|
||||||
|
* Byte Buddy (without dependencies) (net.bytebuddy:byte-buddy:1.14.11 - https://bytebuddy.net/byte-buddy)
|
||||||
* Byte Buddy agent (net.bytebuddy:byte-buddy-agent:1.11.13 - https://bytebuddy.net/byte-buddy-agent)
|
* Byte Buddy agent (net.bytebuddy:byte-buddy-agent:1.11.13 - https://bytebuddy.net/byte-buddy-agent)
|
||||||
* eigenbase-properties (net.hydromatic:eigenbase-properties:1.1.5 - http://github.com/julianhyde/eigenbase-properties)
|
* eigenbase-properties (net.hydromatic:eigenbase-properties:1.1.5 - http://github.com/julianhyde/eigenbase-properties)
|
||||||
* json-unit-core (net.javacrumbs.json-unit:json-unit-core:2.19.0 - https://github.com/lukas-krecan/JsonUnit/json-unit-core)
|
* json-unit-core (net.javacrumbs.json-unit:json-unit-core:2.36.0 - https://github.com/lukas-krecan/JsonUnit/json-unit-core)
|
||||||
* "Java Concurrency in Practice" book annotations (net.jcip:jcip-annotations:1.0 - http://jcip.net/)
|
* "Java Concurrency in Practice" book annotations (net.jcip:jcip-annotations:1.0 - http://jcip.net/)
|
||||||
* ASM based accessors helper used by json-smart (net.minidev:accessors-smart:2.5.0 - https://urielch.github.io/)
|
* ASM based accessors helper used by json-smart (net.minidev:accessors-smart:2.5.0 - https://urielch.github.io/)
|
||||||
|
* ASM based accessors helper used by json-smart (net.minidev:accessors-smart:2.5.2 - https://urielch.github.io/)
|
||||||
* JSON Small and Fast Parser (net.minidev:json-smart:2.5.0 - https://urielch.github.io/)
|
* JSON Small and Fast Parser (net.minidev:json-smart:2.5.0 - https://urielch.github.io/)
|
||||||
|
* JSON Small and Fast Parser (net.minidev:json-smart:2.5.2 - https://urielch.github.io/)
|
||||||
|
* java-support (net.shibboleth.utilities:java-support:8.4.2 - http://shibboleth.net/java-support/)
|
||||||
|
* OGNL - Object Graph Navigation Library (ognl:ognl:3.3.4 - https://github.com/jkuhnert/ognl/)
|
||||||
* Abdera Core (org.apache.abdera:abdera-core:1.1.3 - http://abdera.apache.org/abdera-core)
|
* Abdera Core (org.apache.abdera:abdera-core:1.1.3 - http://abdera.apache.org/abdera-core)
|
||||||
* I18N Libraries (org.apache.abdera:abdera-i18n:1.1.3 - http://abdera.apache.org)
|
* I18N Libraries (org.apache.abdera:abdera-i18n:1.1.3 - http://abdera.apache.org)
|
||||||
* Abdera Parser (org.apache.abdera:abdera-parser:1.1.3 - http://abdera.apache.org/abdera-parser)
|
* Abdera Parser (org.apache.abdera:abdera-parser:1.1.3 - http://abdera.apache.org/abdera-parser)
|
||||||
* Apache Ant Core (org.apache.ant:ant:1.10.14 - https://ant.apache.org/)
|
* Apache Ant Core (org.apache.ant:ant:1.10.15 - https://ant.apache.org/)
|
||||||
* Apache Ant Launcher (org.apache.ant:ant-launcher:1.10.14 - https://ant.apache.org/)
|
* Apache Ant Launcher (org.apache.ant:ant-launcher:1.10.15 - https://ant.apache.org/)
|
||||||
* Apache Commons BCEL (org.apache.bcel:bcel:6.7.0 - https://commons.apache.org/proper/commons-bcel)
|
* Apache Commons BCEL (org.apache.bcel:bcel:6.10.0 - https://commons.apache.org/proper/commons-bcel)
|
||||||
* Calcite Core (org.apache.calcite:calcite-core:1.35.0 - https://calcite.apache.org)
|
* Calcite Core (org.apache.calcite:calcite-core:1.35.0 - https://calcite.apache.org)
|
||||||
* Calcite Linq4j (org.apache.calcite:calcite-linq4j:1.35.0 - https://calcite.apache.org)
|
* Calcite Linq4j (org.apache.calcite:calcite-linq4j:1.35.0 - https://calcite.apache.org)
|
||||||
* Apache Calcite Avatica (org.apache.calcite.avatica:avatica-core:1.23.0 - https://calcite.apache.org/avatica)
|
* Apache Calcite Avatica (org.apache.calcite.avatica:avatica-core:1.23.0 - https://calcite.apache.org/avatica)
|
||||||
* Apache Calcite Avatica Metrics (org.apache.calcite.avatica:avatica-metrics:1.23.0 - https://calcite.apache.org/avatica)
|
* Apache Calcite Avatica Metrics (org.apache.calcite.avatica:avatica-metrics:1.23.0 - https://calcite.apache.org/avatica)
|
||||||
* Apache Commons Collections (org.apache.commons:commons-collections4:4.4 - https://commons.apache.org/proper/commons-collections/)
|
* Apache Commons Collections (org.apache.commons:commons-collections4:4.4 - https://commons.apache.org/proper/commons-collections/)
|
||||||
* Apache Commons Compress (org.apache.commons:commons-compress:1.26.0 - https://commons.apache.org/proper/commons-compress/)
|
* Apache Commons Compress (org.apache.commons:commons-compress:1.27.1 - https://commons.apache.org/proper/commons-compress/)
|
||||||
* Apache Commons Configuration (org.apache.commons:commons-configuration2:2.10.1 - https://commons.apache.org/proper/commons-configuration/)
|
* Apache Commons Configuration (org.apache.commons:commons-configuration2:2.11.0 - https://commons.apache.org/proper/commons-configuration/)
|
||||||
* Apache Commons CSV (org.apache.commons:commons-csv:1.10.0 - https://commons.apache.org/proper/commons-csv/)
|
* Apache Commons CSV (org.apache.commons:commons-csv:1.13.0 - https://commons.apache.org/proper/commons-csv/)
|
||||||
* Apache Commons DBCP (org.apache.commons:commons-dbcp2:2.11.0 - https://commons.apache.org/dbcp/)
|
* Apache Commons DBCP (org.apache.commons:commons-dbcp2:2.13.0 - https://commons.apache.org/proper/commons-dbcp/)
|
||||||
|
* Apache Commons Digester (org.apache.commons:commons-digester3:3.2 - http://commons.apache.org/digester/)
|
||||||
* Apache Commons Exec (org.apache.commons:commons-exec:1.3 - http://commons.apache.org/proper/commons-exec/)
|
* Apache Commons Exec (org.apache.commons:commons-exec:1.3 - http://commons.apache.org/proper/commons-exec/)
|
||||||
* Apache Commons Exec (org.apache.commons:commons-exec:1.4.0 - https://commons.apache.org/proper/commons-exec/)
|
* Apache Commons Exec (org.apache.commons:commons-exec:1.4.0 - https://commons.apache.org/proper/commons-exec/)
|
||||||
* Apache Commons Lang (org.apache.commons:commons-lang3:3.14.0 - https://commons.apache.org/proper/commons-lang/)
|
* Apache Commons Lang (org.apache.commons:commons-lang3:3.17.0 - https://commons.apache.org/proper/commons-lang/)
|
||||||
* Apache Commons Math (org.apache.commons:commons-math3:3.6.1 - http://commons.apache.org/proper/commons-math/)
|
* Apache Commons Math (org.apache.commons:commons-math3:3.6.1 - http://commons.apache.org/proper/commons-math/)
|
||||||
* Apache Commons Pool (org.apache.commons:commons-pool2:2.12.0 - https://commons.apache.org/proper/commons-pool/)
|
* Apache Commons Pool (org.apache.commons:commons-pool2:2.12.1 - https://commons.apache.org/proper/commons-pool/)
|
||||||
* Apache Commons Text (org.apache.commons:commons-text:1.10.0 - https://commons.apache.org/proper/commons-text)
|
* Apache Commons Text (org.apache.commons:commons-text:1.13.0 - https://commons.apache.org/proper/commons-text)
|
||||||
* Curator Client (org.apache.curator:curator-client:2.13.0 - http://curator.apache.org/curator-client)
|
* Curator Client (org.apache.curator:curator-client:2.13.0 - http://curator.apache.org/curator-client)
|
||||||
* Curator Framework (org.apache.curator:curator-framework:2.13.0 - http://curator.apache.org/curator-framework)
|
* Curator Framework (org.apache.curator:curator-framework:2.13.0 - http://curator.apache.org/curator-framework)
|
||||||
* Curator Recipes (org.apache.curator:curator-recipes:2.13.0 - http://curator.apache.org/curator-recipes)
|
* Curator Recipes (org.apache.curator:curator-recipes:2.13.0 - http://curator.apache.org/curator-recipes)
|
||||||
@@ -207,120 +216,130 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.16 - http://hc.apache.org/httpcomponents-core-ga)
|
* Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.16 - http://hc.apache.org/httpcomponents-core-ga)
|
||||||
* Apache HttpClient Mime (org.apache.httpcomponents:httpmime:4.5.14 - http://hc.apache.org/httpcomponents-client-ga)
|
* Apache HttpClient Mime (org.apache.httpcomponents:httpmime:4.5.14 - http://hc.apache.org/httpcomponents-client-ga)
|
||||||
* Apache HttpClient (org.apache.httpcomponents.client5:httpclient5:5.1.3 - https://hc.apache.org/httpcomponents-client-5.0.x/5.1.3/httpclient5/)
|
* Apache HttpClient (org.apache.httpcomponents.client5:httpclient5:5.1.3 - https://hc.apache.org/httpcomponents-client-5.0.x/5.1.3/httpclient5/)
|
||||||
* Apache HttpClient (org.apache.httpcomponents.client5:httpclient5:5.3.1 - https://hc.apache.org/httpcomponents-client-5.0.x/5.3.1/httpclient5/)
|
* Apache HttpClient (org.apache.httpcomponents.client5:httpclient5:5.4.2 - https://hc.apache.org/httpcomponents-client-5.4.x/5.4.2/httpclient5/)
|
||||||
* Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.1.3 - https://hc.apache.org/httpcomponents-core-5.1.x/5.1.3/httpcore5/)
|
* Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.1.3 - https://hc.apache.org/httpcomponents-core-5.1.x/5.1.3/httpcore5/)
|
||||||
* Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.2.4 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2.4/httpcore5/)
|
* Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.3.3 - https://hc.apache.org/httpcomponents-core-5.3.x/5.3.3/httpcore5/)
|
||||||
* Apache HttpComponents Core HTTP/2 (org.apache.httpcomponents.core5:httpcore5-h2:5.1.3 - https://hc.apache.org/httpcomponents-core-5.1.x/5.1.3/httpcore5-h2/)
|
* Apache HttpComponents Core HTTP/2 (org.apache.httpcomponents.core5:httpcore5-h2:5.1.3 - https://hc.apache.org/httpcomponents-core-5.1.x/5.1.3/httpcore5-h2/)
|
||||||
* Apache HttpComponents Core HTTP/2 (org.apache.httpcomponents.core5:httpcore5-h2:5.2.4 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2.4/httpcore5-h2/)
|
* Apache HttpComponents Core HTTP/2 (org.apache.httpcomponents.core5:httpcore5-h2:5.3.3 - https://hc.apache.org/httpcomponents-core-5.3.x/5.3.3/httpcore5-h2/)
|
||||||
* Apache James :: Mime4j :: Core (org.apache.james:apache-mime4j-core:0.8.10 - http://james.apache.org/mime4j/apache-mime4j-core)
|
* Apache James :: Mime4j :: Core (org.apache.james:apache-mime4j-core:0.8.12 - http://james.apache.org/mime4j/apache-mime4j-core)
|
||||||
* Apache James :: Mime4j :: DOM (org.apache.james:apache-mime4j-dom:0.8.11 - http://james.apache.org/mime4j/apache-mime4j-dom)
|
* Apache James :: Mime4j :: DOM (org.apache.james:apache-mime4j-dom:0.8.12 - http://james.apache.org/mime4j/apache-mime4j-dom)
|
||||||
* Apache Jena - Libraries POM (org.apache.jena:apache-jena-libs:4.9.0 - https://jena.apache.org/apache-jena-libs/)
|
* jclouds blobstore core (org.apache.jclouds:jclouds-blobstore:2.6.0 - https://jclouds.apache.org/jclouds-blobstore/)
|
||||||
* Apache Jena - ARQ (org.apache.jena:jena-arq:4.9.0 - https://jena.apache.org/jena-arq/)
|
* jclouds Components Core (org.apache.jclouds:jclouds-core:2.6.0 - https://jclouds.apache.org/jclouds-core/)
|
||||||
* Apache Jena - Base (org.apache.jena:jena-base:4.9.0 - https://jena.apache.org/jena-base/)
|
* jclouds filesystem core (org.apache.jclouds.api:filesystem:2.6.0 - https://jclouds.apache.org/filesystem/)
|
||||||
* Apache Jena - Core (org.apache.jena:jena-core:4.9.0 - https://jena.apache.org/jena-core/)
|
* jclouds s3 api (org.apache.jclouds.api:s3:2.6.0 - https://jclouds.apache.org/s3/)
|
||||||
* Apache Jena - DBOE Base (org.apache.jena:jena-dboe-base:4.9.0 - https://jena.apache.org/jena-dboe-base/)
|
* jclouds sts api (org.apache.jclouds.api:sts:2.6.0 - https://jclouds.apache.org/sts/)
|
||||||
* Apache Jena - DBOE Indexes (org.apache.jena:jena-dboe-index:4.9.0 - https://jena.apache.org/jena-dboe-index/)
|
* jclouds Amazon Simple Storage Service (S3) provider (org.apache.jclouds.provider:aws-s3:2.6.0 - https://jclouds.apache.org/aws-s3/)
|
||||||
* Apache Jena - DBOE Storage (org.apache.jena:jena-dboe-storage:4.9.0 - https://jena.apache.org/jena-dboe-storage/)
|
* Apache Jena - Libraries POM (org.apache.jena:apache-jena-libs:4.10.0 - https://jena.apache.org/apache-jena-libs/)
|
||||||
* Apache Jena - DBOE Transactional Datastructures (org.apache.jena:jena-dboe-trans-data:4.9.0 - https://jena.apache.org/jena-dboe-trans-data/)
|
* Apache Jena - ARQ (org.apache.jena:jena-arq:4.10.0 - https://jena.apache.org/jena-arq/)
|
||||||
* Apache Jena - DBOE Transactions (org.apache.jena:jena-dboe-transaction:4.9.0 - https://jena.apache.org/jena-dboe-transaction/)
|
* Apache Jena - Base (org.apache.jena:jena-base:4.10.0 - https://jena.apache.org/jena-base/)
|
||||||
* Apache Jena - IRI (org.apache.jena:jena-iri:4.9.0 - https://jena.apache.org/jena-iri/)
|
* Apache Jena - Core (org.apache.jena:jena-core:4.10.0 - https://jena.apache.org/jena-core/)
|
||||||
* Apache Jena - RDF Connection (org.apache.jena:jena-rdfconnection:4.9.0 - https://jena.apache.org/jena-rdfconnection/)
|
* Apache Jena - DBOE Base (org.apache.jena:jena-dboe-base:4.10.0 - https://jena.apache.org/jena-dboe-base/)
|
||||||
* Apache Jena - RDF Patch (org.apache.jena:jena-rdfpatch:4.9.0 - https://jena.apache.org/jena-rdfpatch/)
|
* Apache Jena - DBOE Indexes (org.apache.jena:jena-dboe-index:4.10.0 - https://jena.apache.org/jena-dboe-index/)
|
||||||
* Apache Jena - SHACL (org.apache.jena:jena-shacl:4.9.0 - https://jena.apache.org/jena-shacl/)
|
* Apache Jena - DBOE Storage (org.apache.jena:jena-dboe-storage:4.10.0 - https://jena.apache.org/jena-dboe-storage/)
|
||||||
* Apache Jena - ShEx (org.apache.jena:jena-shex:4.9.0 - https://jena.apache.org/jena-shex/)
|
* Apache Jena - DBOE Transactional Datastructures (org.apache.jena:jena-dboe-trans-data:4.10.0 - https://jena.apache.org/jena-dboe-trans-data/)
|
||||||
* Apache Jena - TDB1 (Native Triple Store) (org.apache.jena:jena-tdb:4.9.0 - https://jena.apache.org/jena-tdb/)
|
* Apache Jena - DBOE Transactions (org.apache.jena:jena-dboe-transaction:4.10.0 - https://jena.apache.org/jena-dboe-transaction/)
|
||||||
* Apache Jena - TDB2 (Native Triple Store) (org.apache.jena:jena-tdb2:4.9.0 - https://jena.apache.org/jena-tdb2/)
|
* Apache Jena - IRI (org.apache.jena:jena-iri:4.10.0 - https://jena.apache.org/jena-iri/)
|
||||||
|
* Apache Jena - RDF Connection (org.apache.jena:jena-rdfconnection:4.10.0 - https://jena.apache.org/jena-rdfconnection/)
|
||||||
|
* Apache Jena - RDF Patch (org.apache.jena:jena-rdfpatch:4.10.0 - https://jena.apache.org/jena-rdfpatch/)
|
||||||
|
* Apache Jena - SHACL (org.apache.jena:jena-shacl:4.10.0 - https://jena.apache.org/jena-shacl/)
|
||||||
|
* Apache Jena - ShEx (org.apache.jena:jena-shex:4.10.0 - https://jena.apache.org/jena-shex/)
|
||||||
|
* Apache Jena - TDB1 (Native Triple Store) (org.apache.jena:jena-tdb:4.10.0 - https://jena.apache.org/jena-tdb/)
|
||||||
|
* Apache Jena - TDB2 (Native Triple Store) (org.apache.jena:jena-tdb2:4.10.0 - https://jena.apache.org/jena-tdb2/)
|
||||||
* Kerby-kerb core (org.apache.kerby:kerb-core:1.0.1 - http://directory.apache.org/kerby/kerby-kerb/kerb-core)
|
* Kerby-kerb core (org.apache.kerby:kerb-core:1.0.1 - http://directory.apache.org/kerby/kerby-kerb/kerb-core)
|
||||||
* Kerby-kerb Util (org.apache.kerby:kerb-util:1.0.1 - http://directory.apache.org/kerby/kerby-kerb/kerb-util)
|
* Kerby-kerb Util (org.apache.kerby:kerb-util:1.0.1 - http://directory.apache.org/kerby/kerby-kerb/kerb-util)
|
||||||
* Kerby ASN1 Project (org.apache.kerby:kerby-asn1:1.0.1 - http://directory.apache.org/kerby/kerby-common/kerby-asn1)
|
* Kerby ASN1 Project (org.apache.kerby:kerby-asn1:1.0.1 - http://directory.apache.org/kerby/kerby-common/kerby-asn1)
|
||||||
* Kerby PKIX Project (org.apache.kerby:kerby-pkix:1.0.1 - http://directory.apache.org/kerby/kerby-pkix)
|
* Kerby PKIX Project (org.apache.kerby:kerby-pkix:1.0.1 - http://directory.apache.org/kerby/kerby-pkix)
|
||||||
* Apache Log4j 1.x Compatibility API (org.apache.logging.log4j:log4j-1.2-api:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-1.2-api/)
|
* Apache Log4j 1.x Compatibility API (org.apache.logging.log4j:log4j-1.2-api:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-1.2-api/)
|
||||||
* Apache Log4j API (org.apache.logging.log4j:log4j-api:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-api/)
|
* Apache Log4j API (org.apache.logging.log4j:log4j-api:2.24.3 - https://logging.apache.org/log4j/2.x/log4j/log4j-api/)
|
||||||
* Apache Log4j Core (org.apache.logging.log4j:log4j-core:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-core/)
|
* Apache Log4j Core (org.apache.logging.log4j:log4j-core:2.24.3 - https://logging.apache.org/log4j/2.x/log4j/log4j-core/)
|
||||||
* Apache Log4j JUL Adapter (org.apache.logging.log4j:log4j-jul:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-jul/)
|
* Apache Log4j JUL Adapter (org.apache.logging.log4j:log4j-jul:2.24.3 - https://logging.apache.org/log4j/2.x/log4j/log4j-jul/)
|
||||||
* Apache Log4j Layout for JSON template (org.apache.logging.log4j:log4j-layout-template-json:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-layout-template-json/)
|
* Apache Log4j Layout for JSON template (org.apache.logging.log4j:log4j-layout-template-json:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-layout-template-json/)
|
||||||
* Apache Log4j SLF4J Binding (org.apache.logging.log4j:log4j-slf4j-impl:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-slf4j-impl/)
|
* Apache Log4j SLF4J Binding (org.apache.logging.log4j:log4j-slf4j-impl:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/)
|
||||||
* Apache Log4j SLF4J 2.0 Binding (org.apache.logging.log4j:log4j-slf4j2-impl:2.21.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-slf4j2-impl/)
|
* SLF4J 2 Provider for Log4j API (org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3 - https://logging.apache.org/log4j/2.x/log4j/log4j-slf4j2-impl/)
|
||||||
* Apache Log4j Web (org.apache.logging.log4j:log4j-web:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-web/)
|
* Apache Log4j Web (org.apache.logging.log4j:log4j-web:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-web/)
|
||||||
* Lucene Common Analyzers (org.apache.lucene:lucene-analyzers-common:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-common)
|
* Lucene Common Analyzers (org.apache.lucene:lucene-analyzers-common:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-common)
|
||||||
* Lucene ICU Analysis Components (org.apache.lucene:lucene-analyzers-icu:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-icu)
|
* Lucene ICU Analysis Components (org.apache.lucene:lucene-analyzers-icu:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-icu)
|
||||||
* Lucene Kuromoji Japanese Morphological Analyzer (org.apache.lucene:lucene-analyzers-kuromoji:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-kuromoji)
|
* Lucene Kuromoji Japanese Morphological Analyzer (org.apache.lucene:lucene-analyzers-kuromoji:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-kuromoji)
|
||||||
* Lucene Nori Korean Morphological Analyzer (org.apache.lucene:lucene-analyzers-nori:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-nori)
|
* Lucene Nori Korean Morphological Analyzer (org.apache.lucene:lucene-analyzers-nori:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-nori)
|
||||||
* Lucene Phonetic Filters (org.apache.lucene:lucene-analyzers-phonetic:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-phonetic)
|
* Lucene Phonetic Filters (org.apache.lucene:lucene-analyzers-phonetic:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-phonetic)
|
||||||
* Lucene Smart Chinese Analyzer (org.apache.lucene:lucene-analyzers-smartcn:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-smartcn)
|
* Lucene Smart Chinese Analyzer (org.apache.lucene:lucene-analyzers-smartcn:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-smartcn)
|
||||||
* Lucene Stempel Analyzer (org.apache.lucene:lucene-analyzers-stempel:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-analyzers-stempel)
|
* Lucene Stempel Analyzer (org.apache.lucene:lucene-analyzers-stempel:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-stempel)
|
||||||
* Lucene Memory (org.apache.lucene:lucene-backward-codecs:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-backward-codecs)
|
* Lucene Memory (org.apache.lucene:lucene-backward-codecs:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-backward-codecs)
|
||||||
* Lucene Classification (org.apache.lucene:lucene-classification:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-classification)
|
* Lucene Classification (org.apache.lucene:lucene-classification:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-classification)
|
||||||
* Lucene codecs (org.apache.lucene:lucene-codecs:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-codecs)
|
* Lucene codecs (org.apache.lucene:lucene-codecs:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-codecs)
|
||||||
* Lucene Core (org.apache.lucene:lucene-core:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-core)
|
* Lucene Core (org.apache.lucene:lucene-core:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-core)
|
||||||
* Lucene Expressions (org.apache.lucene:lucene-expressions:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-expressions)
|
* Lucene Expressions (org.apache.lucene:lucene-expressions:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-expressions)
|
||||||
* Lucene Grouping (org.apache.lucene:lucene-grouping:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-grouping)
|
* Lucene Grouping (org.apache.lucene:lucene-grouping:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-grouping)
|
||||||
* Lucene Highlighter (org.apache.lucene:lucene-highlighter:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-highlighter)
|
* Lucene Highlighter (org.apache.lucene:lucene-highlighter:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-highlighter)
|
||||||
* Lucene Join (org.apache.lucene:lucene-join:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-join)
|
* Lucene Join (org.apache.lucene:lucene-join:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-join)
|
||||||
* Lucene Memory (org.apache.lucene:lucene-memory:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-memory)
|
* Lucene Memory (org.apache.lucene:lucene-memory:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-memory)
|
||||||
* Lucene Miscellaneous (org.apache.lucene:lucene-misc:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-misc)
|
* Lucene Miscellaneous (org.apache.lucene:lucene-misc:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-misc)
|
||||||
* Lucene Queries (org.apache.lucene:lucene-queries:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-queries)
|
* Lucene Queries (org.apache.lucene:lucene-queries:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-queries)
|
||||||
* Lucene QueryParsers (org.apache.lucene:lucene-queryparser:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-queryparser)
|
* Lucene QueryParsers (org.apache.lucene:lucene-queryparser:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-queryparser)
|
||||||
* Lucene Sandbox (org.apache.lucene:lucene-sandbox:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-sandbox)
|
* Lucene Sandbox (org.apache.lucene:lucene-sandbox:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-sandbox)
|
||||||
* Lucene Spatial Extras (org.apache.lucene:lucene-spatial-extras:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-spatial-extras)
|
* Lucene Spatial Extras (org.apache.lucene:lucene-spatial-extras:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-spatial-extras)
|
||||||
* Lucene Spatial 3D (org.apache.lucene:lucene-spatial3d:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-spatial3d)
|
* Lucene Spatial 3D (org.apache.lucene:lucene-spatial3d:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-spatial3d)
|
||||||
* Lucene Suggest (org.apache.lucene:lucene-suggest:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-suggest)
|
* Lucene Suggest (org.apache.lucene:lucene-suggest:8.11.4 - https://lucene.apache.org/lucene-parent/lucene-suggest)
|
||||||
* Apache FontBox (org.apache.pdfbox:fontbox:2.0.31 - http://pdfbox.apache.org/)
|
* Apache FontBox (org.apache.pdfbox:fontbox:2.0.33 - http://pdfbox.apache.org/)
|
||||||
* PDFBox JBIG2 ImageIO plugin (org.apache.pdfbox:jbig2-imageio:3.0.4 - https://www.apache.org/jbig2-imageio/)
|
* PDFBox JBIG2 ImageIO plugin (org.apache.pdfbox:jbig2-imageio:3.0.4 - https://www.apache.org/jbig2-imageio/)
|
||||||
* Apache JempBox (org.apache.pdfbox:jempbox:1.8.17 - http://www.apache.org/pdfbox-parent/jempbox/)
|
* Apache JempBox (org.apache.pdfbox:jempbox:1.8.17 - http://www.apache.org/pdfbox-parent/jempbox/)
|
||||||
* Apache PDFBox (org.apache.pdfbox:pdfbox:2.0.31 - https://www.apache.org/pdfbox-parent/pdfbox/)
|
* Apache PDFBox (org.apache.pdfbox:pdfbox:2.0.33 - https://www.apache.org/pdfbox-parent/pdfbox/)
|
||||||
* Apache PDFBox tools (org.apache.pdfbox:pdfbox-tools:2.0.31 - https://www.apache.org/pdfbox-parent/pdfbox-tools/)
|
* Apache PDFBox tools (org.apache.pdfbox:pdfbox-tools:2.0.33 - https://www.apache.org/pdfbox-parent/pdfbox-tools/)
|
||||||
* Apache XmpBox (org.apache.pdfbox:xmpbox:2.0.31 - https://www.apache.org/pdfbox-parent/xmpbox/)
|
* Apache XmpBox (org.apache.pdfbox:xmpbox:2.0.33 - https://www.apache.org/pdfbox-parent/xmpbox/)
|
||||||
* Apache POI - Common (org.apache.poi:poi:5.2.5 - https://poi.apache.org/)
|
* Apache POI - Common (org.apache.poi:poi:5.4.0 - https://poi.apache.org/)
|
||||||
* Apache POI - API based on OPC and OOXML schemas (org.apache.poi:poi-ooxml:5.2.5 - https://poi.apache.org/)
|
* Apache POI - API based on OPC and OOXML schemas (org.apache.poi:poi-ooxml:5.4.0 - https://poi.apache.org/)
|
||||||
* Apache POI (org.apache.poi:poi-ooxml-lite:5.2.5 - https://poi.apache.org/)
|
* Apache POI (org.apache.poi:poi-ooxml-lite:5.4.0 - https://poi.apache.org/)
|
||||||
* Apache POI (org.apache.poi:poi-scratchpad:5.2.5 - https://poi.apache.org/)
|
* Apache POI (org.apache.poi:poi-scratchpad:5.4.0 - https://poi.apache.org/)
|
||||||
* Apache Solr Core (org.apache.solr:solr-core:8.11.3 - https://lucene.apache.org/solr-parent/solr-core)
|
* Apache XML Security for Java (org.apache.santuario:xmlsec:2.3.4 - https://santuario.apache.org/)
|
||||||
* Apache Solr Solrj (org.apache.solr:solr-solrj:8.11.3 - https://lucene.apache.org/solr-parent/solr-solrj)
|
* Apache Solr Core (org.apache.solr:solr-core:8.11.4 - https://lucene.apache.org/solr-parent/solr-core)
|
||||||
|
* Apache Solr Solrj (org.apache.solr:solr-solrj:8.11.4 - https://lucene.apache.org/solr-parent/solr-solrj)
|
||||||
* Apache Standard Taglib Implementation (org.apache.taglibs:taglibs-standard-impl:1.2.5 - http://tomcat.apache.org/taglibs/standard-1.2.5/taglibs-standard-impl)
|
* Apache Standard Taglib Implementation (org.apache.taglibs:taglibs-standard-impl:1.2.5 - http://tomcat.apache.org/taglibs/standard-1.2.5/taglibs-standard-impl)
|
||||||
* Apache Standard Taglib Specification API (org.apache.taglibs:taglibs-standard-spec:1.2.5 - http://tomcat.apache.org/taglibs/standard-1.2.5/taglibs-standard-spec)
|
* Apache Standard Taglib Specification API (org.apache.taglibs:taglibs-standard-spec:1.2.5 - http://tomcat.apache.org/taglibs/standard-1.2.5/taglibs-standard-spec)
|
||||||
* Apache Thrift (org.apache.thrift:libthrift:0.18.1 - http://thrift.apache.org)
|
* Apache Thrift (org.apache.thrift:libthrift:0.19.0 - http://thrift.apache.org)
|
||||||
* Apache Tika core (org.apache.tika:tika-core:2.9.2 - https://tika.apache.org/)
|
* Apache Tika core (org.apache.tika:tika-core:2.9.3 - https://tika.apache.org/)
|
||||||
* Apache Tika Apple parser module (org.apache.tika:tika-parser-apple-module:2.9.2 - https://tika.apache.org/tika-parser-apple-module/)
|
* Apache Tika Apple parser module (org.apache.tika:tika-parser-apple-module:2.9.3 - https://tika.apache.org/tika-parser-apple-module/)
|
||||||
* Apache Tika audiovideo parser module (org.apache.tika:tika-parser-audiovideo-module:2.9.2 - https://tika.apache.org/tika-parser-audiovideo-module/)
|
* Apache Tika audiovideo parser module (org.apache.tika:tika-parser-audiovideo-module:2.9.3 - https://tika.apache.org/tika-parser-audiovideo-module/)
|
||||||
* Apache Tika cad parser module (org.apache.tika:tika-parser-cad-module:2.9.2 - https://tika.apache.org/tika-parser-cad-module/)
|
* Apache Tika cad parser module (org.apache.tika:tika-parser-cad-module:2.9.3 - https://tika.apache.org/tika-parser-cad-module/)
|
||||||
* Apache Tika code parser module (org.apache.tika:tika-parser-code-module:2.9.2 - https://tika.apache.org/tika-parser-code-module/)
|
* Apache Tika code parser module (org.apache.tika:tika-parser-code-module:2.9.3 - https://tika.apache.org/tika-parser-code-module/)
|
||||||
* Apache Tika crypto parser module (org.apache.tika:tika-parser-crypto-module:2.9.2 - https://tika.apache.org/tika-parser-crypto-module/)
|
* Apache Tika crypto parser module (org.apache.tika:tika-parser-crypto-module:2.9.3 - https://tika.apache.org/tika-parser-crypto-module/)
|
||||||
* Apache Tika digest commons (org.apache.tika:tika-parser-digest-commons:2.9.2 - https://tika.apache.org/tika-parser-digest-commons/)
|
* Apache Tika digest commons (org.apache.tika:tika-parser-digest-commons:2.9.3 - https://tika.apache.org/tika-parser-digest-commons/)
|
||||||
* Apache Tika font parser module (org.apache.tika:tika-parser-font-module:2.9.2 - https://tika.apache.org/tika-parser-font-module/)
|
* Apache Tika font parser module (org.apache.tika:tika-parser-font-module:2.9.3 - https://tika.apache.org/tika-parser-font-module/)
|
||||||
* Apache Tika html parser module (org.apache.tika:tika-parser-html-module:2.9.2 - https://tika.apache.org/tika-parser-html-module/)
|
* Apache Tika html parser module (org.apache.tika:tika-parser-html-module:2.9.3 - https://tika.apache.org/tika-parser-html-module/)
|
||||||
* Apache Tika image parser module (org.apache.tika:tika-parser-image-module:2.9.2 - https://tika.apache.org/tika-parser-image-module/)
|
* Apache Tika image parser module (org.apache.tika:tika-parser-image-module:2.9.3 - https://tika.apache.org/tika-parser-image-module/)
|
||||||
* Apache Tika mail commons (org.apache.tika:tika-parser-mail-commons:2.9.2 - https://tika.apache.org/tika-parser-mail-commons/)
|
* Apache Tika mail commons (org.apache.tika:tika-parser-mail-commons:2.9.3 - https://tika.apache.org/tika-parser-mail-commons/)
|
||||||
* Apache Tika mail parser module (org.apache.tika:tika-parser-mail-module:2.9.2 - https://tika.apache.org/tika-parser-mail-module/)
|
* Apache Tika mail parser module (org.apache.tika:tika-parser-mail-module:2.9.3 - https://tika.apache.org/tika-parser-mail-module/)
|
||||||
* Apache Tika Microsoft parser module (org.apache.tika:tika-parser-microsoft-module:2.9.2 - https://tika.apache.org/tika-parser-microsoft-module/)
|
* Apache Tika Microsoft parser module (org.apache.tika:tika-parser-microsoft-module:2.9.3 - https://tika.apache.org/tika-parser-microsoft-module/)
|
||||||
* Apache Tika miscellaneous office format parser module (org.apache.tika:tika-parser-miscoffice-module:2.9.2 - https://tika.apache.org/tika-parser-miscoffice-module/)
|
* Apache Tika miscellaneous office format parser module (org.apache.tika:tika-parser-miscoffice-module:2.9.3 - https://tika.apache.org/tika-parser-miscoffice-module/)
|
||||||
* Apache Tika news parser module (org.apache.tika:tika-parser-news-module:2.9.2 - https://tika.apache.org/tika-parser-news-module/)
|
* Apache Tika news parser module (org.apache.tika:tika-parser-news-module:2.9.3 - https://tika.apache.org/tika-parser-news-module/)
|
||||||
* Apache Tika OCR parser module (org.apache.tika:tika-parser-ocr-module:2.9.2 - https://tika.apache.org/tika-parser-ocr-module/)
|
* Apache Tika OCR parser module (org.apache.tika:tika-parser-ocr-module:2.9.3 - https://tika.apache.org/tika-parser-ocr-module/)
|
||||||
* Apache Tika PDF parser module (org.apache.tika:tika-parser-pdf-module:2.9.2 - https://tika.apache.org/tika-parser-pdf-module/)
|
* Apache Tika PDF parser module (org.apache.tika:tika-parser-pdf-module:2.9.3 - https://tika.apache.org/tika-parser-pdf-module/)
|
||||||
* Apache Tika package parser module (org.apache.tika:tika-parser-pkg-module:2.9.2 - https://tika.apache.org/tika-parser-pkg-module/)
|
* Apache Tika package parser module (org.apache.tika:tika-parser-pkg-module:2.9.3 - https://tika.apache.org/tika-parser-pkg-module/)
|
||||||
* Apache Tika text parser module (org.apache.tika:tika-parser-text-module:2.9.2 - https://tika.apache.org/tika-parser-text-module/)
|
* Apache Tika text parser module (org.apache.tika:tika-parser-text-module:2.9.3 - https://tika.apache.org/tika-parser-text-module/)
|
||||||
* Apache Tika WARC parser module (org.apache.tika:tika-parser-webarchive-module:2.9.2 - https://tika.apache.org/tika-parser-webarchive-module/)
|
* Apache Tika WARC parser module (org.apache.tika:tika-parser-webarchive-module:2.9.3 - https://tika.apache.org/tika-parser-webarchive-module/)
|
||||||
* Apache Tika XML parser module (org.apache.tika:tika-parser-xml-module:2.9.2 - https://tika.apache.org/tika-parser-xml-module/)
|
* Apache Tika XML parser module (org.apache.tika:tika-parser-xml-module:2.9.3 - https://tika.apache.org/tika-parser-xml-module/)
|
||||||
* Apache Tika XMP commons (org.apache.tika:tika-parser-xmp-commons:2.9.2 - https://tika.apache.org/tika-parser-xmp-commons/)
|
* Apache Tika XMP commons (org.apache.tika:tika-parser-xmp-commons:2.9.3 - https://tika.apache.org/tika-parser-xmp-commons/)
|
||||||
* Apache Tika ZIP commons (org.apache.tika:tika-parser-zip-commons:2.9.2 - https://tika.apache.org/tika-parser-zip-commons/)
|
* Apache Tika ZIP commons (org.apache.tika:tika-parser-zip-commons:2.9.3 - https://tika.apache.org/tika-parser-zip-commons/)
|
||||||
* Apache Tika standard parser package (org.apache.tika:tika-parsers-standard-package:2.9.2 - https://tika.apache.org/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/)
|
* Apache Tika standard parser package (org.apache.tika:tika-parsers-standard-package:2.9.3 - https://tika.apache.org/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/)
|
||||||
* tomcat-embed-core (org.apache.tomcat.embed:tomcat-embed-core:10.1.24 - https://tomcat.apache.org/)
|
* tomcat-embed-core (org.apache.tomcat.embed:tomcat-embed-core:10.1.36 - https://tomcat.apache.org/)
|
||||||
* tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:10.1.24 - https://tomcat.apache.org/)
|
* tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:10.1.36 - https://tomcat.apache.org/)
|
||||||
* tomcat-embed-websocket (org.apache.tomcat.embed:tomcat-embed-websocket:10.1.24 - https://tomcat.apache.org/)
|
* tomcat-embed-websocket (org.apache.tomcat.embed:tomcat-embed-websocket:10.1.36 - https://tomcat.apache.org/)
|
||||||
* Apache Velocity - Engine (org.apache.velocity:velocity-engine-core:2.3 - http://velocity.apache.org/engine/devel/velocity-engine-core/)
|
* Apache Velocity - Engine (org.apache.velocity:velocity-engine-core:2.4.1 - http://velocity.apache.org/engine/devel/velocity-engine-core/)
|
||||||
* Apache Velocity - JSR 223 Scripting (org.apache.velocity:velocity-engine-scripting:2.2 - http://velocity.apache.org/engine/devel/velocity-engine-scripting/)
|
* Apache Velocity - JSR 223 Scripting (org.apache.velocity:velocity-engine-scripting:2.3 - http://velocity.apache.org/engine/devel/velocity-engine-scripting/)
|
||||||
|
* Apache Velocity Tools - Generic tools (org.apache.velocity.tools:velocity-tools-generic:3.1 - https://velocity.apache.org/tools/devel/velocity-tools-generic/)
|
||||||
* Axiom API (org.apache.ws.commons.axiom:axiom-api:1.2.14 - http://ws.apache.org/axiom/)
|
* Axiom API (org.apache.ws.commons.axiom:axiom-api:1.2.14 - http://ws.apache.org/axiom/)
|
||||||
* Axiom Impl (org.apache.ws.commons.axiom:axiom-impl:1.2.14 - http://ws.apache.org/axiom/)
|
* Axiom Impl (org.apache.ws.commons.axiom:axiom-impl:1.2.14 - http://ws.apache.org/axiom/)
|
||||||
* XmlBeans (org.apache.xmlbeans:xmlbeans:5.2.0 - https://xmlbeans.apache.org/)
|
* XmlBeans (org.apache.xmlbeans:xmlbeans:5.3.0 - https://xmlbeans.apache.org/)
|
||||||
* Apache ZooKeeper - Server (org.apache.zookeeper:zookeeper:3.6.2 - http://zookeeper.apache.org/zookeeper)
|
* Apache ZooKeeper - Server (org.apache.zookeeper:zookeeper:3.6.2 - http://zookeeper.apache.org/zookeeper)
|
||||||
* Apache ZooKeeper - Jute (org.apache.zookeeper:zookeeper-jute:3.6.2 - http://zookeeper.apache.org/zookeeper-jute)
|
* Apache ZooKeeper - Jute (org.apache.zookeeper:zookeeper-jute:3.6.2 - http://zookeeper.apache.org/zookeeper-jute)
|
||||||
* org.apiguardian:apiguardian-api (org.apiguardian:apiguardian-api:1.1.2 - https://github.com/apiguardian-team/apiguardian)
|
* org.apiguardian:apiguardian-api (org.apiguardian:apiguardian-api:1.1.2 - https://github.com/apiguardian-team/apiguardian)
|
||||||
* AssertJ Core (org.assertj:assertj-core:3.24.2 - https://assertj.github.io/doc/#assertj-core)
|
* AssertJ Core (org.assertj:assertj-core:3.26.3 - https://assertj.github.io/doc/#assertj-core)
|
||||||
* Evo Inflector (org.atteo:evo-inflector:1.3 - http://atteo.org/static/evo-inflector)
|
* Evo Inflector (org.atteo:evo-inflector:1.3 - http://atteo.org/static/evo-inflector)
|
||||||
* Awaitility (org.awaitility:awaitility:4.2.1 - http://awaitility.org)
|
* attoparser (org.attoparser:attoparser:2.0.7.RELEASE - https://www.attoparser.org)
|
||||||
|
* Awaitility (org.awaitility:awaitility:4.2.2 - http://awaitility.org)
|
||||||
* jose4j (org.bitbucket.b_c:jose4j:0.6.5 - https://bitbucket.org/b_c/jose4j/)
|
* jose4j (org.bitbucket.b_c:jose4j:0.6.5 - https://bitbucket.org/b_c/jose4j/)
|
||||||
* TagSoup (org.ccil.cowan.tagsoup:tagsoup:1.2.1 - http://home.ccil.org/~cowan/XML/tagsoup/)
|
* TagSoup (org.ccil.cowan.tagsoup:tagsoup:1.2.1 - http://home.ccil.org/~cowan/XML/tagsoup/)
|
||||||
* Woodstox (org.codehaus.woodstox:wstx-asl:3.2.6 - http://woodstox.codehaus.org)
|
* Woodstox (org.codehaus.woodstox:wstx-asl:3.2.6 - http://woodstox.codehaus.org)
|
||||||
|
* Cryptacular Library (org.cryptacular:cryptacular:1.2.5 - http://www.cryptacular.org)
|
||||||
* jems (org.dmfs:jems:1.18 - https://github.com/dmfs/jems)
|
* jems (org.dmfs:jems:1.18 - https://github.com/dmfs/jems)
|
||||||
* rfc3986-uri (org.dmfs:rfc3986-uri:0.8.1 - https://github.com/dmfs/uri-toolkit)
|
* rfc3986-uri (org.dmfs:rfc3986-uri:0.8.1 - https://github.com/dmfs/uri-toolkit)
|
||||||
* Jetty :: Apache JSP Implementation (org.eclipse.jetty:apache-jsp:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Apache JSP Implementation (org.eclipse.jetty:apache-jsp:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
@@ -335,124 +354,130 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* Jetty :: Asynchronous HTTP Client (org.eclipse.jetty:jetty-client:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-client)
|
* Jetty :: Asynchronous HTTP Client (org.eclipse.jetty:jetty-client:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-client)
|
||||||
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-continuation)
|
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-continuation)
|
||||||
* Jetty :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-deploy)
|
* Jetty :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.57.v20241219 - https://jetty.org/jetty-deploy/)
|
||||||
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-http)
|
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.57.v20241219 - https://jetty.org/jetty-http/)
|
||||||
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-io)
|
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.57.v20241219 - https://jetty.org/jetty-io/)
|
||||||
* Jetty :: JMX Management (org.eclipse.jetty:jetty-jmx:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-jmx)
|
* Jetty :: JMX Management (org.eclipse.jetty:jetty-jmx:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-jmx)
|
||||||
* Jetty :: JNDI Naming (org.eclipse.jetty:jetty-jndi:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: JNDI Naming (org.eclipse.jetty:jetty-jndi:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Plus (org.eclipse.jetty:jetty-plus:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Plus (org.eclipse.jetty:jetty-plus:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Rewrite Handler (org.eclipse.jetty:jetty-rewrite:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-rewrite)
|
* Jetty :: Rewrite Handler (org.eclipse.jetty:jetty-rewrite:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-rewrite)
|
||||||
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-security)
|
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-security)
|
||||||
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-security)
|
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.57.v20241219 - https://jetty.org/jetty-security/)
|
||||||
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-server)
|
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.57.v20241219 - https://jetty.org/jetty-server/)
|
||||||
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-servlet)
|
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.57.v20241219 - https://jetty.org/jetty-servlet/)
|
||||||
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-servlets)
|
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-servlets)
|
||||||
* Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util)
|
* Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.57.v20241219 - https://jetty.org/jetty-util/)
|
||||||
* Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util-ajax)
|
* Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.57.v20241219 - https://jetty.org/jetty-util-ajax/)
|
||||||
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-webapp)
|
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.57.v20241219 - https://jetty.org/jetty-webapp/)
|
||||||
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-xml)
|
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-xml)
|
||||||
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-xml)
|
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.57.v20241219 - https://jetty.org/jetty-xml/)
|
||||||
* Jetty :: ALPN :: API (org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715 - http://www.eclipse.org/jetty/alpn-api)
|
* Jetty :: ALPN :: API (org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715 - http://www.eclipse.org/jetty/alpn-api)
|
||||||
* Jetty :: HTTP2 :: Client (org.eclipse.jetty.http2:http2-client:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-client)
|
* Jetty :: HTTP2 :: Client (org.eclipse.jetty.http2:http2-client:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-client)
|
||||||
* Jetty :: HTTP2 :: Common (org.eclipse.jetty.http2:http2-common:9.4.54.v20240208 - https://eclipse.org/jetty/http2-parent/http2-common)
|
* Jetty :: HTTP2 :: Common (org.eclipse.jetty.http2:http2-common:9.4.57.v20241219 - https://jetty.org/http2-parent/http2-common/)
|
||||||
* Jetty :: HTTP2 :: HPACK (org.eclipse.jetty.http2:http2-hpack:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-hpack)
|
* Jetty :: HTTP2 :: HPACK (org.eclipse.jetty.http2:http2-hpack:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-hpack)
|
||||||
* Jetty :: HTTP2 :: HTTP Client Transport (org.eclipse.jetty.http2:http2-http-client-transport:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-http-client-transport)
|
* Jetty :: HTTP2 :: HTTP Client Transport (org.eclipse.jetty.http2:http2-http-client-transport:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-http-client-transport)
|
||||||
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.15.v20190215 - https://eclipse.org/jetty/http2-parent/http2-server)
|
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.15.v20190215 - https://eclipse.org/jetty/http2-parent/http2-server)
|
||||||
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-server)
|
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-server)
|
||||||
* Jetty :: Schemas (org.eclipse.jetty.toolchain:jetty-schemas:3.1.2 - https://eclipse.org/jetty/jetty-schemas)
|
* Jetty :: Schemas (org.eclipse.jetty.toolchain:jetty-schemas:3.1.2 - https://eclipse.org/jetty/jetty-schemas)
|
||||||
* Ehcache (org.ehcache:ehcache:3.10.8 - http://ehcache.org)
|
* Ehcache (org.ehcache:ehcache:3.10.8 - http://ehcache.org)
|
||||||
* flyway-core (org.flywaydb:flyway-core:10.10.0 - https://flywaydb.org/flyway-core)
|
* flyway-core (org.flywaydb:flyway-core:10.22.0 - https://flywaydb.org/flyway-core)
|
||||||
* flyway-database-postgresql (org.flywaydb:flyway-database-postgresql:10.10.0 - https://flywaydb.org/flyway-database-postgresql)
|
* flyway-database-postgresql (org.flywaydb:flyway-database-postgresql:10.22.0 - https://flywaydb.org/flyway-database-postgresql)
|
||||||
* Ogg and Vorbis for Java, Core (org.gagravarr:vorbis-java-core:0.8 - https://github.com/Gagravarr/VorbisJava)
|
* Ogg and Vorbis for Java, Core (org.gagravarr:vorbis-java-core:0.8 - https://github.com/Gagravarr/VorbisJava)
|
||||||
* Apache Tika plugin for Ogg, Vorbis and FLAC (org.gagravarr:vorbis-java-tika:0.8 - https://github.com/Gagravarr/VorbisJava)
|
* Apache Tika plugin for Ogg, Vorbis and FLAC (org.gagravarr:vorbis-java-tika:0.8 - https://github.com/Gagravarr/VorbisJava)
|
||||||
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
|
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
||||||
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:8.0.1.Final - http://hibernate.org/validator/hibernate-validator)
|
* Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:8.0.1.Final - http://hibernate.org/validator/hibernate-validator)
|
||||||
* Hibernate Validator Portable Extension (org.hibernate.validator:hibernate-validator-cdi:8.0.1.Final - http://hibernate.org/validator/hibernate-validator-cdi)
|
* Hibernate Validator Portable Extension (org.hibernate.validator:hibernate-validator-cdi:8.0.1.Final - http://hibernate.org/validator/hibernate-validator-cdi)
|
||||||
* org.immutables.value-annotations (org.immutables:value-annotations:2.9.2 - http://immutables.org/value-annotations)
|
* org.immutables.value-annotations (org.immutables:value-annotations:2.9.2 - http://immutables.org/value-annotations)
|
||||||
* leveldb (org.iq80.leveldb:leveldb:0.12 - http://github.com/dain/leveldb/leveldb)
|
* leveldb (org.iq80.leveldb:leveldb:0.12 - http://github.com/dain/leveldb/leveldb)
|
||||||
* leveldb-api (org.iq80.leveldb:leveldb-api:0.12 - http://github.com/dain/leveldb/leveldb-api)
|
* leveldb-api (org.iq80.leveldb:leveldb-api:0.12 - http://github.com/dain/leveldb/leveldb-api)
|
||||||
* Javassist (org.javassist:javassist:3.29.2-GA - http://www.javassist.org/)
|
* Javassist (org.javassist:javassist:3.30.2-GA - https://www.javassist.org/)
|
||||||
* JBoss Logging 3 (org.jboss.logging:jboss-logging:3.4.3.Final - http://www.jboss.org)
|
* JBoss Logging 3 (org.jboss.logging:jboss-logging:3.6.1.Final - http://www.jboss.org)
|
||||||
* JDOM (org.jdom:jdom2:2.0.6.1 - http://www.jdom.org)
|
* JDOM (org.jdom:jdom2:2.0.6.1 - http://www.jdom.org)
|
||||||
* jtwig-core (org.jtwig:jtwig-core:5.87.0.RELEASE - http://jtwig.org)
|
|
||||||
* jtwig-reflection (org.jtwig:jtwig-reflection:5.87.0.RELEASE - http://jtwig.org)
|
|
||||||
* jtwig-spring (org.jtwig:jtwig-spring:5.87.0.RELEASE - http://jtwig.org)
|
|
||||||
* jtwig-spring-boot-starter (org.jtwig:jtwig-spring-boot-starter:5.87.0.RELEASE - http://jtwig.org)
|
|
||||||
* jtwig-web (org.jtwig:jtwig-web:5.87.0.RELEASE - http://jtwig.org)
|
|
||||||
* Proj4J (org.locationtech.proj4j:proj4j:1.1.5 - https://github.com/locationtech/proj4j)
|
* Proj4J (org.locationtech.proj4j:proj4j:1.1.5 - https://github.com/locationtech/proj4j)
|
||||||
* Spatial4J (org.locationtech.spatial4j:spatial4j:0.7 - https://projects.eclipse.org/projects/locationtech.spatial4j)
|
* Spatial4J (org.locationtech.spatial4j:spatial4j:0.7 - https://projects.eclipse.org/projects/locationtech.spatial4j)
|
||||||
* MockServer Java Client (org.mock-server:mockserver-client-java:5.11.2 - http://www.mock-server.com)
|
* MockServer Java Client (org.mock-server:mockserver-client-java:5.15.0 - https://www.mock-server.com)
|
||||||
* MockServer Core (org.mock-server:mockserver-core:5.11.2 - http://www.mock-server.com)
|
* MockServer Core (org.mock-server:mockserver-core:5.15.0 - https://www.mock-server.com)
|
||||||
* MockServer JUnit 4 Integration (org.mock-server:mockserver-junit-rule:5.11.2 - http://www.mock-server.com)
|
* MockServer JUnit 4 Integration (org.mock-server:mockserver-junit-rule:5.15.0 - https://www.mock-server.com)
|
||||||
* MockServer & Proxy Netty (org.mock-server:mockserver-netty:5.11.2 - http://www.mock-server.com)
|
* MockServer & Proxy Netty (org.mock-server:mockserver-netty:5.15.0 - https://www.mock-server.com)
|
||||||
* Jetty Server (org.mortbay.jetty:jetty:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/modules/jetty)
|
* jwarc (org.netpreserve:jwarc:0.31.1 - https://github.com/iipc/jwarc)
|
||||||
* Jetty Servlet Tester (org.mortbay.jetty:jetty-servlet-tester:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/jetty-servlet-tester)
|
|
||||||
* Jetty Utilities (org.mortbay.jetty:jetty-util:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/jetty-util)
|
|
||||||
* Servlet Specification API (org.mortbay.jetty:servlet-api:2.5-20081211 - http://jetty.mortbay.org/servlet-api)
|
|
||||||
* jwarc (org.netpreserve:jwarc:0.29.0 - https://github.com/iipc/jwarc)
|
|
||||||
* Objenesis (org.objenesis:objenesis:3.2 - http://objenesis.org/objenesis)
|
* Objenesis (org.objenesis:objenesis:3.2 - http://objenesis.org/objenesis)
|
||||||
* parboiled-core (org.parboiled:parboiled-core:1.3.1 - http://parboiled.org)
|
* OpenSAML :: Core (org.opensaml:opensaml-core:4.3.2 - http://shibboleth.net/opensaml-core/)
|
||||||
* parboiled-java (org.parboiled:parboiled-java:1.3.1 - http://parboiled.org)
|
* OpenSAML :: Messaging API (org.opensaml:opensaml-messaging-api:4.3.2 - http://shibboleth.net/opensaml-messaging-api/)
|
||||||
* org.roaringbitmap:RoaringBitmap (org.roaringbitmap:RoaringBitmap:0.9.45 - https://github.com/RoaringBitmap/RoaringBitmap)
|
* OpenSAML :: Profile API (org.opensaml:opensaml-profile-api:4.3.2 - http://shibboleth.net/opensaml-profile-api/)
|
||||||
* org.roaringbitmap:shims (org.roaringbitmap:shims:0.9.45 - https://github.com/RoaringBitmap/RoaringBitmap)
|
* OpenSAML :: SAML Provider API (org.opensaml:opensaml-saml-api:4.3.2 - http://shibboleth.net/opensaml-saml-api/)
|
||||||
|
* OpenSAML :: SAML Provider Implementations (org.opensaml:opensaml-saml-impl:4.3.2 - http://shibboleth.net/opensaml-saml-impl/)
|
||||||
|
* OpenSAML :: Security API (org.opensaml:opensaml-security-api:4.3.2 - http://shibboleth.net/opensaml-security-api/)
|
||||||
|
* OpenSAML :: Security Implementation (org.opensaml:opensaml-security-impl:4.3.2 - http://shibboleth.net/opensaml-security-impl/)
|
||||||
|
* OpenSAML :: SOAP Provider API (org.opensaml:opensaml-soap-api:4.3.2 - http://shibboleth.net/opensaml-soap-api/)
|
||||||
|
* OpenSAML :: SOAP Provider Implementations (org.opensaml:opensaml-soap-impl:4.3.2 - http://shibboleth.net/opensaml-soap-impl/)
|
||||||
|
* OpenSAML :: Storage API (org.opensaml:opensaml-storage-api:4.3.2 - http://shibboleth.net/opensaml-storage-api/)
|
||||||
|
* OpenSAML :: XML Security API (org.opensaml:opensaml-xmlsec-api:4.3.2 - http://shibboleth.net/opensaml-xmlsec-api/)
|
||||||
|
* OpenSAML :: XML Security Implementation (org.opensaml:opensaml-xmlsec-impl:4.3.2 - http://shibboleth.net/opensaml-xmlsec-impl/)
|
||||||
|
* parboiled-core (org.parboiled:parboiled-core:1.1.7 - http://parboiled.org)
|
||||||
|
* parboiled-java (org.parboiled:parboiled-java:1.1.7 - http://parboiled.org)
|
||||||
|
* org.roaringbitmap:RoaringBitmap (org.roaringbitmap:RoaringBitmap:1.0.0 - https://github.com/RoaringBitmap/RoaringBitmap)
|
||||||
* RRD4J (org.rrd4j:rrd4j:3.5 - https://github.com/rrd4j/rrd4j/)
|
* RRD4J (org.rrd4j:rrd4j:3.5 - https://github.com/rrd4j/rrd4j/)
|
||||||
* Scala Library (org.scala-lang:scala-library:2.13.11 - https://www.scala-lang.org/)
|
* Scala Library (org.scala-lang:scala-library:2.13.2 - https://www.scala-lang.org/)
|
||||||
* Scala Compiler (org.scala-lang:scala-reflect:2.13.0 - https://www.scala-lang.org/)
|
* Scala Compiler (org.scala-lang:scala-reflect:2.13.0 - https://www.scala-lang.org/)
|
||||||
* scala-collection-compat (org.scala-lang.modules:scala-collection-compat_2.13:2.1.6 - http://www.scala-lang.org/)
|
* scala-collection-compat (org.scala-lang.modules:scala-collection-compat_2.13:2.1.6 - http://www.scala-lang.org/)
|
||||||
* scala-java8-compat (org.scala-lang.modules:scala-java8-compat_2.13:0.9.0 - http://www.scala-lang.org/)
|
* scala-java8-compat (org.scala-lang.modules:scala-java8-compat_2.13:0.9.0 - http://www.scala-lang.org/)
|
||||||
* scala-parser-combinators (org.scala-lang.modules:scala-parser-combinators_2.13:1.1.2 - http://www.scala-lang.org/)
|
* scala-parser-combinators (org.scala-lang.modules:scala-parser-combinators_2.13:1.1.2 - http://www.scala-lang.org/)
|
||||||
* scala-xml (org.scala-lang.modules:scala-xml_2.13:1.3.0 - http://www.scala-lang.org/)
|
* scala-xml (org.scala-lang.modules:scala-xml_2.13:1.3.0 - http://www.scala-lang.org/)
|
||||||
* JSONassert (org.skyscreamer:jsonassert:1.5.1 - https://github.com/skyscreamer/JSONassert)
|
* JSONassert (org.skyscreamer:jsonassert:1.5.3 - https://github.com/skyscreamer/JSONassert)
|
||||||
* JCL 1.2 implemented over SLF4J (org.slf4j:jcl-over-slf4j:2.0.11 - http://www.slf4j.org)
|
* JCL 1.2 implemented over SLF4J (org.slf4j:jcl-over-slf4j:2.0.16 - http://www.slf4j.org)
|
||||||
* Spring AOP (org.springframework:spring-aop:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring AOP (org.springframework:spring-aop:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Beans (org.springframework:spring-beans:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Beans (org.springframework:spring-beans:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Context (org.springframework:spring-context:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Context (org.springframework:spring-context:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Context Support (org.springframework:spring-context-support:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Context Support (org.springframework:spring-context-support:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Core (org.springframework:spring-core:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Core (org.springframework:spring-core:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Expression Language (SpEL) (org.springframework:spring-expression:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Expression Language (SpEL) (org.springframework:spring-expression:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Commons Logging Bridge (org.springframework:spring-jcl:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Commons Logging Bridge (org.springframework:spring-jcl:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring JDBC (org.springframework:spring-jdbc:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring JDBC (org.springframework:spring-jdbc:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Object/Relational Mapping (org.springframework:spring-orm:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Object/Relational Mapping (org.springframework:spring-orm:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring TestContext Framework (org.springframework:spring-test:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring TestContext Framework (org.springframework:spring-test:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Transaction (org.springframework:spring-tx:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Transaction (org.springframework:spring-tx:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Web (org.springframework:spring-web:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Web (org.springframework:spring-web:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* Spring Web MVC (org.springframework:spring-webmvc:6.1.8 - https://github.com/spring-projects/spring-framework)
|
* Spring Web MVC (org.springframework:spring-webmvc:6.2.4 - https://github.com/spring-projects/spring-framework)
|
||||||
* spring-boot (org.springframework.boot:spring-boot:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot (org.springframework.boot:spring-boot:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-actuator (org.springframework.boot:spring-boot-actuator:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-actuator (org.springframework.boot:spring-boot-actuator:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-actuator-autoconfigure (org.springframework.boot:spring-boot-actuator-autoconfigure:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-actuator-autoconfigure (org.springframework.boot:spring-boot-actuator-autoconfigure:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-autoconfigure (org.springframework.boot:spring-boot-autoconfigure:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-autoconfigure (org.springframework.boot:spring-boot-autoconfigure:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* Spring Boot Configuration Processor (org.springframework.boot:spring-boot-configuration-processor:2.0.0.RELEASE - https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-tools/spring-boot-configuration-processor)
|
* Spring Boot Configuration Processor (org.springframework.boot:spring-boot-configuration-processor:2.0.0.RELEASE - https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-tools/spring-boot-configuration-processor)
|
||||||
* spring-boot-starter (org.springframework.boot:spring-boot-starter:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter (org.springframework.boot:spring-boot-starter:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-actuator (org.springframework.boot:spring-boot-starter-actuator:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-actuator (org.springframework.boot:spring-boot-starter-actuator:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-aop (org.springframework.boot:spring-boot-starter-aop:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-aop (org.springframework.boot:spring-boot-starter-aop:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-cache (org.springframework.boot:spring-boot-starter-cache:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-cache (org.springframework.boot:spring-boot-starter-cache:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-data-rest (org.springframework.boot:spring-boot-starter-data-rest:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-data-rest (org.springframework.boot:spring-boot-starter-data-rest:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-json (org.springframework.boot:spring-boot-starter-json:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-json (org.springframework.boot:spring-boot-starter-json:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-log4j2 (org.springframework.boot:spring-boot-starter-log4j2:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-log4j2 (org.springframework.boot:spring-boot-starter-log4j2:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-security (org.springframework.boot:spring-boot-starter-security:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-security (org.springframework.boot:spring-boot-starter-security:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-test (org.springframework.boot:spring-boot-starter-test:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-test (org.springframework.boot:spring-boot-starter-test:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-tomcat (org.springframework.boot:spring-boot-starter-tomcat:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-tomcat (org.springframework.boot:spring-boot-starter-tomcat:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-starter-web (org.springframework.boot:spring-boot-starter-web:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-starter-web (org.springframework.boot:spring-boot-starter-web:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-test (org.springframework.boot:spring-boot-test:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-test (org.springframework.boot:spring-boot-test:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* spring-boot-test-autoconfigure (org.springframework.boot:spring-boot-test-autoconfigure:3.2.6 - https://spring.io/projects/spring-boot)
|
* spring-boot-test-autoconfigure (org.springframework.boot:spring-boot-test-autoconfigure:3.4.3 - https://spring.io/projects/spring-boot)
|
||||||
* Spring Data Core (org.springframework.data:spring-data-commons:3.2.6 - https://spring.io/projects/spring-data)
|
* Spring Data Core (org.springframework.data:spring-data-commons:3.4.3 - https://spring.io/projects/spring-data)
|
||||||
* Spring Data REST - Core (org.springframework.data:spring-data-rest-core:4.2.6 - https://www.spring.io/spring-data/spring-data-rest-parent/spring-data-rest-core)
|
* Spring Data REST - Core (org.springframework.data:spring-data-rest-core:4.4.3 - https://www.spring.io/spring-data/spring-data-rest-parent/spring-data-rest-core)
|
||||||
* Spring Data REST - WebMVC (org.springframework.data:spring-data-rest-webmvc:4.2.6 - https://www.spring.io/spring-data/spring-data-rest-parent/spring-data-rest-webmvc)
|
* Spring Data REST - WebMVC (org.springframework.data:spring-data-rest-webmvc:4.4.3 - https://www.spring.io/spring-data/spring-data-rest-parent/spring-data-rest-webmvc)
|
||||||
* Spring HATEOAS (org.springframework.hateoas:spring-hateoas:2.2.2 - https://github.com/spring-projects/spring-hateoas)
|
* Spring HATEOAS (org.springframework.hateoas:spring-hateoas:2.4.1 - https://github.com/spring-projects/spring-hateoas)
|
||||||
* Spring Plugin - Core (org.springframework.plugin:spring-plugin-core:3.0.0 - https://github.com/spring-projects/spring-plugin/spring-plugin-core)
|
* Spring Plugin - Core (org.springframework.plugin:spring-plugin-core:3.0.0 - https://github.com/spring-projects/spring-plugin/spring-plugin-core)
|
||||||
* spring-security-config (org.springframework.security:spring-security-config:6.2.4 - https://spring.io/projects/spring-security)
|
* spring-security-config (org.springframework.security:spring-security-config:6.4.3 - https://spring.io/projects/spring-security)
|
||||||
* spring-security-core (org.springframework.security:spring-security-core:6.2.4 - https://spring.io/projects/spring-security)
|
* spring-security-core (org.springframework.security:spring-security-core:6.4.4 - https://spring.io/projects/spring-security)
|
||||||
* spring-security-crypto (org.springframework.security:spring-security-crypto:6.2.4 - https://spring.io/projects/spring-security)
|
* spring-security-crypto (org.springframework.security:spring-security-crypto:6.4.4 - https://spring.io/projects/spring-security)
|
||||||
* spring-security-test (org.springframework.security:spring-security-test:6.2.4 - https://spring.io/projects/spring-security)
|
* spring-security-saml2-service-provider (org.springframework.security:spring-security-saml2-service-provider:6.4.4 - https://spring.io/projects/spring-security)
|
||||||
* spring-security-web (org.springframework.security:spring-security-web:6.2.4 - https://spring.io/projects/spring-security)
|
* spring-security-test (org.springframework.security:spring-security-test:6.4.4 - https://spring.io/projects/spring-security)
|
||||||
|
* spring-security-web (org.springframework.security:spring-security-web:6.4.4 - https://spring.io/projects/spring-security)
|
||||||
|
* thymeleaf (org.thymeleaf:thymeleaf:3.1.3.RELEASE - http://www.thymeleaf.org/thymeleaf-lib/thymeleaf)
|
||||||
|
* unbescape (org.unbescape:unbescape:1.1.6.RELEASE - http://www.unbescape.org)
|
||||||
* snappy-java (org.xerial.snappy:snappy-java:1.1.10.1 - https://github.com/xerial/snappy-java)
|
* snappy-java (org.xerial.snappy:snappy-java:1.1.10.1 - https://github.com/xerial/snappy-java)
|
||||||
* xml-matchers (org.xmlmatchers:xml-matchers:0.10 - http://code.google.com/p/xml-matchers/)
|
* xml-matchers (org.xmlmatchers:xml-matchers:0.10 - http://code.google.com/p/xml-matchers/)
|
||||||
* org.xmlunit:xmlunit-core (org.xmlunit:xmlunit-core:2.10.0 - https://www.xmlunit.org/)
|
* org.xmlunit:xmlunit-core (org.xmlunit:xmlunit-core:2.10.0 - https://www.xmlunit.org/)
|
||||||
* org.xmlunit:xmlunit-core (org.xmlunit:xmlunit-core:2.9.1 - https://www.xmlunit.org/)
|
* org.xmlunit:xmlunit-placeholders (org.xmlunit:xmlunit-placeholders:2.9.1 - https://www.xmlunit.org/xmlunit-placeholders/)
|
||||||
* org.xmlunit:xmlunit-placeholders (org.xmlunit:xmlunit-placeholders:2.8.0 - https://www.xmlunit.org/xmlunit-placeholders/)
|
* SnakeYAML (org.yaml:snakeyaml:2.3 - https://bitbucket.org/snakeyaml/snakeyaml)
|
||||||
* SnakeYAML (org.yaml:snakeyaml:2.2 - https://bitbucket.org/snakeyaml/snakeyaml)
|
|
||||||
* software.amazon.ion:ion-java (software.amazon.ion:ion-java:1.0.2 - https://github.com/amznlabs/ion-java/)
|
|
||||||
* Xerces2-j (xerces:xercesImpl:2.12.2 - https://xerces.apache.org/xerces2-j/)
|
* Xerces2-j (xerces:xercesImpl:2.12.2 - https://xerces.apache.org/xerces2-j/)
|
||||||
|
|
||||||
BSD License:
|
BSD License:
|
||||||
@@ -463,27 +488,32 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* JSONLD Java :: Core (com.github.jsonld-java:jsonld-java:0.13.4 - http://github.com/jsonld-java/jsonld-java/jsonld-java/)
|
* JSONLD Java :: Core (com.github.jsonld-java:jsonld-java:0.13.4 - http://github.com/jsonld-java/jsonld-java/jsonld-java/)
|
||||||
* curvesapi (com.github.virtuald:curvesapi:1.08 - https://github.com/virtuald/curvesapi)
|
* curvesapi (com.github.virtuald:curvesapi:1.08 - https://github.com/virtuald/curvesapi)
|
||||||
* Protocol Buffers [Core] (com.google.protobuf:protobuf-java:3.15.0 - https://developers.google.com/protocol-buffers/protobuf-java/)
|
* Protocol Buffers [Core] (com.google.protobuf:protobuf-java:3.15.0 - https://developers.google.com/protocol-buffers/protobuf-java/)
|
||||||
* Protocol Buffers [Core] (com.google.protobuf:protobuf-java:3.23.3 - https://developers.google.com/protocol-buffers/protobuf-java/)
|
* Protocol Buffers [Core] (com.google.protobuf:protobuf-java:3.24.3 - https://developers.google.com/protocol-buffers/protobuf-java/)
|
||||||
* JZlib (com.jcraft:jzlib:1.1.3 - http://www.jcraft.com/jzlib/)
|
* JZlib (com.jcraft:jzlib:1.1.3 - http://www.jcraft.com/jzlib/)
|
||||||
* dnsjava (dnsjava:dnsjava:2.1.9 - http://www.dnsjava.org)
|
* jmustache (com.samskivert:jmustache:1.15 - http://github.com/samskivert/jmustache)
|
||||||
|
* dnsjava (dnsjava:dnsjava:3.6.3 - https://github.com/dnsjava/dnsjava)
|
||||||
* jaxen (jaxen:jaxen:2.0.0 - http://www.cafeconleche.org/jaxen/jaxen)
|
* jaxen (jaxen:jaxen:2.0.0 - http://www.cafeconleche.org/jaxen/jaxen)
|
||||||
* ANTLR 4 Runtime (org.antlr:antlr4-runtime:4.13.1 - https://www.antlr.org/antlr4-runtime/)
|
* ANTLR 4 Runtime (org.antlr:antlr4-runtime:4.13.2 - https://www.antlr.org/antlr4-runtime/)
|
||||||
* commons-compiler (org.codehaus.janino:commons-compiler:3.1.8 - http://janino-compiler.github.io/commons-compiler/)
|
* commons-compiler (org.codehaus.janino:commons-compiler:3.1.8 - http://janino-compiler.github.io/commons-compiler/)
|
||||||
* janino (org.codehaus.janino:janino:3.1.8 - http://janino-compiler.github.io/janino/)
|
* janino (org.codehaus.janino:janino:3.1.8 - http://janino-compiler.github.io/janino/)
|
||||||
* Stax2 API (org.codehaus.woodstox:stax2-api:4.2.1 - http://github.com/FasterXML/stax2-api)
|
* Stax2 API (org.codehaus.woodstox:stax2-api:4.2.1 - http://github.com/FasterXML/stax2-api)
|
||||||
* Hamcrest Date (org.exparity:hamcrest-date:2.0.8 - https://github.com/exparity/hamcrest-date)
|
* Hamcrest Date (org.exparity:hamcrest-date:2.0.8 - https://github.com/exparity/hamcrest-date)
|
||||||
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* Hamcrest (org.hamcrest:hamcrest:2.2 - http://hamcrest.org/JavaHamcrest/)
|
* Hamcrest (org.hamcrest:hamcrest:2.2 - http://hamcrest.org/JavaHamcrest/)
|
||||||
* Hamcrest Core (org.hamcrest:hamcrest-core:2.2 - http://hamcrest.org/JavaHamcrest/)
|
* Hamcrest Core (org.hamcrest:hamcrest-core:2.2 - http://hamcrest.org/JavaHamcrest/)
|
||||||
* HdrHistogram (org.hdrhistogram:HdrHistogram:2.1.12 - http://hdrhistogram.github.io/HdrHistogram/)
|
* HdrHistogram (org.hdrhistogram:HdrHistogram:2.2.2 - http://hdrhistogram.github.io/HdrHistogram/)
|
||||||
* JBibTeX (org.jbibtex:jbibtex:1.0.20 - http://www.jbibtex.org)
|
* JBibTeX (org.jbibtex:jbibtex:1.0.20 - http://www.jbibtex.org)
|
||||||
* asm (org.ow2.asm:asm:8.0.1 - http://asm.ow2.io/)
|
* asm (org.ow2.asm:asm:8.0.1 - http://asm.ow2.io/)
|
||||||
* asm-analysis (org.ow2.asm:asm-analysis:8.0.1 - http://asm.ow2.io/)
|
* asm-analysis (org.ow2.asm:asm-analysis:8.0.1 - http://asm.ow2.io/)
|
||||||
* asm-commons (org.ow2.asm:asm-commons:8.0.1 - http://asm.ow2.io/)
|
* asm-commons (org.ow2.asm:asm-commons:8.0.1 - http://asm.ow2.io/)
|
||||||
* asm-tree (org.ow2.asm:asm-tree:8.0.1 - http://asm.ow2.io/)
|
* asm-tree (org.ow2.asm:asm-tree:8.0.1 - http://asm.ow2.io/)
|
||||||
* asm-util (org.ow2.asm:asm-util:7.1 - http://asm.ow2.org/)
|
* ASM Util (org.ow2.asm:asm-util:5.0.3 - http://asm.objectweb.org/asm-util/)
|
||||||
* PostgreSQL JDBC Driver (org.postgresql:postgresql:42.7.3 - https://jdbc.postgresql.org)
|
* PostgreSQL JDBC Driver (org.postgresql:postgresql:42.7.5 - https://jdbc.postgresql.org)
|
||||||
* Reflections (org.reflections:reflections:0.9.12 - http://github.com/ronmamo/reflections)
|
* Reflections (org.reflections:reflections:0.9.12 - http://github.com/ronmamo/reflections)
|
||||||
* JMatIO (org.tallison:jmatio:1.5 - https://github.com/tballison/jmatio)
|
* JMatIO (org.tallison:jmatio:1.5 - https://github.com/tballison/jmatio)
|
||||||
|
* XZ for Java (org.tukaani:xz:1.10 - https://tukaani.org/xz/java.html)
|
||||||
* XMLUnit for Java (xmlunit:xmlunit:1.3 - http://xmlunit.sourceforge.net/)
|
* XMLUnit for Java (xmlunit:xmlunit:1.3 - http://xmlunit.sourceforge.net/)
|
||||||
|
|
||||||
CC0:
|
CC0:
|
||||||
@@ -497,7 +527,7 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* Old JAXB Runtime (com.sun.xml.bind:jaxb-impl:2.3.1 - http://jaxb.java.net/jaxb-bundles/jaxb-impl)
|
* Old JAXB Runtime (com.sun.xml.bind:jaxb-impl:2.3.1 - http://jaxb.java.net/jaxb-bundles/jaxb-impl)
|
||||||
* Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca)
|
* Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca)
|
||||||
* Jakarta Mail API (jakarta.mail:jakarta.mail-api:2.1.3 - https://projects.eclipse.org/projects/ee4j/jakarta.mail-api)
|
* Jakarta Mail API (jakarta.mail:jakarta.mail-api:2.1.3 - https://projects.eclipse.org/projects/ee4j/jakarta.mail-api)
|
||||||
* Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:6.0.0 - https://projects.eclipse.org/projects/ee4j.servlet)
|
* Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:6.1.0 - https://projects.eclipse.org/projects/ee4j.servlet)
|
||||||
* jakarta.transaction API (jakarta.transaction:jakarta.transaction-api:2.0.1 - https://projects.eclipse.org/projects/ee4j.jta)
|
* jakarta.transaction API (jakarta.transaction:jakarta.transaction-api:2.0.1 - https://projects.eclipse.org/projects/ee4j.jta)
|
||||||
* JavaBeans Activation Framework API jar (javax.activation:javax.activation-api:1.2.0 - http://java.net/all/javax.activation-api/)
|
* JavaBeans Activation Framework API jar (javax.activation:javax.activation-api:1.2.0 - http://java.net/all/javax.activation-api/)
|
||||||
* javax.annotation API (javax.annotation:javax.annotation-api:1.3 - http://jcp.org/en/jsr/detail?id=250)
|
* javax.annotation API (javax.annotation:javax.annotation-api:1.3 - http://jcp.org/en/jsr/detail?id=250)
|
||||||
@@ -506,13 +536,13 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* jaxb-api (javax.xml.bind:jaxb-api:2.3.1 - https://github.com/javaee/jaxb-spec/jaxb-api)
|
* jaxb-api (javax.xml.bind:jaxb-api:2.3.1 - https://github.com/javaee/jaxb-spec/jaxb-api)
|
||||||
* JHighlight (org.codelibs:jhighlight:1.1.0 - https://github.com/codelibs/jhighlight)
|
* JHighlight (org.codelibs:jhighlight:1.1.0 - https://github.com/codelibs/jhighlight)
|
||||||
* Angus Mail default provider (org.eclipse.angus:jakarta.mail:2.0.3 - http://eclipse-ee4j.github.io/angus-mail/jakarta.mail)
|
* Angus Mail default provider (org.eclipse.angus:jakarta.mail:2.0.3 - http://eclipse-ee4j.github.io/angus-mail/jakarta.mail)
|
||||||
* HK2 API module (org.glassfish.hk2:hk2-api:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api)
|
* HK2 API module (org.glassfish.hk2:hk2-api:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api)
|
||||||
* ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
* ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
||||||
* HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils)
|
* HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils)
|
||||||
* OSGi resource locator (org.glassfish.hk2:osgi-resource-locator:1.0.3 - https://projects.eclipse.org/projects/ee4j/osgi-resource-locator)
|
* OSGi resource locator (org.glassfish.hk2:osgi-resource-locator:1.0.3 - https://projects.eclipse.org/projects/ee4j/osgi-resource-locator)
|
||||||
* aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged)
|
* aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged)
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
|
|
||||||
Cordra (Version 2) License Agreement:
|
Cordra (Version 2) License Agreement:
|
||||||
@@ -536,8 +566,8 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* JAXB Core (org.glassfish.jaxb:jaxb-core:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
* JAXB Core (org.glassfish.jaxb:jaxb-core:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
||||||
* JAXB Runtime (org.glassfish.jaxb:jaxb-runtime:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
* JAXB Runtime (org.glassfish.jaxb:jaxb-runtime:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
||||||
* TXW2 Runtime (org.glassfish.jaxb:txw2:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
* TXW2 Runtime (org.glassfish.jaxb:txw2:4.0.5 - https://eclipse-ee4j.github.io/jaxb-ri/)
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* MIME streaming extension (org.jvnet.mimepull:mimepull:1.9.15 - https://github.com/eclipse-ee4j/metro-mimepull)
|
* MIME streaming extension (org.jvnet.mimepull:mimepull:1.9.15 - https://github.com/eclipse-ee4j/metro-mimepull)
|
||||||
* org.locationtech.jts:jts-core (org.locationtech.jts:jts-core:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-core)
|
* org.locationtech.jts:jts-core (org.locationtech.jts:jts-core:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-core)
|
||||||
@@ -546,16 +576,16 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
Eclipse Public License:
|
Eclipse Public License:
|
||||||
|
|
||||||
* System Rules (com.github.stefanbirkner:system-rules:1.19.0 - http://stefanbirkner.github.io/system-rules/)
|
* System Rules (com.github.stefanbirkner:system-rules:1.19.0 - http://stefanbirkner.github.io/system-rules/)
|
||||||
* H2 Database Engine (com.h2database:h2:2.2.224 - https://h2database.com)
|
* H2 Database Engine (com.h2database:h2:2.3.232 - https://h2database.com)
|
||||||
* Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca)
|
* Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca)
|
||||||
* Jakarta Expression Language API (jakarta.el:jakarta.el-api:5.0.1 - https://projects.eclipse.org/projects/ee4j.el)
|
* Jakarta Expression Language API (jakarta.el:jakarta.el-api:5.0.1 - https://projects.eclipse.org/projects/ee4j.el)
|
||||||
* Jakarta Mail API (jakarta.mail:jakarta.mail-api:2.1.3 - https://projects.eclipse.org/projects/ee4j/jakarta.mail-api)
|
* Jakarta Mail API (jakarta.mail:jakarta.mail-api:2.1.3 - https://projects.eclipse.org/projects/ee4j/jakarta.mail-api)
|
||||||
* Jakarta Persistence API (jakarta.persistence:jakarta.persistence-api:3.1.0 - https://github.com/eclipse-ee4j/jpa-api)
|
* Jakarta Persistence API (jakarta.persistence:jakarta.persistence-api:3.1.0 - https://github.com/eclipse-ee4j/jpa-api)
|
||||||
* Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:6.0.0 - https://projects.eclipse.org/projects/ee4j.servlet)
|
* Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:6.1.0 - https://projects.eclipse.org/projects/ee4j.servlet)
|
||||||
* jakarta.transaction API (jakarta.transaction:jakarta.transaction-api:2.0.1 - https://projects.eclipse.org/projects/ee4j.jta)
|
* jakarta.transaction API (jakarta.transaction:jakarta.transaction-api:2.0.1 - https://projects.eclipse.org/projects/ee4j.jta)
|
||||||
* Jakarta RESTful WS API (jakarta.ws.rs:jakarta.ws.rs-api:3.1.0 - https://github.com/eclipse-ee4j/jaxrs-api)
|
* Jakarta RESTful WS API (jakarta.ws.rs:jakarta.ws.rs-api:3.1.0 - https://github.com/eclipse-ee4j/jaxrs-api)
|
||||||
* JUnit (junit:junit:4.13.2 - http://junit.org)
|
* JUnit (junit:junit:4.13.2 - http://junit.org)
|
||||||
* AspectJ Weaver (org.aspectj:aspectjweaver:1.9.22 - https://www.eclipse.org/aspectj/)
|
* AspectJ Weaver (org.aspectj:aspectjweaver:1.9.22.1 - https://www.eclipse.org/aspectj/)
|
||||||
* Angus Mail default provider (org.eclipse.angus:jakarta.mail:2.0.3 - http://eclipse-ee4j.github.io/angus-mail/jakarta.mail)
|
* Angus Mail default provider (org.eclipse.angus:jakarta.mail:2.0.3 - http://eclipse-ee4j.github.io/angus-mail/jakarta.mail)
|
||||||
* Jetty :: Apache JSP Implementation (org.eclipse.jetty:apache-jsp:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Apache JSP Implementation (org.eclipse.jetty:apache-jsp:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Apache :: JSTL module (org.eclipse.jetty:apache-jstl:9.4.15.v20190215 - http://tomcat.apache.org/taglibs/standard/)
|
* Apache :: JSTL module (org.eclipse.jetty:apache-jstl:9.4.15.v20190215 - http://tomcat.apache.org/taglibs/standard/)
|
||||||
@@ -569,65 +599,72 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* Jetty :: Asynchronous HTTP Client (org.eclipse.jetty:jetty-client:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-client)
|
* Jetty :: Asynchronous HTTP Client (org.eclipse.jetty:jetty-client:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-client)
|
||||||
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-continuation)
|
* Jetty :: Continuation (org.eclipse.jetty:jetty-continuation:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-continuation)
|
||||||
* Jetty :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-deploy)
|
* Jetty :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.57.v20241219 - https://jetty.org/jetty-deploy/)
|
||||||
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-http)
|
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.57.v20241219 - https://jetty.org/jetty-http/)
|
||||||
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-io)
|
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.57.v20241219 - https://jetty.org/jetty-io/)
|
||||||
* Jetty :: JMX Management (org.eclipse.jetty:jetty-jmx:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-jmx)
|
* Jetty :: JMX Management (org.eclipse.jetty:jetty-jmx:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-jmx)
|
||||||
* Jetty :: JNDI Naming (org.eclipse.jetty:jetty-jndi:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: JNDI Naming (org.eclipse.jetty:jetty-jndi:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Plus (org.eclipse.jetty:jetty-plus:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Plus (org.eclipse.jetty:jetty-plus:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Rewrite Handler (org.eclipse.jetty:jetty-rewrite:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-rewrite)
|
* Jetty :: Rewrite Handler (org.eclipse.jetty:jetty-rewrite:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-rewrite)
|
||||||
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-security)
|
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-security)
|
||||||
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-security)
|
* Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.57.v20241219 - https://jetty.org/jetty-security/)
|
||||||
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-server)
|
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.57.v20241219 - https://jetty.org/jetty-server/)
|
||||||
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-servlet)
|
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.57.v20241219 - https://jetty.org/jetty-servlet/)
|
||||||
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.15.v20190215 - http://www.eclipse.org/jetty)
|
||||||
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-servlets)
|
* Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-servlets)
|
||||||
* Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util)
|
* Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.57.v20241219 - https://jetty.org/jetty-util/)
|
||||||
* Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util-ajax)
|
* Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.57.v20241219 - https://jetty.org/jetty-util-ajax/)
|
||||||
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-webapp)
|
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.57.v20241219 - https://jetty.org/jetty-webapp/)
|
||||||
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-xml)
|
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.53.v20231009 - https://eclipse.org/jetty/jetty-xml)
|
||||||
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-xml)
|
* Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.57.v20241219 - https://jetty.org/jetty-xml/)
|
||||||
* Jetty :: ALPN :: API (org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715 - http://www.eclipse.org/jetty/alpn-api)
|
* Jetty :: ALPN :: API (org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715 - http://www.eclipse.org/jetty/alpn-api)
|
||||||
* Jetty :: HTTP2 :: Client (org.eclipse.jetty.http2:http2-client:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-client)
|
* Jetty :: HTTP2 :: Client (org.eclipse.jetty.http2:http2-client:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-client)
|
||||||
* Jetty :: HTTP2 :: Common (org.eclipse.jetty.http2:http2-common:9.4.54.v20240208 - https://eclipse.org/jetty/http2-parent/http2-common)
|
* Jetty :: HTTP2 :: Common (org.eclipse.jetty.http2:http2-common:9.4.57.v20241219 - https://jetty.org/http2-parent/http2-common/)
|
||||||
* Jetty :: HTTP2 :: HPACK (org.eclipse.jetty.http2:http2-hpack:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-hpack)
|
* Jetty :: HTTP2 :: HPACK (org.eclipse.jetty.http2:http2-hpack:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-hpack)
|
||||||
* Jetty :: HTTP2 :: HTTP Client Transport (org.eclipse.jetty.http2:http2-http-client-transport:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-http-client-transport)
|
* Jetty :: HTTP2 :: HTTP Client Transport (org.eclipse.jetty.http2:http2-http-client-transport:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-http-client-transport)
|
||||||
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.15.v20190215 - https://eclipse.org/jetty/http2-parent/http2-server)
|
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.15.v20190215 - https://eclipse.org/jetty/http2-parent/http2-server)
|
||||||
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-server)
|
* Jetty :: HTTP2 :: Server (org.eclipse.jetty.http2:http2-server:9.4.53.v20231009 - https://eclipse.org/jetty/http2-parent/http2-server)
|
||||||
* Jetty :: Schemas (org.eclipse.jetty.toolchain:jetty-schemas:3.1.2 - https://eclipse.org/jetty/jetty-schemas)
|
* Jetty :: Schemas (org.eclipse.jetty.toolchain:jetty-schemas:3.1.2 - https://eclipse.org/jetty/jetty-schemas)
|
||||||
* JSON-P Default Provider (org.glassfish:jakarta.json:2.0.1 - https://github.com/eclipse-ee4j/jsonp)
|
* JSON-P Default Provider (org.glassfish:jakarta.json:2.0.1 - https://github.com/eclipse-ee4j/jsonp)
|
||||||
* HK2 API module (org.glassfish.hk2:hk2-api:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api)
|
* HK2 API module (org.glassfish.hk2:hk2-api:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api)
|
||||||
* ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
* ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
||||||
* HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils)
|
* HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils)
|
||||||
* OSGi resource locator (org.glassfish.hk2:osgi-resource-locator:1.0.3 - https://projects.eclipse.org/projects/ee4j/osgi-resource-locator)
|
* OSGi resource locator (org.glassfish.hk2:osgi-resource-locator:1.0.3 - https://projects.eclipse.org/projects/ee4j/osgi-resource-locator)
|
||||||
* aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged)
|
* aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.6 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged)
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* org.locationtech.jts:jts-core (org.locationtech.jts:jts-core:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-core)
|
* org.locationtech.jts:jts-core (org.locationtech.jts:jts-core:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-core)
|
||||||
* org.locationtech.jts.io:jts-io-common (org.locationtech.jts.io:jts-io-common:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-io/jts-io-common)
|
* org.locationtech.jts.io:jts-io-common (org.locationtech.jts.io:jts-io-common:1.19.0 - https://www.locationtech.org/projects/technology.jts/jts-modules/jts-io/jts-io-common)
|
||||||
* Jetty Server (org.mortbay.jetty:jetty:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/modules/jetty)
|
|
||||||
* Jetty Servlet Tester (org.mortbay.jetty:jetty-servlet-tester:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/jetty-servlet-tester)
|
GENERAL PUBLIC LICENSE, version 3 (GPL-3.0):
|
||||||
* Jetty Utilities (org.mortbay.jetty:jetty-util:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/jetty-util)
|
|
||||||
|
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.5.0 - https://github.com/albfernandez/juniversalchardet)
|
||||||
|
|
||||||
GNU Lesser General Public License (LGPL):
|
GNU Lesser General Public License (LGPL):
|
||||||
|
|
||||||
|
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.5.0 - https://github.com/albfernandez/juniversalchardet)
|
||||||
* btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
|
* btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
|
||||||
* jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
|
* jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
|
||||||
* jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
|
* jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
|
||||||
|
* json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
|
||||||
* json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
|
* json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
|
||||||
* json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
|
* json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
|
||||||
* msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
|
* msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
|
||||||
* uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
|
* uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
|
||||||
|
* openpdf (com.github.librepdf:openpdf:2.0.3 - https://github.com/LibrePDF/OpenPDF/openpdf)
|
||||||
* FindBugs-Annotations (com.google.code.findbugs:annotations:3.0.1u2 - http://findbugs.sourceforge.net/)
|
* FindBugs-Annotations (com.google.code.findbugs:annotations:3.0.1u2 - http://findbugs.sourceforge.net/)
|
||||||
* JHighlight (org.codelibs:jhighlight:1.1.0 - https://github.com/codelibs/jhighlight)
|
* JHighlight (org.codelibs:jhighlight:1.1.0 - https://github.com/codelibs/jhighlight)
|
||||||
|
* Cryptacular Library (org.cryptacular:cryptacular:1.2.5 - http://www.cryptacular.org)
|
||||||
* Hibernate Commons Annotations (org.hibernate.common:hibernate-commons-annotations:6.0.6.Final - http://hibernate.org)
|
* Hibernate Commons Annotations (org.hibernate.common:hibernate-commons-annotations:6.0.6.Final - http://hibernate.org)
|
||||||
* Hibernate ORM - hibernate-core (org.hibernate.orm:hibernate-core:6.4.8.Final - https://hibernate.org/orm)
|
* Hibernate ORM - hibernate-core (org.hibernate.orm:hibernate-core:6.4.8.Final - https://hibernate.org/orm)
|
||||||
* Hibernate ORM - hibernate-jcache (org.hibernate.orm:hibernate-jcache:6.4.8.Final - https://hibernate.org/orm)
|
* Hibernate ORM - hibernate-jcache (org.hibernate.orm:hibernate-jcache:6.4.8.Final - https://hibernate.org/orm)
|
||||||
* Hibernate ORM - hibernate-jpamodelgen (org.hibernate.orm:hibernate-jpamodelgen:6.4.8.Final - https://hibernate.org/orm)
|
* Hibernate ORM - hibernate-jpamodelgen (org.hibernate.orm:hibernate-jpamodelgen:6.4.8.Final - https://hibernate.org/orm)
|
||||||
* im4java (org.im4java:im4java:1.4.0 - http://sourceforge.net/projects/im4java/)
|
* im4java (org.im4java:im4java:1.4.0 - http://sourceforge.net/projects/im4java/)
|
||||||
* Javassist (org.javassist:javassist:3.29.2-GA - http://www.javassist.org/)
|
* Javassist (org.javassist:javassist:3.30.2-GA - https://www.javassist.org/)
|
||||||
|
* Flying Saucer Core Renderer (org.xhtmlrenderer:flying-saucer-core:9.11.4 - http://code.google.com/p/flying-saucer/flying-saucer-core/)
|
||||||
|
* Flying Saucer PDF Rendering (org.xhtmlrenderer:flying-saucer-pdf:9.11.4 - http://code.google.com/p/flying-saucer/flying-saucer-pdf/)
|
||||||
* XOM (xom:xom:1.3.9 - https://xom.nu)
|
* XOM (xom:xom:1.3.9 - https://xom.nu)
|
||||||
|
|
||||||
Go License:
|
Go License:
|
||||||
@@ -648,25 +685,22 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* better-files (com.github.pathikrit:better-files_2.13:3.9.1 - https://github.com/pathikrit/better-files)
|
* better-files (com.github.pathikrit:better-files_2.13:3.9.1 - https://github.com/pathikrit/better-files)
|
||||||
* Java SemVer (com.github.zafarkhaja:java-semver:0.9.0 - https://github.com/zafarkhaja/jsemver)
|
* Java SemVer (com.github.zafarkhaja:java-semver:0.9.0 - https://github.com/zafarkhaja/jsemver)
|
||||||
* dd-plist (com.googlecode.plist:dd-plist:1.28 - http://www.github.com/3breadt/dd-plist)
|
* dd-plist (com.googlecode.plist:dd-plist:1.28 - http://www.github.com/3breadt/dd-plist)
|
||||||
* DigitalCollections: IIIF API Library (de.digitalcollections.iiif:iiif-apis:0.3.10 - https://github.com/dbmdz/iiif-apis)
|
* DigitalCollections: IIIF API Library (de.digitalcollections.iiif:iiif-apis:0.3.11 - https://github.com/dbmdz/iiif-apis)
|
||||||
* s3mock (io.findify:s3mock_2.13:0.2.6 - https://github.com/findify/s3mock)
|
* s3mock (io.findify:s3mock_2.13:0.2.6 - https://github.com/findify/s3mock)
|
||||||
* ClassGraph (io.github.classgraph:classgraph:4.8.165 - https://github.com/classgraph/classgraph)
|
* ClassGraph (io.github.classgraph:classgraph:4.8.165 - https://github.com/classgraph/classgraph)
|
||||||
* JOpt Simple (net.sf.jopt-simple:jopt-simple:5.0.4 - http://jopt-simple.github.io/jopt-simple)
|
* JOpt Simple (net.sf.jopt-simple:jopt-simple:5.0.4 - http://jopt-simple.github.io/jopt-simple)
|
||||||
* Bouncy Castle S/MIME API (org.bouncycastle:bcmail-jdk18on:1.77 - https://www.bouncycastle.org/java.html)
|
* Bouncy Castle JavaMail S/MIME APIs (org.bouncycastle:bcmail-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||||
* Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk15on:1.67 - http://www.bouncycastle.org/java.html)
|
* Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||||
* Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk18on:1.78.1 - https://www.bouncycastle.org/java.html)
|
* Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||||
* Bouncy Castle Provider (org.bouncycastle:bcprov-jdk15on:1.67 - http://www.bouncycastle.org/java.html)
|
* Bouncy Castle ASN.1 Extension and Utility APIs (org.bouncycastle:bcutil-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||||
* Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.78.1 - https://www.bouncycastle.org/java.html)
|
|
||||||
* Bouncy Castle ASN.1 Extension and Utility APIs (org.bouncycastle:bcutil-jdk18on:1.78.1 - https://www.bouncycastle.org/java.html)
|
|
||||||
* org.brotli:dec (org.brotli:dec:0.1.2 - http://brotli.org/dec)
|
* org.brotli:dec (org.brotli:dec:0.1.2 - http://brotli.org/dec)
|
||||||
* Checker Qual (org.checkerframework:checker-qual:3.31.0 - https://checkerframework.org)
|
* Checker Qual (org.checkerframework:checker-qual:3.49.0 - https://checkerframework.org/)
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* mockito-core (org.mockito:mockito-core:3.12.4 - https://github.com/mockito/mockito)
|
* mockito-core (org.mockito:mockito-core:3.12.4 - https://github.com/mockito/mockito)
|
||||||
* mockito-inline (org.mockito:mockito-inline:3.12.4 - https://github.com/mockito/mockito)
|
* mockito-inline (org.mockito:mockito-inline:3.12.4 - https://github.com/mockito/mockito)
|
||||||
* SLF4J API Module (org.slf4j:slf4j-api:2.0.11 - http://www.slf4j.org)
|
* SLF4J API Module (org.slf4j:slf4j-api:2.0.16 - http://www.slf4j.org)
|
||||||
* SLF4J Extensions Module (org.slf4j:slf4j-ext:1.7.28 - http://www.slf4j.org)
|
|
||||||
* HAL Browser (org.webjars:hal-browser:ad9b865 - http://webjars.org)
|
* HAL Browser (org.webjars:hal-browser:ad9b865 - http://webjars.org)
|
||||||
* toastr (org.webjars.bowergithub.codeseven:toastr:2.1.4 - http://webjars.org)
|
* toastr (org.webjars.bowergithub.codeseven:toastr:2.1.4 - http://webjars.org)
|
||||||
* backbone (org.webjars.bowergithub.jashkenas:backbone:1.4.1 - https://www.webjars.org)
|
* backbone (org.webjars.bowergithub.jashkenas:backbone:1.4.1 - https://www.webjars.org)
|
||||||
@@ -674,28 +708,29 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
* jquery (org.webjars.bowergithub.jquery:jquery-dist:3.7.1 - https://www.webjars.org)
|
* jquery (org.webjars.bowergithub.jquery:jquery-dist:3.7.1 - https://www.webjars.org)
|
||||||
* urijs (org.webjars.bowergithub.medialize:uri.js:1.19.11 - https://www.webjars.org)
|
* urijs (org.webjars.bowergithub.medialize:uri.js:1.19.11 - https://www.webjars.org)
|
||||||
* bootstrap (org.webjars.bowergithub.twbs:bootstrap:4.6.2 - https://www.webjars.org)
|
* bootstrap (org.webjars.bowergithub.twbs:bootstrap:4.6.2 - https://www.webjars.org)
|
||||||
* core-js (org.webjars.npm:core-js:3.37.1 - https://www.webjars.org)
|
* core-js (org.webjars.npm:core-js:3.41.0 - https://www.webjars.org)
|
||||||
* @json-editor/json-editor (org.webjars.npm:json-editor__json-editor:2.6.1 - https://www.webjars.org)
|
* @json-editor/json-editor (org.webjars.npm:json-editor__json-editor:2.15.1 - https://www.webjars.org)
|
||||||
|
|
||||||
Mozilla Public License:
|
Mozilla Public License:
|
||||||
|
|
||||||
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.4.0 - https://github.com/albfernandez/juniversalchardet)
|
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.5.0 - https://github.com/albfernandez/juniversalchardet)
|
||||||
* H2 Database Engine (com.h2database:h2:2.2.224 - https://h2database.com)
|
* openpdf (com.github.librepdf:openpdf:2.0.3 - https://github.com/LibrePDF/OpenPDF/openpdf)
|
||||||
|
* H2 Database Engine (com.h2database:h2:2.3.232 - https://h2database.com)
|
||||||
* Saxon-HE (net.sf.saxon:Saxon-HE:9.8.0-14 - http://www.saxonica.com/)
|
* Saxon-HE (net.sf.saxon:Saxon-HE:9.8.0-14 - http://www.saxonica.com/)
|
||||||
* Javassist (org.javassist:javassist:3.29.2-GA - http://www.javassist.org/)
|
* Javassist (org.javassist:javassist:3.30.2-GA - https://www.javassist.org/)
|
||||||
* Mozilla Rhino (org.mozilla:rhino:1.7.7.2 - https://developer.mozilla.org/en/Rhino)
|
* Mozilla Rhino (org.mozilla:rhino:1.7.7.2 - https://developer.mozilla.org/en/Rhino)
|
||||||
|
|
||||||
Public Domain:
|
Public Domain:
|
||||||
|
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* AOP alliance (aopalliance:aopalliance:1.0 - http://aopalliance.sourceforge.net)
|
||||||
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-core-common (org.glassfish.jersey.core:jersey-common:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common)
|
||||||
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
* HdrHistogram (org.hdrhistogram:HdrHistogram:2.1.12 - http://hdrhistogram.github.io/HdrHistogram/)
|
* HdrHistogram (org.hdrhistogram:HdrHistogram:2.2.2 - http://hdrhistogram.github.io/HdrHistogram/)
|
||||||
* JSON in Java (org.json:json:20231013 - https://github.com/douglascrockford/JSON-java)
|
* JSON in Java (org.json:json:20231013 - https://github.com/douglascrockford/JSON-java)
|
||||||
* LatencyUtils (org.latencyutils:LatencyUtils:2.0.3 - http://latencyutils.github.io/LatencyUtils/)
|
* LatencyUtils (org.latencyutils:LatencyUtils:2.0.3 - http://latencyutils.github.io/LatencyUtils/)
|
||||||
* Reflections (org.reflections:reflections:0.9.12 - http://github.com/ronmamo/reflections)
|
* Reflections (org.reflections:reflections:0.9.12 - http://github.com/ronmamo/reflections)
|
||||||
* XZ for Java (org.tukaani:xz:1.9 - https://tukaani.org/xz/java.html)
|
|
||||||
|
|
||||||
UnRar License:
|
UnRar License:
|
||||||
|
|
||||||
@@ -703,16 +738,16 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
|||||||
|
|
||||||
Unicode/ICU License:
|
Unicode/ICU License:
|
||||||
|
|
||||||
* ICU4J (com.ibm.icu:icu4j:62.1 - http://icu-project.org/)
|
* ICU4J (com.ibm.icu:icu4j:62.2 - http://icu-project.org/)
|
||||||
|
|
||||||
W3C license:
|
W3C license:
|
||||||
|
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
|
|
||||||
jQuery license:
|
jQuery license:
|
||||||
|
|
||||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client)
|
||||||
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
* jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.10 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||||
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
* jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.1.3 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart)
|
||||||
|
@@ -7,4 +7,5 @@
|
|||||||
<!-- TODO: We should have these turned on. But, currently there's a known bug with indentation checks
|
<!-- TODO: We should have these turned on. But, currently there's a known bug with indentation checks
|
||||||
on JMockIt Expectations blocks and similar. See https://github.com/checkstyle/checkstyle/issues/3739 -->
|
on JMockIt Expectations blocks and similar. See https://github.com/checkstyle/checkstyle/issues/3739 -->
|
||||||
<suppress checks="Indentation" files="src[/\\]test[/\\]java"/>
|
<suppress checks="Indentation" files="src[/\\]test[/\\]java"/>
|
||||||
|
<suppress checks="Regexp" files="DSpaceHttpClientFactory\.java"/>
|
||||||
</suppressions>
|
</suppressions>
|
||||||
|
@@ -136,5 +136,22 @@ For more information on CheckStyle configurations below, see: http://checkstyle.
|
|||||||
<module name="OneStatementPerLine"/>
|
<module name="OneStatementPerLine"/>
|
||||||
<!-- Require that "catch" statements are not empty (must at least contain a comment) -->
|
<!-- Require that "catch" statements are not empty (must at least contain a comment) -->
|
||||||
<module name="EmptyCatchBlock"/>
|
<module name="EmptyCatchBlock"/>
|
||||||
|
|
||||||
|
<!-- Require to use DSpaceHttpClientFactory.getClient() statement instead of creating directly the client -->
|
||||||
|
<module name="Regexp">
|
||||||
|
<property name="format" value="HttpClientBuilder\.create\s*\(\s*\)" />
|
||||||
|
<property name="message" value="Use DSpaceHttpClientFactory.getClient() instead of HttpClientBuilder.create()" />
|
||||||
|
<property name="illegalPattern" value="true"/>
|
||||||
|
<property name="ignoreComments" value="true"/>
|
||||||
|
</module>
|
||||||
|
<!-- Require to use DSpaceHttpClientFactory.getClient() statement instead of creating directly the client -->
|
||||||
|
<module name="Regexp">
|
||||||
|
<property name="format" value="HttpClients\.createDefault\s*\(\s*\)" />
|
||||||
|
<property name="message" value="Use DSpaceHttpClientFactory.getClient() instead of HttpClients.createDefault()" />
|
||||||
|
<property name="illegalPattern" value="true"/>
|
||||||
|
<property name="ignoreComments" value="true"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
|
||||||
</module>
|
</module>
|
||||||
</module>
|
</module>
|
||||||
|
@@ -93,7 +93,7 @@ services:
|
|||||||
additional_contexts:
|
additional_contexts:
|
||||||
solrconfigs: ./dspace/solr/
|
solrconfigs: ./dspace/solr/
|
||||||
args:
|
args:
|
||||||
SOLR_VERSION: "${SOLR_VER:-8.11}"
|
SOLR_VERSION: "${SOLR_VER:-9.8}"
|
||||||
networks:
|
networks:
|
||||||
dspacenet:
|
dspacenet:
|
||||||
ports:
|
ports:
|
||||||
@@ -105,10 +105,15 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
# Keep Solr data directory between reboots
|
# Keep Solr data directory between reboots
|
||||||
- solr_data:/var/solr/data
|
- solr_data:/var/solr/data
|
||||||
|
# NOTE: We are not running Solr as "root", but we need root permissions to copy our cores to the mounted
|
||||||
|
# /var/solr/data directory. Then we start Solr as the "solr" user.
|
||||||
|
user: root
|
||||||
# Initialize all DSpace Solr cores then start Solr:
|
# Initialize all DSpace Solr cores then start Solr:
|
||||||
# * First, run precreate-core to create the core (if it doesn't yet exist). If exists already, this is a no-op
|
# * First, run precreate-core to create the core (if it doesn't yet exist). If exists already, this is a no-op
|
||||||
# * Second, copy configsets to this core:
|
# * Second, copy configsets to this core:
|
||||||
# Updates to Solr configs require the container to be rebuilt/restarted: `docker compose -p d7 up -d --build dspacesolr`
|
# Updates to Solr configs require the container to be rebuilt/restarted: `docker compose -p d7 up -d --build dspacesolr`
|
||||||
|
# * Third, ensure all new folders are owned by "solr" user
|
||||||
|
# * Finally, start Solr as the "solr" user via the provided solr-foreground script
|
||||||
entrypoint:
|
entrypoint:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- '-c'
|
- '-c'
|
||||||
@@ -126,7 +131,8 @@ services:
|
|||||||
cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent
|
cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent
|
||||||
precreate-core suggestion /opt/solr/server/solr/configsets/suggestion
|
precreate-core suggestion /opt/solr/server/solr/configsets/suggestion
|
||||||
cp -r /opt/solr/server/solr/configsets/suggestion/* suggestion
|
cp -r /opt/solr/server/solr/configsets/suggestion/* suggestion
|
||||||
exec solr -f
|
chown -R solr:solr /var/solr
|
||||||
|
runuser -u solr -- solr-foreground
|
||||||
volumes:
|
volumes:
|
||||||
assetstore:
|
assetstore:
|
||||||
pgdata:
|
pgdata:
|
||||||
|
@@ -177,7 +177,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>jaxb2-maven-plugin</artifactId>
|
<artifactId>jaxb2-maven-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>workflow-curation</id>
|
<id>workflow-curation</id>
|
||||||
@@ -500,10 +500,6 @@
|
|||||||
<groupId>jakarta.annotation</groupId>
|
<groupId>jakarta.annotation</groupId>
|
||||||
<artifactId>jakarta.annotation-api</artifactId>
|
<artifactId>jakarta.annotation-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>jakarta.el</groupId>
|
|
||||||
<artifactId>jakarta.el-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jaxen</groupId>
|
<groupId>jaxen</groupId>
|
||||||
<artifactId>jaxen</artifactId>
|
<artifactId>jaxen</artifactId>
|
||||||
@@ -653,11 +649,18 @@
|
|||||||
<version>1.1.1</version>
|
<version>1.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- guava is needed by OAuth, Guice, Mockserver, ORCID, s3mock, Solr, JClouds -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Gson is needed by JENA, borker-client, OAuth, Handle and JClouds -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.postgresql</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
@@ -731,7 +734,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.amazonaws</groupId>
|
<groupId>com.amazonaws</groupId>
|
||||||
<artifactId>aws-java-sdk-s3</artifactId>
|
<artifactId>aws-java-sdk-s3</artifactId>
|
||||||
<version>1.12.781</version>
|
<version>1.12.783</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- TODO: This may need to be replaced with the "orcid-model" artifact once this ticket is resolved:
|
<!-- TODO: This may need to be replaced with the "orcid-model" artifact once this ticket is resolved:
|
||||||
@@ -767,11 +770,12 @@
|
|||||||
<version>1.19.0</version>
|
<version>1.19.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Used for Solr core export/import -->
|
<!-- Used for Solr core export/import -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.opencsv</groupId>
|
<groupId>com.opencsv</groupId>
|
||||||
<artifactId>opencsv</artifactId>
|
<artifactId>opencsv</artifactId>
|
||||||
<version>5.10</version>
|
<version>5.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Email templating -->
|
<!-- Email templating -->
|
||||||
@@ -860,6 +864,55 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JClouds Assetstorage Support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${jclouds.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.sun.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-impl</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.annotation</groupId>
|
||||||
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta.ws.rs</groupId>
|
||||||
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-blobstore</artifactId>
|
||||||
|
<version>${jclouds.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta.ws.rs</groupId>
|
||||||
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds.api</groupId>
|
||||||
|
<artifactId>filesystem</artifactId>
|
||||||
|
<version>${jclouds.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds.provider</groupId>
|
||||||
|
<artifactId>aws-s3</artifactId>
|
||||||
|
<version>${jclouds.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- required frontpage generation -->
|
<!-- required frontpage generation -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf</groupId>
|
<groupId>org.thymeleaf</groupId>
|
||||||
@@ -876,7 +929,20 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xhtmlrenderer</groupId>
|
<groupId>org.xhtmlrenderer</groupId>
|
||||||
<artifactId>flying-saucer-pdf</artifactId>
|
<artifactId>flying-saucer-pdf</artifactId>
|
||||||
<version>9.11.4</version>
|
<version>9.12.0</version>
|
||||||
|
<exclusions>
|
||||||
|
<!-- Conflicts with Hibernate. Use version that is brought in via Hibernate -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>mockwebserver</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -21,6 +21,13 @@ import javax.xml.xpath.XPathConstants;
|
|||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
|
import org.apache.commons.cli.DefaultParser;
|
||||||
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.BitstreamFormat;
|
import org.dspace.content.BitstreamFormat;
|
||||||
@@ -41,7 +48,7 @@ import org.xml.sax.SAXException;
|
|||||||
* <P>
|
* <P>
|
||||||
* <code>RegistryLoader -bitstream bitstream-formats.xml</code>
|
* <code>RegistryLoader -bitstream bitstream-formats.xml</code>
|
||||||
* <P>
|
* <P>
|
||||||
* <code>RegistryLoader -dc dc-types.xml</code>
|
* <code>RegistryLoader -metadata dc-types.xml</code>
|
||||||
*
|
*
|
||||||
* @author Robert Tansley
|
* @author Robert Tansley
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
@@ -50,7 +57,7 @@ public class RegistryLoader {
|
|||||||
/**
|
/**
|
||||||
* log4j category
|
* log4j category
|
||||||
*/
|
*/
|
||||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(RegistryLoader.class);
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(RegistryLoader.class);
|
||||||
|
|
||||||
protected static BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance()
|
protected static BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance()
|
||||||
.getBitstreamFormatService();
|
.getBitstreamFormatService();
|
||||||
@@ -67,50 +74,99 @@ public class RegistryLoader {
|
|||||||
* @throws Exception if error
|
* @throws Exception if error
|
||||||
*/
|
*/
|
||||||
public static void main(String[] argv) throws Exception {
|
public static void main(String[] argv) throws Exception {
|
||||||
String usage = "Usage: " + RegistryLoader.class.getName()
|
// Set up command-line options and parse arguments
|
||||||
+ " (-bitstream | -metadata) registry-file.xml";
|
CommandLineParser parser = new DefaultParser();
|
||||||
|
Options options = createCommandLineOptions();
|
||||||
Context context = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context = new Context();
|
CommandLine line = parser.parse(options, argv);
|
||||||
|
|
||||||
|
// Check if help option was entered or no options provided
|
||||||
|
if (line.hasOption('h') || line.getOptions().length == 0) {
|
||||||
|
printHelp(options);
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context context = new Context();
|
||||||
|
|
||||||
// Can't update registries anonymously, so we need to turn off
|
// Can't update registries anonymously, so we need to turn off
|
||||||
// authorisation
|
// authorisation
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
// Work out what we're loading
|
try {
|
||||||
if (argv[0].equalsIgnoreCase("-bitstream")) {
|
// Work out what we're loading
|
||||||
RegistryLoader.loadBitstreamFormats(context, argv[1]);
|
if (line.hasOption('b')) {
|
||||||
} else if (argv[0].equalsIgnoreCase("-metadata")) {
|
String filename = line.getOptionValue('b');
|
||||||
// Call MetadataImporter, as it handles Metadata schema updates
|
if (StringUtils.isEmpty(filename)) {
|
||||||
MetadataImporter.loadRegistry(argv[1], true);
|
System.err.println("No file path provided for bitstream format registry");
|
||||||
} else {
|
printHelp(options);
|
||||||
System.err.println(usage);
|
System.exit(1);
|
||||||
|
}
|
||||||
|
RegistryLoader.loadBitstreamFormats(context, filename);
|
||||||
|
} else if (line.hasOption('m')) {
|
||||||
|
String filename = line.getOptionValue('m');
|
||||||
|
if (StringUtils.isEmpty(filename)) {
|
||||||
|
System.err.println("No file path provided for metadata registry");
|
||||||
|
printHelp(options);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
// Call MetadataImporter, as it handles Metadata schema updates
|
||||||
|
MetadataImporter.loadRegistry(filename, true);
|
||||||
|
} else {
|
||||||
|
System.err.println("No registry type specified");
|
||||||
|
printHelp(options);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit changes and close Context
|
||||||
|
context.complete();
|
||||||
|
System.exit(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.fatal(LogHelper.getHeader(context, "error_loading_registries", ""), e);
|
||||||
|
System.err.println("Error: \n - " + e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
} finally {
|
||||||
|
// Clean up our context, if it still exists & it was never completed
|
||||||
|
if (context != null && context.isValid()) {
|
||||||
|
context.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
// Commit changes and close Context
|
System.err.println("Error parsing command-line arguments: " + e.getMessage());
|
||||||
context.complete();
|
printHelp(options);
|
||||||
|
|
||||||
System.exit(0);
|
|
||||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
|
||||||
System.err.println(usage);
|
|
||||||
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
} catch (Exception e) {
|
|
||||||
log.fatal(LogHelper.getHeader(context, "error_loading_registries",
|
|
||||||
""), e);
|
|
||||||
|
|
||||||
System.err.println("Error: \n - " + e.getMessage());
|
|
||||||
System.exit(1);
|
|
||||||
} finally {
|
|
||||||
// Clean up our context, if it still exists & it was never completed
|
|
||||||
if (context != null && context.isValid()) {
|
|
||||||
context.abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the command-line options
|
||||||
|
* @return the command-line options
|
||||||
|
*/
|
||||||
|
private static Options createCommandLineOptions() {
|
||||||
|
Options options = new Options();
|
||||||
|
|
||||||
|
options.addOption("b", "bitstream", true, "load bitstream format registry from specified file");
|
||||||
|
options.addOption("m", "metadata", true, "load metadata registry from specified file");
|
||||||
|
options.addOption("h", "help", false, "print this help message");
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the help message
|
||||||
|
* @param options the command-line options
|
||||||
|
*/
|
||||||
|
private static void printHelp(Options options) {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("RegistryLoader",
|
||||||
|
"Load bitstream format or metadata registries into the database\n",
|
||||||
|
options,
|
||||||
|
"\nExamples:\n" +
|
||||||
|
" RegistryLoader -b bitstream-formats.xml\n" +
|
||||||
|
" RegistryLoader -m dc-types.xml",
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Bitstream Format metadata
|
* Load Bitstream Format metadata
|
||||||
*
|
*
|
||||||
@@ -221,7 +277,7 @@ public class RegistryLoader {
|
|||||||
* contains:
|
* contains:
|
||||||
* <P>
|
* <P>
|
||||||
* <code>
|
* <code>
|
||||||
* <foo><mimetype>application/pdf</mimetype></foo>
|
* <foo><mimetype>application/pdf</mimetype></foo>
|
||||||
* </code>
|
* </code>
|
||||||
* passing this the <code>foo</code> node and <code>mimetype</code> will
|
* passing this the <code>foo</code> node and <code>mimetype</code> will
|
||||||
* return <code>application/pdf</code>.
|
* return <code>application/pdf</code>.
|
||||||
@@ -262,10 +318,10 @@ public class RegistryLoader {
|
|||||||
* document contains:
|
* document contains:
|
||||||
* <P>
|
* <P>
|
||||||
* <code>
|
* <code>
|
||||||
* <foo>
|
* <foo>
|
||||||
* <bar>val1</bar>
|
* <bar>val1</bar>
|
||||||
* <bar>val2</bar>
|
* <bar>val2</bar>
|
||||||
* </foo>
|
* </foo>
|
||||||
* </code>
|
* </code>
|
||||||
* passing this the <code>foo</code> node and <code>bar</code> will
|
* passing this the <code>foo</code> node and <code>bar</code> will
|
||||||
* return <code>val1</code> and <code>val2</code>.
|
* return <code>val1</code> and <code>val2</code>.
|
||||||
@@ -295,4 +351,4 @@ public class RegistryLoader {
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -416,7 +416,7 @@ public class BulkAccessControl extends DSpaceRunnable<BulkAccessControlScriptCon
|
|||||||
discoverQuery.setQuery(query);
|
discoverQuery.setQuery(query);
|
||||||
discoverQuery.setStart(start);
|
discoverQuery.setStart(start);
|
||||||
discoverQuery.setMaxResults(limit);
|
discoverQuery.setMaxResults(limit);
|
||||||
|
discoverQuery.setSortField("search.resourceid", DiscoverQuery.SORT_ORDER.asc);
|
||||||
return discoverQuery;
|
return discoverQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -142,7 +142,8 @@ public class MetadataExportFilteredItemsReport extends DSpaceRunnable
|
|||||||
|
|
||||||
FilteredItems items = contentReportService.findFilteredItems(context, query);
|
FilteredItems items = contentReportService.findFilteredItems(context, query);
|
||||||
handler.logDebug("creating dspacecsv");
|
handler.logDebug("creating dspacecsv");
|
||||||
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService.export(context, items.getItems().iterator(), true);
|
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService.export(context, items.getItems().iterator(),
|
||||||
|
true, handler);
|
||||||
handler.logDebug("writing to file " + getFileNameOrExportFile());
|
handler.logDebug("writing to file " + getFileNameOrExportFile());
|
||||||
handler.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
handler.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||||
context.restoreAuthSystemState();
|
context.restoreAuthSystemState();
|
||||||
|
@@ -143,7 +143,7 @@ public class MetadataExportSearch extends DSpaceRunnable<MetadataExportSearchScr
|
|||||||
|
|
||||||
Iterator<Item> itemIterator = searchService.iteratorSearch(context, dso, discoverQuery);
|
Iterator<Item> itemIterator = searchService.iteratorSearch(context, dso, discoverQuery);
|
||||||
handler.logDebug("creating dspacecsv");
|
handler.logDebug("creating dspacecsv");
|
||||||
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService.export(context, itemIterator, true);
|
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService.export(context, itemIterator, true, handler);
|
||||||
handler.logDebug("writing to file " + getFileNameOrExportFile());
|
handler.logDebug("writing to file " + getFileNameOrExportFile());
|
||||||
handler.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
handler.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||||
context.restoreAuthSystemState();
|
context.restoreAuthSystemState();
|
||||||
|
@@ -23,6 +23,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import jakarta.annotation.Nullable;
|
import jakarta.annotation.Nullable;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.util.RelationshipUtils;
|
import org.dspace.app.util.RelationshipUtils;
|
||||||
@@ -89,7 +90,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
/**
|
/**
|
||||||
* The authority controlled fields
|
* The authority controlled fields
|
||||||
*/
|
*/
|
||||||
protected static Set<String> authorityControlled;
|
protected Set<String> authorityControlled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The prefix of the authority controlled field
|
* The prefix of the authority controlled field
|
||||||
@@ -742,10 +743,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
if (value == null || !value.contains(csv.getAuthoritySeparator())) {
|
if (value == null || !value.contains(csv.getAuthoritySeparator())) {
|
||||||
simplyCopyValue(value, dcv);
|
simplyCopyValue(value, dcv);
|
||||||
} else {
|
} else {
|
||||||
String[] parts = value.split(csv.getAuthoritySeparator());
|
resolveValueAndAuthority(value, dcv);
|
||||||
dcv.setValue(parts[0]);
|
|
||||||
dcv.setAuthority(parts[1]);
|
|
||||||
dcv.setConfidence((parts.length > 2 ? Integer.valueOf(parts[2]) : Choices.CF_ACCEPTED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromAuthority==null: with the current implementation metadata values from external authority sources
|
// fromAuthority==null: with the current implementation metadata values from external authority sources
|
||||||
@@ -1162,10 +1160,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
} else if (value == null || !value.contains(csv.getAuthoritySeparator())) {
|
} else if (value == null || !value.contains(csv.getAuthoritySeparator())) {
|
||||||
simplyCopyValue(value, dcv);
|
simplyCopyValue(value, dcv);
|
||||||
} else {
|
} else {
|
||||||
String[] parts = value.split(csv.getEscapedAuthoritySeparator());
|
resolveValueAndAuthority(value, dcv);
|
||||||
dcv.setValue(parts[0]);
|
|
||||||
dcv.setAuthority(parts[1]);
|
|
||||||
dcv.setConfidence((parts.length > 2 ? Integer.valueOf(parts[2]) : Choices.CF_ACCEPTED));
|
|
||||||
}
|
}
|
||||||
return dcv;
|
return dcv;
|
||||||
}
|
}
|
||||||
@@ -1176,6 +1171,35 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
dcv.setConfidence(Choices.CF_UNSET);
|
dcv.setConfidence(Choices.CF_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resolveValueAndAuthority(String value, BulkEditMetadataValue dcv) {
|
||||||
|
// Cells with valid authority are composed of three parts ~ <value>, <authority>, <confidence>
|
||||||
|
// The value itself may also include the authority separator though
|
||||||
|
String[] parts = value.split(csv.getEscapedAuthoritySeparator());
|
||||||
|
|
||||||
|
// If we don't have enough parts, assume the whole string is the value
|
||||||
|
if (parts.length < 3) {
|
||||||
|
simplyCopyValue(value, dcv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// The last part of the cell must be a confidence value (integer)
|
||||||
|
int confidence = Integer.parseInt(parts[parts.length - 1]);
|
||||||
|
String authority = parts[parts.length - 2];
|
||||||
|
String plainValue = String.join(
|
||||||
|
csv.getAuthoritySeparator(),
|
||||||
|
ArrayUtils.subarray(parts, 0, parts.length - 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
dcv.setValue(plainValue);
|
||||||
|
dcv.setAuthority(authority);
|
||||||
|
dcv.setConfidence(confidence);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Otherwise assume the whole string is the value
|
||||||
|
simplyCopyValue(value, dcv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to find if a String occurs in an array of Strings
|
* Method to find if a String occurs in an array of Strings
|
||||||
*
|
*
|
||||||
@@ -1368,10 +1392,10 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
/**
|
/**
|
||||||
* is the field is defined as authority controlled
|
* is the field is defined as authority controlled
|
||||||
*/
|
*/
|
||||||
private static boolean isAuthorityControlledField(String md) {
|
private boolean isAuthorityControlledField(String md) {
|
||||||
String mdf = md.contains(":") ? StringUtils.substringAfter(md, ":") : md;
|
String mdf = md.contains(":") ? StringUtils.substringAfter(md, ":") : md;
|
||||||
mdf = StringUtils.substringBefore(mdf, "[");
|
mdf = StringUtils.substringBefore(mdf, "[");
|
||||||
return authorityControlled.contains(mdf);
|
return authorityControlled.contains(mdf) || authorityControlled.contains(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1802,5 +1826,4 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
String targetType, String originType, String originTypeName) {
|
String targetType, String originType, String originTypeName) {
|
||||||
return RelationshipUtils.matchRelationshipType(relTypes, targetType, originType, originTypeName);
|
return RelationshipUtils.matchRelationshipType(relTypes, targetType, originType, originTypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.client;
|
||||||
|
|
||||||
|
import static org.apache.commons.collections4.ListUtils.emptyIfNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory of {@link HttpClient} with common configurations.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DSpaceHttpClientFactory {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSpaceProxyRoutePlanner proxyRoutePlanner;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<HttpRequestInterceptor> requestInterceptors;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<HttpResponseInterceptor> responseInterceptors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an instance of {@link DSpaceHttpClientFactory} from the Spring context.
|
||||||
|
* @return the bean instance
|
||||||
|
*/
|
||||||
|
public static DSpaceHttpClientFactory getInstance() {
|
||||||
|
return new DSpace().getSingletonService(DSpaceHttpClientFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an instance of {@link HttpClient} setting the proxy if configured.
|
||||||
|
*
|
||||||
|
* @return the client
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient build() {
|
||||||
|
return build(HttpClientBuilder.create(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a Builder if an instance of {@link HttpClient} pre-setting the proxy if configured.
|
||||||
|
*
|
||||||
|
* @return the client
|
||||||
|
*/
|
||||||
|
public HttpClientBuilder builder(boolean setProxy) {
|
||||||
|
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
|
||||||
|
if (setProxy) {
|
||||||
|
clientBuilder.setRoutePlanner(proxyRoutePlanner);
|
||||||
|
}
|
||||||
|
getRequestInterceptors().forEach(clientBuilder::addInterceptorLast);
|
||||||
|
getResponseInterceptors().forEach(clientBuilder::addInterceptorLast);
|
||||||
|
return clientBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an instance of {@link HttpClient} without setting the proxy, even if
|
||||||
|
* configured.
|
||||||
|
*
|
||||||
|
* @return the client
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient buildWithoutProxy() {
|
||||||
|
return build(HttpClientBuilder.create(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an instance of {@link HttpClient} setting the proxy if configured,
|
||||||
|
* disabling automatic retries and setting the maximum total connection.
|
||||||
|
*
|
||||||
|
* @param maxConnTotal the maximum total connection value
|
||||||
|
* @return the client
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient buildWithoutAutomaticRetries(int maxConnTotal) {
|
||||||
|
HttpClientBuilder clientBuilder = HttpClientBuilder.create()
|
||||||
|
.disableAutomaticRetries()
|
||||||
|
.setMaxConnTotal(maxConnTotal);
|
||||||
|
return build(clientBuilder, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an instance of {@link HttpClient} setting the proxy if configured with
|
||||||
|
* the given request configuration.
|
||||||
|
* @param requestConfig the request configuration
|
||||||
|
* @return the client
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient buildWithRequestConfig(RequestConfig requestConfig) {
|
||||||
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
|
||||||
|
.setDefaultRequestConfig(requestConfig);
|
||||||
|
return build(httpClientBuilder, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CloseableHttpClient build(HttpClientBuilder clientBuilder, boolean setProxy) {
|
||||||
|
if (setProxy) {
|
||||||
|
clientBuilder.setRoutePlanner(proxyRoutePlanner);
|
||||||
|
}
|
||||||
|
getRequestInterceptors().forEach(clientBuilder::addInterceptorLast);
|
||||||
|
getResponseInterceptors().forEach(clientBuilder::addInterceptorLast);
|
||||||
|
return clientBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationService getConfigurationService() {
|
||||||
|
return configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigurationService(ConfigurationService configurationService) {
|
||||||
|
this.configurationService = configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HttpRequestInterceptor> getRequestInterceptors() {
|
||||||
|
return emptyIfNull(requestInterceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestInterceptors(List<HttpRequestInterceptor> requestInterceptors) {
|
||||||
|
this.requestInterceptors = requestInterceptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HttpResponseInterceptor> getResponseInterceptors() {
|
||||||
|
return emptyIfNull(responseInterceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseInterceptors(List<HttpResponseInterceptor> responseInterceptors) {
|
||||||
|
this.responseInterceptors = responseInterceptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DSpaceProxyRoutePlanner getProxyRoutePlanner() {
|
||||||
|
return proxyRoutePlanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProxyRoutePlanner(DSpaceProxyRoutePlanner proxyRoutePlanner) {
|
||||||
|
this.proxyRoutePlanner = proxyRoutePlanner;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.client;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpException;
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.HttpRequest;
|
||||||
|
import org.apache.http.impl.conn.DefaultRoutePlanner;
|
||||||
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of {@link DefaultRoutePlanner} that determine the proxy based on
|
||||||
|
* the configuration service, ignoring configured hosts.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DSpaceProxyRoutePlanner extends DefaultRoutePlanner {
|
||||||
|
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
public DSpaceProxyRoutePlanner(ConfigurationService configurationService) {
|
||||||
|
super(null);
|
||||||
|
this.configurationService = configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
|
||||||
|
if (isTargetHostConfiguredToBeIgnored(target)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String proxyHost = configurationService.getProperty("http.proxy.host");
|
||||||
|
String proxyPort = configurationService.getProperty("http.proxy.port");
|
||||||
|
if (StringUtils.isAnyBlank(proxyHost, proxyPort)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new HttpHost(proxyHost, Integer.parseInt(proxyPort), "http");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new RuntimeException("Invalid proxy port configuration: " + proxyPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTargetHostConfiguredToBeIgnored(HttpHost target) {
|
||||||
|
String[] hostsToIgnore = configurationService.getArrayProperty("http.proxy.hosts-to-ignore");
|
||||||
|
if (ArrayUtils.isEmpty(hostsToIgnore)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Arrays.stream(hostsToIgnore)
|
||||||
|
.anyMatch(host -> matchesHost(host, target.getHostName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesHost(String hostPattern, String hostName) {
|
||||||
|
if (hostName.equals(hostPattern)) {
|
||||||
|
return true;
|
||||||
|
} else if (hostPattern.startsWith("*")) {
|
||||||
|
return hostName.endsWith(StringUtils.removeStart(hostPattern, "*"));
|
||||||
|
} else if (hostPattern.endsWith("*")) {
|
||||||
|
return hostName.startsWith(StringUtils.removeEnd(hostPattern, "*"));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -18,9 +18,9 @@ import org.apache.http.client.methods.CloseableHttpResponse;
|
|||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.app.ldn.model.Notification;
|
import org.dspace.app.ldn.model.Notification;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -34,21 +34,13 @@ public class SendLDNMessageAction implements LDNAction {
|
|||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(SendLDNMessageAction.class);
|
private static final Logger log = LogManager.getLogger(SendLDNMessageAction.class);
|
||||||
|
|
||||||
private CloseableHttpClient client = null;
|
private CloseableHttpClient client;
|
||||||
|
|
||||||
public SendLDNMessageAction() {
|
public SendLDNMessageAction() {
|
||||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
|
||||||
client = builder
|
|
||||||
.disableAutomaticRetries()
|
|
||||||
.setMaxConnTotal(5)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendLDNMessageAction(CloseableHttpClient client) {
|
public SendLDNMessageAction(CloseableHttpClient client) {
|
||||||
this();
|
this.client = client;
|
||||||
if (client != null) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,9 +58,10 @@ public class SendLDNMessageAction implements LDNAction {
|
|||||||
// NOTE: Github believes there is a "Potential server-side request forgery due to a user-provided value"
|
// NOTE: Github believes there is a "Potential server-side request forgery due to a user-provided value"
|
||||||
// This is a false positive because the LDN Service URL is configured by the user from DSpace.
|
// This is a false positive because the LDN Service URL is configured by the user from DSpace.
|
||||||
// See the frontend configuration at [dspace.ui.url]/admin/ldn/services
|
// See the frontend configuration at [dspace.ui.url]/admin/ldn/services
|
||||||
try (
|
if (client == null) {
|
||||||
CloseableHttpResponse response = client.execute(httpPost);
|
client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5);
|
||||||
) {
|
}
|
||||||
|
try (CloseableHttpResponse response = client.execute(httpPost)) {
|
||||||
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
||||||
result = LDNActionStatus.CONTINUE;
|
result = LDNActionStatus.CONTINUE;
|
||||||
} else if (isRedirect(response.getStatusLine().getStatusCode())) {
|
} else if (isRedirect(response.getStatusLine().getStatusCode())) {
|
||||||
@@ -77,6 +70,7 @@ public class SendLDNMessageAction implements LDNAction {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e);
|
log.error(e);
|
||||||
}
|
}
|
||||||
|
client.close();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,9 +85,9 @@ public class SendLDNMessageAction implements LDNAction {
|
|||||||
statusCode == HttpStatus.SC_TEMPORARY_REDIRECT;
|
statusCode == HttpStatus.SC_TEMPORARY_REDIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LDNActionStatus handleRedirect(CloseableHttpResponse oldresponse,
|
private LDNActionStatus handleRedirect(CloseableHttpResponse oldResponse,
|
||||||
HttpPost request) throws HttpException {
|
HttpPost request) throws HttpException {
|
||||||
Header[] urls = oldresponse.getHeaders(HttpHeaders.LOCATION);
|
Header[] urls = oldResponse.getHeaders(HttpHeaders.LOCATION);
|
||||||
String url = urls.length > 0 && urls[0] != null ? urls[0].getValue() : null;
|
String url = urls.length > 0 && urls[0] != null ? urls[0].getValue() : null;
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
throw new HttpException("Error following redirect, unable to reach"
|
throw new HttpException("Error following redirect, unable to reach"
|
||||||
@@ -102,17 +96,14 @@ public class SendLDNMessageAction implements LDNAction {
|
|||||||
LDNActionStatus result = LDNActionStatus.ABORT;
|
LDNActionStatus result = LDNActionStatus.ABORT;
|
||||||
try {
|
try {
|
||||||
request.setURI(new URI(url));
|
request.setURI(new URI(url));
|
||||||
try (
|
try (CloseableHttpResponse response = client.execute(request)) {
|
||||||
CloseableHttpResponse response = client.execute(request);
|
|
||||||
) {
|
|
||||||
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
||||||
return LDNActionStatus.CONTINUE;
|
result = LDNActionStatus.CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error following redirect:", e);
|
log.error("Error following redirect:", e);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return LDNActionStatus.ABORT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -141,7 +141,7 @@ public class TikaTextExtractionFilter
|
|||||||
@Override
|
@Override
|
||||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
try {
|
try {
|
||||||
writer.append(new String(ch), start, length);
|
writer.append(new String(ch, start, length));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
String errorMsg = String.format("Could not append to temporary file at %s " +
|
String errorMsg = String.format("Could not append to temporary file at %s " +
|
||||||
"when performing text extraction",
|
"when performing text extraction",
|
||||||
@@ -159,7 +159,7 @@ public class TikaTextExtractionFilter
|
|||||||
@Override
|
@Override
|
||||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||||
try {
|
try {
|
||||||
writer.append(new String(ch), start, length);
|
writer.append(new String(ch, start, length));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
String errorMsg = String.format("Could not append to temporary file at %s " +
|
String errorMsg = String.format("Could not append to temporary file at %s " +
|
||||||
"when performing text extraction",
|
"when performing text extraction",
|
||||||
|
@@ -17,15 +17,15 @@ import jakarta.annotation.PostConstruct;
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.app.sherpa.v2.SHERPAPublisherResponse;
|
import org.dspace.app.sherpa.v2.SHERPAPublisherResponse;
|
||||||
import org.dspace.app.sherpa.v2.SHERPAResponse;
|
import org.dspace.app.sherpa.v2.SHERPAResponse;
|
||||||
import org.dspace.app.sherpa.v2.SHERPAUtils;
|
import org.dspace.app.sherpa.v2.SHERPAUtils;
|
||||||
@@ -45,8 +45,6 @@ import org.springframework.cache.annotation.Cacheable;
|
|||||||
*/
|
*/
|
||||||
public class SHERPAService {
|
public class SHERPAService {
|
||||||
|
|
||||||
private CloseableHttpClient client = null;
|
|
||||||
|
|
||||||
private int maxNumberOfTries;
|
private int maxNumberOfTries;
|
||||||
private long sleepBetweenTimeouts;
|
private long sleepBetweenTimeouts;
|
||||||
private int timeout = 5000;
|
private int timeout = 5000;
|
||||||
@@ -59,19 +57,6 @@ public class SHERPAService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
ConfigurationService configurationService;
|
ConfigurationService configurationService;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new HTTP builder with sensible defaults in constructor
|
|
||||||
*/
|
|
||||||
public SHERPAService() {
|
|
||||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
|
||||||
// httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as
|
|
||||||
// not to hammer the SHERPA service too much.
|
|
||||||
client = builder
|
|
||||||
.disableAutomaticRetries()
|
|
||||||
.setMaxConnTotal(5)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complete initialization of the Bean.
|
* Complete initialization of the Bean.
|
||||||
*/
|
*/
|
||||||
@@ -132,46 +117,47 @@ public class SHERPAService {
|
|||||||
timeout,
|
timeout,
|
||||||
sleepBetweenTimeouts));
|
sleepBetweenTimeouts));
|
||||||
|
|
||||||
try {
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5)) {
|
||||||
Thread.sleep(sleepBetweenTimeouts);
|
Thread.sleep(sleepBetweenTimeouts);
|
||||||
|
|
||||||
// Construct a default HTTP method (first result)
|
// Construct a default HTTP method (first result)
|
||||||
method = constructHttpGet(type, field, predicate, value, start, limit);
|
method = constructHttpGet(type, field, predicate, value, start, limit);
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
HttpResponse response = client.execute(method);
|
try (CloseableHttpResponse response = client.execute(method)) {
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||||
+ response.getStatusLine().getReasonPhrase());
|
+ response.getStatusLine().getReasonPhrase());
|
||||||
|
|
||||||
if (statusCode != HttpStatus.SC_OK) {
|
if (statusCode != HttpStatus.SC_OK) {
|
||||||
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: "
|
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: "
|
||||||
+ statusCode);
|
+ statusCode);
|
||||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpEntity responseBody = response.getEntity();
|
HttpEntity responseBody = response.getEntity();
|
||||||
|
|
||||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||||
if (null != responseBody) {
|
if (null != responseBody) {
|
||||||
log.debug("Non-null SHERPA response received for query of " + value);
|
log.debug("Non-null SHERPA response received for query of " + value);
|
||||||
InputStream content = null;
|
InputStream content = null;
|
||||||
try {
|
try {
|
||||||
content = responseBody.getContent();
|
content = responseBody.getContent();
|
||||||
sherpaResponse =
|
sherpaResponse =
|
||||||
new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON);
|
new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
content.close();
|
content.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Empty SHERPA response body for query on " + value);
|
||||||
|
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO returned no response");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.debug("Empty SHERPA response body for query on " + value);
|
|
||||||
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO returned no response");
|
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage();
|
String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage();
|
||||||
@@ -235,45 +221,46 @@ public class SHERPAService {
|
|||||||
timeout,
|
timeout,
|
||||||
sleepBetweenTimeouts));
|
sleepBetweenTimeouts));
|
||||||
|
|
||||||
try {
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5)) {
|
||||||
Thread.sleep(sleepBetweenTimeouts);
|
Thread.sleep(sleepBetweenTimeouts);
|
||||||
|
|
||||||
// Construct a default HTTP method (first result)
|
// Construct a default HTTP method (first result)
|
||||||
method = constructHttpGet(type, field, predicate, value, start, limit);
|
method = constructHttpGet(type, field, predicate, value, start, limit);
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
HttpResponse response = client.execute(method);
|
try (CloseableHttpResponse response = client.execute(method)) {
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||||
+ response.getStatusLine().getReasonPhrase());
|
+ response.getStatusLine().getReasonPhrase());
|
||||||
|
|
||||||
if (statusCode != HttpStatus.SC_OK) {
|
if (statusCode != HttpStatus.SC_OK) {
|
||||||
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: "
|
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: "
|
||||||
+ statusCode);
|
+ statusCode);
|
||||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpEntity responseBody = response.getEntity();
|
HttpEntity responseBody = response.getEntity();
|
||||||
|
|
||||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||||
if (null != responseBody) {
|
if (null != responseBody) {
|
||||||
log.debug("Non-null SHERPA response received for query of " + value);
|
log.debug("Non-null SHERPA response received for query of " + value);
|
||||||
InputStream content = null;
|
InputStream content = null;
|
||||||
try {
|
try {
|
||||||
content = responseBody.getContent();
|
content = responseBody.getContent();
|
||||||
sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON);
|
sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
content.close();
|
content.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Empty SHERPA response body for query on " + value);
|
||||||
|
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.debug("Empty SHERPA response body for query on " + value);
|
|
||||||
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response");
|
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage();
|
String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage();
|
||||||
@@ -283,7 +270,7 @@ public class SHERPAService {
|
|||||||
String errorMessage = "Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage();
|
String errorMessage = "Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage();
|
||||||
log.error(errorMessage, e);
|
log.error(errorMessage, e);
|
||||||
sherpaResponse = new SHERPAResponse(errorMessage);
|
sherpaResponse = new SHERPAResponse(errorMessage);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
String errorMessage = "Encountered exception while sleeping thread: " + e.getMessage();
|
String errorMessage = "Encountered exception while sleeping thread: " + e.getMessage();
|
||||||
log.error(errorMessage, e);
|
log.error(errorMessage, e);
|
||||||
sherpaResponse = new SHERPAResponse(errorMessage);
|
sherpaResponse = new SHERPAResponse(errorMessage);
|
||||||
|
@@ -1231,8 +1231,8 @@ public class LogAnalyser {
|
|||||||
}
|
}
|
||||||
accessionedQuery.append("]");
|
accessionedQuery.append("]");
|
||||||
discoverQuery.addFilterQueries(accessionedQuery.toString());
|
discoverQuery.addFilterQueries(accessionedQuery.toString());
|
||||||
discoverQuery.addFilterQueries("withdrawn: false");
|
discoverQuery.addFilterQueries("withdrawn:false");
|
||||||
discoverQuery.addFilterQueries("archived: true");
|
discoverQuery.addFilterQueries("archived:true");
|
||||||
|
|
||||||
return (int) SearchUtils.getSearchService().search(context, discoverQuery).getTotalSearchResults();
|
return (int) SearchUtils.getSearchService().search(context, discoverQuery).getTotalSearchResults();
|
||||||
}
|
}
|
||||||
|
@@ -119,8 +119,11 @@ public class PublicationLoaderRunnable
|
|||||||
DiscoverResultItemIterator researchers = findResearchers();
|
DiscoverResultItemIterator researchers = findResearchers();
|
||||||
while (researchers.hasNext()) {
|
while (researchers.hasNext()) {
|
||||||
Item researcher = researchers.next();
|
Item researcher = researchers.next();
|
||||||
|
researcher = context.reloadEntity(researcher);
|
||||||
publicationLoader.importRecords(context, researcher);
|
publicationLoader.importRecords(context, researcher);
|
||||||
setLastImportMetadataValue(researcher);
|
setLastImportMetadataValue(researcher);
|
||||||
|
context.commit();
|
||||||
|
context.uncacheEntity(researcher);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
context.restoreAuthSystemState();
|
context.restoreAuthSystemState();
|
||||||
|
@@ -64,20 +64,36 @@ public class InitializeEntities {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] argv) throws SQLException, AuthorizeException, ParseException {
|
public static void main(String[] argv) throws SQLException, AuthorizeException, ParseException {
|
||||||
InitializeEntities initializeEntities = new InitializeEntities();
|
InitializeEntities initializeEntities = new InitializeEntities();
|
||||||
|
// Set up command-line options and parse arguments
|
||||||
CommandLineParser parser = new DefaultParser();
|
CommandLineParser parser = new DefaultParser();
|
||||||
Options options = createCommandLineOptions();
|
Options options = createCommandLineOptions();
|
||||||
CommandLine line = parser.parse(options,argv);
|
CommandLine line = parser.parse(options,argv);
|
||||||
String fileLocation = getFileLocationFromCommandLine(line);
|
// First of all, check if the help option was entered or a required argument is missing
|
||||||
checkHelpEntered(options, line);
|
checkHelpEntered(options, line);
|
||||||
|
// Get the file location from the command line
|
||||||
|
String fileLocation = getFileLocationFromCommandLine(line);
|
||||||
|
// Run the script
|
||||||
initializeEntities.run(fileLocation);
|
initializeEntities.run(fileLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the help option was entered or a required argument is missing. If so, print help and exit.
|
||||||
|
* @param options the defined command-line options
|
||||||
|
* @param line the parsed command-line arguments
|
||||||
|
*/
|
||||||
private static void checkHelpEntered(Options options, CommandLine line) {
|
private static void checkHelpEntered(Options options, CommandLine line) {
|
||||||
if (line.hasOption("h")) {
|
if (line.hasOption("h") || !line.hasOption("f")) {
|
||||||
HelpFormatter formatter = new HelpFormatter();
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
formatter.printHelp("Initialize Entities", options);
|
formatter.printHelp("Initialize Entities", options);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file path from the command-line argument. Exits with exit code 1 if no file argument was entered.
|
||||||
|
* @param line the parsed command-line arguments
|
||||||
|
* @return the file path
|
||||||
|
*/
|
||||||
private static String getFileLocationFromCommandLine(CommandLine line) {
|
private static String getFileLocationFromCommandLine(CommandLine line) {
|
||||||
String query = line.getOptionValue("f");
|
String query = line.getOptionValue("f");
|
||||||
if (StringUtils.isEmpty(query)) {
|
if (StringUtils.isEmpty(query)) {
|
||||||
@@ -88,13 +104,25 @@ public class InitializeEntities {
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the command-line options
|
||||||
|
* @return the command-line options
|
||||||
|
*/
|
||||||
protected static Options createCommandLineOptions() {
|
protected static Options createCommandLineOptions() {
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
options.addOption("f", "file", true, "the location for the file containing the xml data");
|
options.addOption("f", "file", true, "the path to the file containing the " +
|
||||||
|
"relationship definitions (e.g. ${dspace.dir}/config/entities/relationship-types.xml)");
|
||||||
|
options.addOption("h", "help", false, "print this message");
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the script for the given file location
|
||||||
|
* @param fileLocation the file location
|
||||||
|
* @throws SQLException If something goes wrong initializing context or inserting relationship types
|
||||||
|
* @throws AuthorizeException If the script user fails to authorize while inserting relationship types
|
||||||
|
*/
|
||||||
private void run(String fileLocation) throws SQLException, AuthorizeException {
|
private void run(String fileLocation) throws SQLException, AuthorizeException {
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -102,6 +130,12 @@ public class InitializeEntities {
|
|||||||
context.complete();
|
context.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the XML file at fileLocation to create relationship types in the database
|
||||||
|
* @param context DSpace context
|
||||||
|
* @param fileLocation the full or relative file path to the relationship types XML
|
||||||
|
* @throws AuthorizeException If the script user fails to authorize while inserting relationship types
|
||||||
|
*/
|
||||||
private void parseXMLToRelations(Context context, String fileLocation) throws AuthorizeException {
|
private void parseXMLToRelations(Context context, String fileLocation) throws AuthorizeException {
|
||||||
try {
|
try {
|
||||||
File fXmlFile = new File(fileLocation);
|
File fXmlFile = new File(fileLocation);
|
||||||
@@ -158,15 +192,15 @@ public class InitializeEntities {
|
|||||||
|
|
||||||
for (int j = 0; j < leftCardinalityList.getLength(); j++) {
|
for (int j = 0; j < leftCardinalityList.getLength(); j++) {
|
||||||
Node node = leftCardinalityList.item(j);
|
Node node = leftCardinalityList.item(j);
|
||||||
leftCardinalityMin = getString(leftCardinalityMin,(Element) node, "min");
|
leftCardinalityMin = getCardinalityMinString(leftCardinalityMin,(Element) node, "min");
|
||||||
leftCardinalityMax = getString(leftCardinalityMax,(Element) node, "max");
|
leftCardinalityMax = getCardinalityMinString(leftCardinalityMax,(Element) node, "max");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < rightCardinalityList.getLength(); j++) {
|
for (int j = 0; j < rightCardinalityList.getLength(); j++) {
|
||||||
Node node = rightCardinalityList.item(j);
|
Node node = rightCardinalityList.item(j);
|
||||||
rightCardinalityMin = getString(rightCardinalityMin,(Element) node, "min");
|
rightCardinalityMin = getCardinalityMinString(rightCardinalityMin,(Element) node, "min");
|
||||||
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
rightCardinalityMax = getCardinalityMinString(rightCardinalityMax,(Element) node, "max");
|
||||||
|
|
||||||
}
|
}
|
||||||
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
||||||
@@ -182,13 +216,39 @@ public class InitializeEntities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getString(String leftCardinalityMin,Element node, String minOrMax) {
|
/**
|
||||||
|
* Extract the min or max value for the left or right cardinality from the node text content
|
||||||
|
* @param leftCardinalityMin current left cardinality min
|
||||||
|
* @param node node to extract the min or max value from
|
||||||
|
* @param minOrMax element tag name to parse
|
||||||
|
* @return final left cardinality min
|
||||||
|
*/
|
||||||
|
private String getCardinalityMinString(String leftCardinalityMin, Element node, String minOrMax) {
|
||||||
if (node.getElementsByTagName(minOrMax).getLength() > 0) {
|
if (node.getElementsByTagName(minOrMax).getLength() > 0) {
|
||||||
leftCardinalityMin = node.getElementsByTagName(minOrMax).item(0).getTextContent();
|
leftCardinalityMin = node.getElementsByTagName(minOrMax).item(0).getTextContent();
|
||||||
}
|
}
|
||||||
return leftCardinalityMin;
|
return leftCardinalityMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the relationship type based on values parsed from the XML relationship types configuration
|
||||||
|
*
|
||||||
|
* @param context DSpace context
|
||||||
|
* @param leftType left relationship type (e.g. "Publication").
|
||||||
|
* @param rightType right relationship type (e.g. "Journal").
|
||||||
|
* @param leftwardType leftward relationship type (e.g. "isAuthorOfPublication").
|
||||||
|
* @param rightwardType rightward relationship type (e.g. "isPublicationOfAuthor").
|
||||||
|
* @param leftCardinalityMin left cardinality min
|
||||||
|
* @param leftCardinalityMax left cardinality max
|
||||||
|
* @param rightCardinalityMin right cardinality min
|
||||||
|
* @param rightCardinalityMax right cardinality max
|
||||||
|
* @param copyToLeft copy metadata values to left if right side is deleted
|
||||||
|
* @param copyToRight copy metadata values to right if left side is deleted
|
||||||
|
* @param tilted set a tilted relationship side (left or right) if there are many relationships going one way
|
||||||
|
* to help performance (e.g. authors with 1000s of publications)
|
||||||
|
* @throws SQLException if database error occurs while saving the relationship type
|
||||||
|
* @throws AuthorizeException if authorization error occurs while saving the relationship type
|
||||||
|
*/
|
||||||
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
||||||
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||||
String rightCardinalityMin, String rightCardinalityMax,
|
String rightCardinalityMin, String rightCardinalityMax,
|
||||||
|
@@ -100,6 +100,14 @@ public class OpenSearchServiceImpl implements OpenSearchService {
|
|||||||
configurationService.getProperty("websvc.opensearch.uicontext");
|
configurationService.getProperty("websvc.opensearch.uicontext");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get base search UI URL (websvc.opensearch.max_num_of_items_per_request)
|
||||||
|
*/
|
||||||
|
public int getMaxNumOfItemsPerRequest() {
|
||||||
|
return configurationService.getIntProperty(
|
||||||
|
"websvc.opensearch.max_num_of_items_per_request", 100);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentType(String format) {
|
public String getContentType(String format) {
|
||||||
return "html".equals(format) ? "text/html" :
|
return "html".equals(format) ? "text/html" :
|
||||||
|
@@ -257,8 +257,14 @@ public class SyndicationFeed {
|
|||||||
String pubDateString = getOneDC(item, dateField);
|
String pubDateString = getOneDC(item, dateField);
|
||||||
if (pubDateString != null) {
|
if (pubDateString != null) {
|
||||||
ZonedDateTime pubDate = new DCDate(pubDateString).toDate();
|
ZonedDateTime pubDate = new DCDate(pubDateString).toDate();
|
||||||
entry.setPublishedDate(java.util.Date.from(pubDate.toInstant()));
|
// If date string could not be parsed as a date, then pubDate will be null
|
||||||
hasDate = true;
|
if (pubDate != null) {
|
||||||
|
entry.setPublishedDate(java.util.Date.from(pubDate.toInstant()));
|
||||||
|
hasDate = true;
|
||||||
|
} else {
|
||||||
|
log.warn("Date field {} for item {} could not be parsed: {}", dateField, item.getID(),
|
||||||
|
pubDateString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// date of last change to Item
|
// date of last change to Item
|
||||||
entry.setUpdatedDate(java.util.Date.from(item.getLastModified()));
|
entry.setUpdatedDate(java.util.Date.from(item.getLastModified()));
|
||||||
|
@@ -13,12 +13,12 @@ import java.time.Instant;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpHead;
|
import org.apache.http.client.methods.HttpHead;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.app.util.dao.WebAppDAO;
|
import org.dspace.app.util.dao.WebAppDAO;
|
||||||
import org.dspace.app.util.service.WebAppService;
|
import org.dspace.app.util.service.WebAppService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -77,8 +77,8 @@ public class WebAppServiceImpl implements WebAppService {
|
|||||||
for (WebApp app : webApps) {
|
for (WebApp app : webApps) {
|
||||||
method = new HttpHead(app.getUrl());
|
method = new HttpHead(app.getUrl());
|
||||||
int status;
|
int status;
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpResponse response = client.execute(method);
|
CloseableHttpResponse response = client.execute(method);
|
||||||
status = response.getStatusLine().getStatusCode();
|
status = response.getStatusLine().getStatusCode();
|
||||||
}
|
}
|
||||||
if (status != HttpStatus.SC_OK) {
|
if (status != HttpStatus.SC_OK) {
|
||||||
|
@@ -112,4 +112,10 @@ public interface OpenSearchService {
|
|||||||
|
|
||||||
public DSpaceObject resolveScope(Context context, String scope) throws SQLException;
|
public DSpaceObject resolveScope(Context context, String scope) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the maximum number of items that can be included in a single opensearch request.
|
||||||
|
*
|
||||||
|
* @return the maximum number of items allowed per request
|
||||||
|
*/
|
||||||
|
int getMaxNumOfItemsPerRequest();
|
||||||
}
|
}
|
||||||
|
@@ -22,12 +22,13 @@ import org.apache.commons.io.IOUtils;
|
|||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.client.methods.RequestBuilder;
|
import org.apache.http.client.methods.RequestBuilder;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.authenticate.oidc.OidcClient;
|
import org.dspace.authenticate.oidc.OidcClient;
|
||||||
import org.dspace.authenticate.oidc.OidcClientException;
|
import org.dspace.authenticate.oidc.OidcClientException;
|
||||||
import org.dspace.authenticate.oidc.model.OidcTokenResponseDTO;
|
import org.dspace.authenticate.oidc.model.OidcTokenResponseDTO;
|
||||||
@@ -83,21 +84,17 @@ public class OidcClientImpl implements OidcClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeAndParseJson(HttpUriRequest httpUriRequest, Class<T> clazz) {
|
private <T> T executeAndParseJson(HttpUriRequest httpUriRequest, Class<T> clazz) {
|
||||||
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpClient client = HttpClientBuilder.create().build();
|
return executeAndReturns(() -> {
|
||||||
|
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||||
return executeAndReturns(() -> {
|
if (isNotSuccessfull(response)) {
|
||||||
|
throw new OidcClientException(getStatusCode(response), formatErrorMessage(response));
|
||||||
HttpResponse response = client.execute(httpUriRequest);
|
}
|
||||||
|
return objectMapper.readValue(getContent(response), clazz);
|
||||||
if (isNotSuccessfull(response)) {
|
});
|
||||||
throw new OidcClientException(getStatusCode(response), formatErrorMessage(response));
|
} catch (IOException e) {
|
||||||
}
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
return objectMapper.readValue(getContent(response), clazz);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
||||||
|
@@ -7,27 +7,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.authority.orcid;
|
package org.dspace.authority.orcid;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authority.AuthorityValue;
|
import org.dspace.authority.AuthorityValue;
|
||||||
import org.dspace.authority.SolrAuthorityInterface;
|
import org.dspace.authority.SolrAuthorityInterface;
|
||||||
import org.dspace.external.OrcidRestConnector;
|
import org.dspace.external.OrcidRestConnector;
|
||||||
import org.dspace.external.provider.orcid.xml.XMLtoBio;
|
import org.dspace.external.provider.orcid.xml.XMLtoBio;
|
||||||
import org.json.JSONObject;
|
import org.dspace.orcid.model.factory.OrcidFactoryUtils;
|
||||||
import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier;
|
import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier;
|
||||||
import org.orcid.jaxb.model.v3.release.record.Person;
|
import org.orcid.jaxb.model.v3.release.record.Person;
|
||||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||||
@@ -50,6 +45,11 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
|
|
||||||
private String accessToken;
|
private String accessToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum retries to allow for the access token retrieval
|
||||||
|
*/
|
||||||
|
private int maxClientRetries = 3;
|
||||||
|
|
||||||
public void setOAUTHUrl(String oAUTHUrl) {
|
public void setOAUTHUrl(String oAUTHUrl) {
|
||||||
OAUTHUrl = oAUTHUrl;
|
OAUTHUrl = oAUTHUrl;
|
||||||
}
|
}
|
||||||
@@ -62,46 +62,32 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessToken(String accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the accessToken that is required for all subsequent calls to ORCID
|
* Initialize the accessToken that is required for all subsequent calls to ORCID
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
if (StringUtils.isBlank(accessToken)
|
// Initialize access token at spring instantiation. If it fails, the access token will be null rather
|
||||||
&& StringUtils.isNotBlank(clientSecret)
|
// than causing a fatal Spring startup error
|
||||||
&& StringUtils.isNotBlank(clientId)
|
initializeAccessToken();
|
||||||
&& StringUtils.isNotBlank(OAUTHUrl)) {
|
}
|
||||||
String authenticationParameters = "?client_id=" + clientId +
|
|
||||||
"&client_secret=" + clientSecret +
|
|
||||||
"&scope=/read-public&grant_type=client_credentials";
|
|
||||||
try {
|
|
||||||
HttpPost httpPost = new HttpPost(OAUTHUrl + authenticationParameters);
|
|
||||||
httpPost.addHeader("Accept", "application/json");
|
|
||||||
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
public void initializeAccessToken() {
|
||||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
// If we have reaches max retries or the access token is already set, return immediately
|
||||||
|
if (maxClientRetries <= 0 || org.apache.commons.lang3.StringUtils.isNotBlank(accessToken)) {
|
||||||
JSONObject responseObject = null;
|
return;
|
||||||
try (InputStream is = getResponse.getEntity().getContent();
|
}
|
||||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
try {
|
||||||
String inputStr;
|
accessToken = OrcidFactoryUtils.retrieveAccessToken(clientId, clientSecret, OAUTHUrl).orElse(null);
|
||||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
} catch (IOException e) {
|
||||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")) {
|
log.error("Error retrieving ORCID access token, {} retries left", --maxClientRetries);
|
||||||
try {
|
|
||||||
responseObject = new JSONObject(inputStr);
|
|
||||||
} catch (Exception e) {
|
|
||||||
//Not as valid as I'd hoped, move along
|
|
||||||
responseObject = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (responseObject != null && responseObject.has("access_token")) {
|
|
||||||
accessToken = (String) responseObject.get("access_token");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error during initialization of the Orcid connector", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +102,7 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<AuthorityValue> queryAuthorities(String text, int max) {
|
public List<AuthorityValue> queryAuthorities(String text, int max) {
|
||||||
init();
|
initializeAccessToken();
|
||||||
List<Person> bios = queryBio(text, max);
|
List<Person> bios = queryBio(text, max);
|
||||||
List<AuthorityValue> result = new ArrayList<>();
|
List<AuthorityValue> result = new ArrayList<>();
|
||||||
for (Person person : bios) {
|
for (Person person : bios) {
|
||||||
@@ -135,7 +121,7 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthorityValue queryAuthorityID(String id) {
|
public AuthorityValue queryAuthorityID(String id) {
|
||||||
init();
|
initializeAccessToken();
|
||||||
Person person = getBio(id);
|
Person person = getBio(id);
|
||||||
AuthorityValue valueFromPerson = Orcidv3AuthorityValue.create(person);
|
AuthorityValue valueFromPerson = Orcidv3AuthorityValue.create(person);
|
||||||
return valueFromPerson;
|
return valueFromPerson;
|
||||||
@@ -151,11 +137,14 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
if (!isValid(id)) {
|
if (!isValid(id)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
init();
|
if (orcidRestConnector == null) {
|
||||||
|
log.error("ORCID REST connector is null, returning null Person");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
initializeAccessToken();
|
||||||
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
||||||
XMLtoBio converter = new XMLtoBio();
|
XMLtoBio converter = new XMLtoBio();
|
||||||
Person person = converter.convertSinglePerson(bioDocument);
|
return converter.convertSinglePerson(bioDocument);
|
||||||
return person;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -167,10 +156,16 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
|||||||
* @return List<Person>
|
* @return List<Person>
|
||||||
*/
|
*/
|
||||||
public List<Person> queryBio(String text, int start, int rows) {
|
public List<Person> queryBio(String text, int start, int rows) {
|
||||||
init();
|
|
||||||
if (rows > 100) {
|
if (rows > 100) {
|
||||||
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
||||||
}
|
}
|
||||||
|
// Check REST connector is initialized
|
||||||
|
if (orcidRestConnector == null) {
|
||||||
|
log.error("ORCID REST connector is not initialized, returning empty list");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
// Check / init access token
|
||||||
|
initializeAccessToken();
|
||||||
|
|
||||||
String searchPath = "search?q=" + URLEncoder.encode(text) + "&start=" + start + "&rows=" + rows;
|
String searchPath = "search?q=" + URLEncoder.encode(text) + "&start=" + start + "&rows=" + rows;
|
||||||
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
||||||
|
@@ -21,7 +21,7 @@ import jakarta.persistence.JoinColumn;
|
|||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.SequenceGenerator;
|
import jakarta.persistence.SequenceGenerator;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import org.apache.solr.common.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.HibernateProxyHelper;
|
import org.dspace.core.HibernateProxyHelper;
|
||||||
|
@@ -19,6 +19,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.dao.ResourcePolicyDAO;
|
import org.dspace.authorize.dao.ResourcePolicyDAO;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.authorize.service.ResourcePolicyService;
|
import org.dspace.authorize.service.ResourcePolicyService;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
@@ -51,6 +52,9 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private GroupService groupService;
|
private GroupService groupService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
protected ResourcePolicyServiceImpl() {
|
protected ResourcePolicyServiceImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,6 +426,6 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
|||||||
} else if (group != null && groupService.isMember(context, eperson, group)) {
|
} else if (group != null && groupService.isMember(context, eperson, group)) {
|
||||||
isMy = true;
|
isMy = true;
|
||||||
}
|
}
|
||||||
return isMy;
|
return isMy || authorizeService.isAdmin(context, eperson, resourcePolicy.getdSpaceObject());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,6 @@ import org.dspace.authorize.service.AuthorizeService;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.discovery.DiscoverFacetField;
|
|
||||||
import org.dspace.discovery.DiscoverQuery;
|
import org.dspace.discovery.DiscoverQuery;
|
||||||
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||||
import org.dspace.discovery.DiscoverResult;
|
import org.dspace.discovery.DiscoverResult;
|
||||||
@@ -34,7 +33,6 @@ import org.dspace.discovery.SearchService;
|
|||||||
import org.dspace.discovery.SearchServiceException;
|
import org.dspace.discovery.SearchServiceException;
|
||||||
import org.dspace.discovery.SearchUtils;
|
import org.dspace.discovery.SearchUtils;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
|
||||||
import org.dspace.discovery.indexobject.IndexableItem;
|
import org.dspace.discovery.indexobject.IndexableItem;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
@@ -181,32 +179,28 @@ public class SolrBrowseDAO implements BrowseDAO {
|
|||||||
addLocationScopeFilter(query);
|
addLocationScopeFilter(query);
|
||||||
addDefaultFilterQueries(query);
|
addDefaultFilterQueries(query);
|
||||||
if (distinct) {
|
if (distinct) {
|
||||||
DiscoverFacetField dff;
|
// We use a json.facet query for metadata browsing because it allows us to limit the results
|
||||||
|
// while obtaining the total number of facet values with numBuckets:true and sort in reverse order
|
||||||
// To get the number of distinct values we use the next "json.facet" query param
|
// Example of json.facet query:
|
||||||
// {"entries_count": {"type":"terms","field": "<fieldName>_filter", "limit":0, "numBuckets":true}}"
|
// {"<fieldName>": {"type":"terms","field": "<fieldName>_filter", "limit":0, "offset":0,
|
||||||
|
// "sort":"index desc", "numBuckets":true, "prefix":"<startsWith>"}}
|
||||||
ObjectNode jsonFacet = JsonNodeFactory.instance.objectNode();
|
ObjectNode jsonFacet = JsonNodeFactory.instance.objectNode();
|
||||||
ObjectNode entriesCount = JsonNodeFactory.instance.objectNode();
|
ObjectNode entriesFacet = JsonNodeFactory.instance.objectNode();
|
||||||
entriesCount.put("type", "terms");
|
entriesFacet.put("type", "terms");
|
||||||
entriesCount.put("field", facetField + "_filter");
|
entriesFacet.put("field", facetField + "_filter");
|
||||||
entriesCount.put("limit", 0);
|
entriesFacet.put("limit", limit);
|
||||||
entriesCount.put("numBuckets", true);
|
entriesFacet.put("offset", offset);
|
||||||
jsonFacet.set("entries_count", entriesCount);
|
entriesFacet.put("numBuckets", true);
|
||||||
|
if (ascending) {
|
||||||
if (StringUtils.isNotBlank(startsWith)) {
|
entriesFacet.put("sort", "index");
|
||||||
dff = new DiscoverFacetField(facetField,
|
|
||||||
DiscoveryConfigurationParameters.TYPE_TEXT, limit,
|
|
||||||
DiscoveryConfigurationParameters.SORT.VALUE, startsWith, offset);
|
|
||||||
|
|
||||||
// Add the prefix to the json facet query
|
|
||||||
entriesCount.put("prefix", startsWith);
|
|
||||||
} else {
|
} else {
|
||||||
dff = new DiscoverFacetField(facetField,
|
entriesFacet.put("sort", "index desc");
|
||||||
DiscoveryConfigurationParameters.TYPE_TEXT, limit,
|
|
||||||
DiscoveryConfigurationParameters.SORT.VALUE, offset);
|
|
||||||
}
|
}
|
||||||
query.addFacetField(dff);
|
if (StringUtils.isNotBlank(startsWith)) {
|
||||||
query.setFacetMinCount(1);
|
// Add the prefix to the json facet query
|
||||||
|
entriesFacet.put("prefix", startsWith);
|
||||||
|
}
|
||||||
|
jsonFacet.set(facetField, entriesFacet);
|
||||||
query.setMaxResults(0);
|
query.setMaxResults(0);
|
||||||
query.addProperty("json.facet", jsonFacet.toString());
|
query.addProperty("json.facet", jsonFacet.toString());
|
||||||
} else {
|
} else {
|
||||||
@@ -282,26 +276,15 @@ public class SolrBrowseDAO implements BrowseDAO {
|
|||||||
DiscoverResult resp = getSolrResponse();
|
DiscoverResult resp = getSolrResponse();
|
||||||
List<FacetResult> facet = resp.getFacetResult(facetField);
|
List<FacetResult> facet = resp.getFacetResult(facetField);
|
||||||
int count = doCountQuery();
|
int count = doCountQuery();
|
||||||
int start = 0;
|
|
||||||
int max = facet.size();
|
int max = facet.size();
|
||||||
List<String[]> result = new ArrayList<>();
|
List<String[]> result = new ArrayList<>();
|
||||||
if (ascending) {
|
|
||||||
for (int i = start; i < (start + max) && i < count; i++) {
|
for (int i = 0; i < max && i < count; i++) {
|
||||||
FacetResult c = facet.get(i);
|
FacetResult c = facet.get(i);
|
||||||
String freq = showFrequencies ? String.valueOf(c.getCount())
|
String freq = showFrequencies ? String.valueOf(c.getCount())
|
||||||
: "";
|
: "";
|
||||||
result.add(new String[] {c.getDisplayedValue(),
|
result.add(new String[] {c.getDisplayedValue(),
|
||||||
c.getAuthorityKey(), freq});
|
c.getAuthorityKey(), freq});
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = count - start - 1; i >= count - (start + max)
|
|
||||||
&& i >= 0; i--) {
|
|
||||||
FacetResult c = facet.get(i);
|
|
||||||
String freq = showFrequencies ? String.valueOf(c.getCount())
|
|
||||||
: "";
|
|
||||||
result.add(new String[] {c.getDisplayedValue(),
|
|
||||||
c.getAuthorityKey(), freq});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -362,9 +345,9 @@ public class SolrBrowseDAO implements BrowseDAO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isAscending) {
|
if (isAscending) {
|
||||||
query.setQuery("bi_" + column + "_sort" + ": [* TO \"" + value + "\"}");
|
query.setQuery("bi_" + column + "_sort" + ":[* TO \"" + value + "\"}");
|
||||||
} else {
|
} else {
|
||||||
query.setQuery("bi_" + column + "_sort" + ": {\"" + value + "\" TO *]");
|
query.setQuery("bi_" + column + "_sort" + ":{\"" + value + "\" TO *]");
|
||||||
query.addFilterQueries("-(bi_" + column + "_sort" + ":" + value + "*)");
|
query.addFilterQueries("-(bi_" + column + "_sort" + ":" + value + "*)");
|
||||||
}
|
}
|
||||||
DiscoverResult resp = null;
|
DiscoverResult resp = null;
|
||||||
|
@@ -1021,7 +1021,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
if (StringUtils.isNotBlank(q)) {
|
if (StringUtils.isNotBlank(q)) {
|
||||||
StringBuilder buildQuery = new StringBuilder();
|
StringBuilder buildQuery = new StringBuilder();
|
||||||
String escapedQuery = ClientUtils.escapeQueryChars(q);
|
String escapedQuery = ClientUtils.escapeQueryChars(q);
|
||||||
buildQuery.append("(").append(escapedQuery).append(" OR ").append(escapedQuery).append("*").append(")");
|
buildQuery.append("(").append(escapedQuery).append(" OR dc.title_sort:*")
|
||||||
|
.append(escapedQuery).append("*").append(")");
|
||||||
discoverQuery.setQuery(buildQuery.toString());
|
discoverQuery.setQuery(buildQuery.toString());
|
||||||
}
|
}
|
||||||
DiscoverResult resp = searchService.search(context, discoverQuery);
|
DiscoverResult resp = searchService.search(context, discoverQuery);
|
||||||
|
@@ -187,11 +187,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
String authority) {
|
String authority) {
|
||||||
List<MetadataValue> metadata = getMetadata(dso, schema, element, qualifier, lang);
|
List<MetadataValue> metadata = getMetadata(dso, schema, element, qualifier, lang);
|
||||||
List<MetadataValue> result = new ArrayList<>(metadata);
|
List<MetadataValue> result = new ArrayList<>(metadata);
|
||||||
if (!authority.equals(Item.ANY)) {
|
if (!Item.ANY.equals(authority)) {
|
||||||
Iterator<MetadataValue> iterator = result.iterator();
|
Iterator<MetadataValue> iterator = result.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
MetadataValue metadataValue = iterator.next();
|
MetadataValue metadataValue = iterator.next();
|
||||||
if (!authority.equals(metadataValue.getAuthority())) {
|
if (!StringUtils.equals(authority, metadataValue.getAuthority())) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,7 +509,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
MetadataField metadataField = metadataValue.getMetadataField();
|
MetadataField metadataField = metadataValue.getMetadataField();
|
||||||
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
|
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
|
||||||
// We will attempt to disprove a match - if we can't we have a match
|
// We will attempt to disprove a match - if we can't we have a match
|
||||||
if (!element.equals(Item.ANY) && !element.equals(metadataField.getElement())) {
|
if (!Item.ANY.equals(element) && !StringUtils.equals(element, metadataField.getElement())) {
|
||||||
// Elements do not match, no wildcard
|
// Elements do not match, no wildcard
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -520,9 +520,9 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
// Value is qualified, so no match
|
// Value is qualified, so no match
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!qualifier.equals(Item.ANY)) {
|
} else if (!Item.ANY.equals(qualifier)) {
|
||||||
// Not a wildcard, so qualifier must match exactly
|
// Not a wildcard, so qualifier must match exactly
|
||||||
if (!qualifier.equals(metadataField.getQualifier())) {
|
if (!StringUtils.equals(qualifier, metadataField.getQualifier())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,15 +533,15 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
// Value is qualified, so no match
|
// Value is qualified, so no match
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!language.equals(Item.ANY)) {
|
} else if (!Item.ANY.equals(language)) {
|
||||||
// Not a wildcard, so language must match exactly
|
// Not a wildcard, so language must match exactly
|
||||||
if (!language.equals(metadataValue.getLanguage())) {
|
if (!StringUtils.equals(language, metadataValue.getLanguage())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!schema.equals(Item.ANY)) {
|
if (!Item.ANY.equals(schema)) {
|
||||||
if (metadataSchema != null && !metadataSchema.getName().equals(schema)) {
|
if (!StringUtils.equals(schema, metadataSchema.getName())) {
|
||||||
// The namespace doesn't match
|
// The namespace doesn't match
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import org.dspace.core.Constants;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.handle.factory.HandleServiceFactory;
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,6 +37,11 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DSpaceObjectUtils dSpaceObjectUtils;
|
private DSpaceObjectUtils dSpaceObjectUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
private int csxExportLimit = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DSpaceCSV handleExport(Context context, boolean exportAllItems, boolean exportAllMetadata, String identifier,
|
public DSpaceCSV handleExport(Context context, boolean exportAllItems, boolean exportAllMetadata, String identifier,
|
||||||
DSpaceRunnableHandler handler) throws Exception {
|
DSpaceRunnableHandler handler) throws Exception {
|
||||||
@@ -43,7 +49,7 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
|
|
||||||
if (exportAllItems) {
|
if (exportAllItems) {
|
||||||
handler.logInfo("Exporting whole repository WARNING: May take some time!");
|
handler.logInfo("Exporting whole repository WARNING: May take some time!");
|
||||||
toExport = itemService.findAll(context);
|
toExport = itemService.findAll(context, getCsvExportLimit(), 0);
|
||||||
} else {
|
} else {
|
||||||
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService()
|
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService()
|
||||||
.resolveToObject(context, identifier);
|
.resolveToObject(context, identifier);
|
||||||
@@ -63,7 +69,7 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
} else if (dso.getType() == Constants.COLLECTION) {
|
} else if (dso.getType() == Constants.COLLECTION) {
|
||||||
handler.logInfo("Exporting collection '" + dso.getName() + "' (" + identifier + ")");
|
handler.logInfo("Exporting collection '" + dso.getName() + "' (" + identifier + ")");
|
||||||
Collection collection = (Collection) dso;
|
Collection collection = (Collection) dso;
|
||||||
toExport = itemService.findByCollection(context, collection);
|
toExport = itemService.findByCollection(context, collection, getCsvExportLimit(), 0);
|
||||||
} else if (dso.getType() == Constants.COMMUNITY) {
|
} else if (dso.getType() == Constants.COMMUNITY) {
|
||||||
handler.logInfo("Exporting community '" + dso.getName() + "' (" + identifier + ")");
|
handler.logInfo("Exporting community '" + dso.getName() + "' (" + identifier + ")");
|
||||||
toExport = buildFromCommunity(context, (Community) dso);
|
toExport = buildFromCommunity(context, (Community) dso);
|
||||||
@@ -74,18 +80,21 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DSpaceCSV csv = this.export(context, toExport, exportAllMetadata);
|
DSpaceCSV csv = this.export(context, toExport, exportAllMetadata, handler);
|
||||||
return csv;
|
return csv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DSpaceCSV export(Context context, Iterator<Item> toExport, boolean exportAll) throws Exception {
|
public DSpaceCSV export(Context context, Iterator<Item> toExport,
|
||||||
|
boolean exportAll, DSpaceRunnableHandler handler) throws Exception {
|
||||||
Context.Mode originalMode = context.getCurrentMode();
|
Context.Mode originalMode = context.getCurrentMode();
|
||||||
context.setMode(Context.Mode.READ_ONLY);
|
context.setMode(Context.Mode.READ_ONLY);
|
||||||
|
|
||||||
// Process each item
|
// Process each item until we reach the limit
|
||||||
|
int itemExportLimit = getCsvExportLimit();
|
||||||
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
||||||
while (toExport.hasNext()) {
|
|
||||||
|
for (int itemsAdded = 0; toExport.hasNext() && itemsAdded < itemExportLimit; itemsAdded++) {
|
||||||
Item item = toExport.next();
|
Item item = toExport.next();
|
||||||
csv.addItem(item);
|
csv.addItem(item);
|
||||||
context.uncacheEntity(item);
|
context.uncacheEntity(item);
|
||||||
@@ -97,8 +106,9 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DSpaceCSV export(Context context, Community community, boolean exportAll) throws Exception {
|
public DSpaceCSV export(Context context, Community community,
|
||||||
return export(context, buildFromCommunity(context, community), exportAll);
|
boolean exportAll, DSpaceRunnableHandler handler) throws Exception {
|
||||||
|
return export(context, buildFromCommunity(context, community), exportAll, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,21 +127,30 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
|||||||
// Add all the collections
|
// Add all the collections
|
||||||
List<Collection> collections = community.getCollections();
|
List<Collection> collections = community.getCollections();
|
||||||
for (Collection collection : collections) {
|
for (Collection collection : collections) {
|
||||||
Iterator<Item> items = itemService.findByCollection(context, collection);
|
// Never obtain more items than the configured limit
|
||||||
while (items.hasNext()) {
|
Iterator<Item> items = itemService.findByCollection(context, collection, getCsvExportLimit(), 0);
|
||||||
|
while (result.size() < getCsvExportLimit() && items.hasNext()) {
|
||||||
result.add(items.next());
|
result.add(items.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the sub-communities
|
// Add all the sub-communities
|
||||||
List<Community> communities = community.getSubcommunities();
|
List<Community> communities = community.getSubcommunities();
|
||||||
for (Community subCommunity : communities) {
|
for (Community subCommunity : communities) {
|
||||||
Iterator<Item> items = buildFromCommunity(context, subCommunity);
|
Iterator<Item> items = buildFromCommunity(context, subCommunity);
|
||||||
while (items.hasNext()) {
|
while (result.size() < getCsvExportLimit() && items.hasNext()) {
|
||||||
result.add(items.next());
|
result.add(items.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.iterator();
|
return result.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCsvExportLimit() {
|
||||||
|
if (csxExportLimit == -1) {
|
||||||
|
csxExportLimit = configurationService.getIntProperty("bulkedit.export.max.items", 500);
|
||||||
|
}
|
||||||
|
return csxExportLimit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -571,13 +571,17 @@ public final class ChoiceAuthorityServiceImpl implements ChoiceAuthorityService
|
|||||||
|
|
||||||
Set<String> metadataFields = new HashSet<>();
|
Set<String> metadataFields = new HashSet<>();
|
||||||
Map<String, List<String>> formsToFields = this.authoritiesFormDefinitions.get(nameVocab);
|
Map<String, List<String>> formsToFields = this.authoritiesFormDefinitions.get(nameVocab);
|
||||||
|
// Vocabulary is not associated with any form definition, meaning it won't be a browse index
|
||||||
|
if (formsToFields == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
for (Map.Entry<String, List<String>> formToField : formsToFields.entrySet()) {
|
for (Map.Entry<String, List<String>> formToField : formsToFields.entrySet()) {
|
||||||
metadataFields.addAll(formToField.getValue().stream().map(value ->
|
metadataFields.addAll(formToField.getValue().stream().map(value ->
|
||||||
StringUtils.replace(value, "_", "."))
|
StringUtils.replace(value, "_", "."))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
DiscoverySearchFilterFacet matchingFacet = null;
|
DiscoverySearchFilterFacet matchingFacet = null;
|
||||||
for (DiscoverySearchFilterFacet facetConfig : searchConfigurationService.getAllFacetsConfig()) {
|
for (DiscoverySearchFilterFacet facetConfig : searchConfigurationService.getAllUniqueFacetsConfig()) {
|
||||||
boolean coversAllFieldsFromVocab = true;
|
boolean coversAllFieldsFromVocab = true;
|
||||||
for (String fieldFromVocab: metadataFields) {
|
for (String fieldFromVocab: metadataFields) {
|
||||||
boolean coversFieldFromVocab = false;
|
boolean coversFieldFromVocab = false;
|
||||||
|
@@ -11,8 +11,6 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -21,7 +19,11 @@ import java.util.zip.ZipEntry;
|
|||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.BitstreamFormat;
|
import org.dspace.content.BitstreamFormat;
|
||||||
@@ -1310,13 +1312,12 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester {
|
|||||||
if (params.getBooleanProperty("manifestOnly", false)) {
|
if (params.getBooleanProperty("manifestOnly", false)) {
|
||||||
// NOTE: since we are only dealing with a METS manifest,
|
// NOTE: since we are only dealing with a METS manifest,
|
||||||
// we will assume all external files are available via URLs.
|
// we will assume all external files are available via URLs.
|
||||||
try {
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
// attempt to open a connection to given URL
|
// attempt to open a connection to given URL
|
||||||
URL fileURL = new URL(path);
|
try (CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(path))) {
|
||||||
URLConnection connection = fileURL.openConnection();
|
// open stream to access file contents
|
||||||
|
return httpResponse.getEntity().getContent();
|
||||||
// open stream to access file contents
|
}
|
||||||
return connection.getInputStream();
|
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
log
|
log
|
||||||
.error("Unable to retrieve external file from URL '"
|
.error("Unable to retrieve external file from URL '"
|
||||||
|
@@ -202,7 +202,7 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
|
|||||||
* Get the value(s) of a metadata field.
|
* Get the value(s) of a metadata field.
|
||||||
* @param dSpaceObject the object whose metadata are sought.
|
* @param dSpaceObject the object whose metadata are sought.
|
||||||
* @param mdString the name of the field: {@code schema.element.qualifier}.
|
* @param mdString the name of the field: {@code schema.element.qualifier}.
|
||||||
* @param authority name of the authority which controls these values, or null.
|
* @param authority name of the authority which controls these values, or Item.ANY, or null.
|
||||||
* @return all matching metadata values, or null if none.
|
* @return all matching metadata values, or null if none.
|
||||||
*/
|
*/
|
||||||
public List<MetadataValue> getMetadata(T dSpaceObject, String mdString, String authority);
|
public List<MetadataValue> getMetadata(T dSpaceObject, String mdString, String authority);
|
||||||
@@ -216,7 +216,7 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
|
|||||||
* @param lang the language of the requested field value(s),
|
* @param lang the language of the requested field value(s),
|
||||||
* null if explicitly no language,
|
* null if explicitly no language,
|
||||||
* or {@link org.dspace.content.Item.ANY} to match all languages.
|
* or {@link org.dspace.content.Item.ANY} to match all languages.
|
||||||
* @param authority name of the authority which controls these values, or null.
|
* @param authority name of the authority which controls these values, or Item.ANY, or null.
|
||||||
* @return value(s) of the indicated field for the given DSO, or null.
|
* @return value(s) of the indicated field for the given DSO, or null.
|
||||||
*/
|
*/
|
||||||
public List<MetadataValue> getMetadata(T dSpaceObject, String schema,
|
public List<MetadataValue> getMetadata(T dSpaceObject, String schema,
|
||||||
|
@@ -44,7 +44,8 @@ public interface MetadataDSpaceCsvExportService {
|
|||||||
* @return A DSpaceCSV object containing the exported information
|
* @return A DSpaceCSV object containing the exported information
|
||||||
* @throws Exception If something goes wrong
|
* @throws Exception If something goes wrong
|
||||||
*/
|
*/
|
||||||
public DSpaceCSV export(Context context, Iterator<Item> toExport, boolean exportAll) throws Exception;
|
public DSpaceCSV export(Context context, Iterator<Item> toExport,
|
||||||
|
boolean exportAll, DSpaceRunnableHandler handler) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will export all the Items within the given Community to a DSpaceCSV
|
* This method will export all the Items within the given Community to a DSpaceCSV
|
||||||
@@ -54,6 +55,9 @@ public interface MetadataDSpaceCsvExportService {
|
|||||||
* @return A DSpaceCSV object containing the exported information
|
* @return A DSpaceCSV object containing the exported information
|
||||||
* @throws Exception If something goes wrong
|
* @throws Exception If something goes wrong
|
||||||
*/
|
*/
|
||||||
public DSpaceCSV export(Context context, Community community, boolean exportAll) throws Exception;
|
public DSpaceCSV export(Context context, Community community,
|
||||||
|
boolean exportAll, DSpaceRunnableHandler handler) throws Exception;
|
||||||
|
|
||||||
}
|
int getCsvExportLimit();
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -55,7 +55,7 @@ import org.dspace.services.ConfigurationService;
|
|||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing an e-mail message. The {@link send} method causes the
|
* Builder representing an e-mail message. The {@link send} method causes the
|
||||||
* assembled message to be formatted and sent.
|
* assembled message to be formatted and sent.
|
||||||
* <p>
|
* <p>
|
||||||
* Typical use:
|
* Typical use:
|
||||||
@@ -168,6 +168,9 @@ public class Email {
|
|||||||
*/
|
*/
|
||||||
private String charset;
|
private String charset;
|
||||||
|
|
||||||
|
/** The message being assembled. */
|
||||||
|
MimeMessage message;
|
||||||
|
|
||||||
private static final Logger LOG = LogManager.getLogger();
|
private static final Logger LOG = LogManager.getLogger();
|
||||||
|
|
||||||
/** Velocity template settings. */
|
/** Velocity template settings. */
|
||||||
@@ -188,6 +191,9 @@ public class Email {
|
|||||||
/** Velocity template for a message body */
|
/** Velocity template for a message body */
|
||||||
private Template template;
|
private Template template;
|
||||||
|
|
||||||
|
/** The message text. */
|
||||||
|
private String body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new email message.
|
* Create a new email message.
|
||||||
*/
|
*/
|
||||||
@@ -254,9 +260,15 @@ public class Email {
|
|||||||
/**
|
/**
|
||||||
* Fill out the next argument in the template.
|
* Fill out the next argument in the template.
|
||||||
*
|
*
|
||||||
* @param arg the value for the next argument
|
* @param arg the value for the next argument. If {@code null},
|
||||||
|
* a zero-length string is substituted.
|
||||||
*/
|
*/
|
||||||
public void addArgument(Object arg) {
|
public void addArgument(Object arg) {
|
||||||
|
if (null == arg) {
|
||||||
|
arg = "";
|
||||||
|
LOG.warn("Null argument {} to email template {} replaced with zero-length string",
|
||||||
|
arguments.size(), contentName);
|
||||||
|
}
|
||||||
arguments.add(arg);
|
arguments.add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +339,27 @@ public class Email {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the email. If the template defines a Velocity context property
|
* Sends the email. If sending is disabled then the assembled message is
|
||||||
|
* logged instead.
|
||||||
|
*
|
||||||
|
* @throws MessagingException if there was a problem sending the mail.
|
||||||
|
* @throws IOException if IO error
|
||||||
|
*/
|
||||||
|
public void send() throws MessagingException, IOException {
|
||||||
|
build();
|
||||||
|
|
||||||
|
ConfigurationService config
|
||||||
|
= DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
boolean disabled = config.getBooleanProperty("mail.server.disabled", false);
|
||||||
|
if (disabled) {
|
||||||
|
LOG.info(format(message, body));
|
||||||
|
} else {
|
||||||
|
Transport.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message. If the template defines a Velocity context property
|
||||||
* named among the values of DSpace configuration property
|
* named among the values of DSpace configuration property
|
||||||
* {@code mail.message.headers} then that name and its value will be added
|
* {@code mail.message.headers} then that name and its value will be added
|
||||||
* to the message's headers.
|
* to the message's headers.
|
||||||
@@ -336,11 +368,12 @@ public class Email {
|
|||||||
* called, the value of any "subject" property will be used as if setSubject
|
* called, the value of any "subject" property will be used as if setSubject
|
||||||
* had been called with that value. Thus a template may define its subject,
|
* had been called with that value. Thus a template may define its subject,
|
||||||
* but the caller may override it.
|
* but the caller may override it.
|
||||||
*
|
*
|
||||||
* @throws MessagingException if there was a problem sending the mail.
|
* @throws MessagingException if there is no template, or passed through.
|
||||||
* @throws IOException if IO error
|
* @throws IOException passed through.
|
||||||
*/
|
*/
|
||||||
public void send() throws MessagingException, IOException {
|
void build()
|
||||||
|
throws MessagingException, IOException {
|
||||||
if (null == template) {
|
if (null == template) {
|
||||||
// No template -- no content -- PANIC!!!
|
// No template -- no content -- PANIC!!!
|
||||||
throw new MessagingException("Email has no body");
|
throw new MessagingException("Email has no body");
|
||||||
@@ -351,7 +384,6 @@ public class Email {
|
|||||||
|
|
||||||
// Get the mail configuration properties
|
// Get the mail configuration properties
|
||||||
String from = config.getProperty("mail.from.address");
|
String from = config.getProperty("mail.from.address");
|
||||||
boolean disabled = config.getBooleanProperty("mail.server.disabled", false);
|
|
||||||
|
|
||||||
// If no character set specified, attempt to retrieve a default
|
// If no character set specified, attempt to retrieve a default
|
||||||
if (charset == null) {
|
if (charset == null) {
|
||||||
@@ -362,7 +394,7 @@ public class Email {
|
|||||||
Session session = DSpaceServicesFactory.getInstance().getEmailService().getSession();
|
Session session = DSpaceServicesFactory.getInstance().getEmailService().getSession();
|
||||||
|
|
||||||
// Create message
|
// Create message
|
||||||
MimeMessage message = new MimeMessage(session);
|
message = new MimeMessage(session);
|
||||||
|
|
||||||
// Set the recipients of the message
|
// Set the recipients of the message
|
||||||
for (String recipient : recipients) {
|
for (String recipient : recipients) {
|
||||||
@@ -385,7 +417,7 @@ public class Email {
|
|||||||
LOG.error("Template not merged: {}", ex.getMessage());
|
LOG.error("Template not merged: {}", ex.getMessage());
|
||||||
throw new MessagingException("Template not merged", ex);
|
throw new MessagingException("Template not merged", ex);
|
||||||
}
|
}
|
||||||
String fullMessage = writer.toString();
|
body = writer.toString();
|
||||||
|
|
||||||
// Set some message header fields
|
// Set some message header fields
|
||||||
Instant date = Instant.now();
|
Instant date = Instant.now();
|
||||||
@@ -412,20 +444,19 @@ public class Email {
|
|||||||
message.setSubject(subject);
|
message.setSubject(subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add attachments
|
// Attach the body.
|
||||||
if (attachments.isEmpty() && moreAttachments.isEmpty()) {
|
if (attachments.isEmpty() && moreAttachments.isEmpty()) { // Flat body.
|
||||||
// If a character set has been specified, or a default exists
|
|
||||||
if (charset != null) {
|
if (charset != null) {
|
||||||
message.setText(fullMessage, charset);
|
message.setText(body, charset);
|
||||||
} else {
|
} else {
|
||||||
message.setText(fullMessage);
|
message.setText(body);
|
||||||
}
|
}
|
||||||
} else {
|
} else { // Add attachments.
|
||||||
Multipart multipart = new MimeMultipart();
|
Multipart multipart = new MimeMultipart();
|
||||||
|
|
||||||
// create the first part of the email
|
// create the first part of the email
|
||||||
BodyPart messageBodyPart = new MimeBodyPart();
|
BodyPart messageBodyPart = new MimeBodyPart();
|
||||||
messageBodyPart.setText(fullMessage);
|
messageBodyPart.setText(body);
|
||||||
multipart.addBodyPart(messageBodyPart);
|
multipart.addBodyPart(messageBodyPart);
|
||||||
|
|
||||||
// Add file attachments
|
// Add file attachments
|
||||||
@@ -457,30 +488,47 @@ public class Email {
|
|||||||
replyToAddr[0] = new InternetAddress(replyTo);
|
replyToAddr[0] = new InternetAddress(replyTo);
|
||||||
message.setReplyTo(replyToAddr);
|
message.setReplyTo(replyToAddr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (disabled) {
|
/**
|
||||||
StringBuilder text = new StringBuilder(
|
* Flatten the email into a string.
|
||||||
"Message not sent due to mail.server.disabled:\n");
|
*
|
||||||
|
* @param message the message headers, attachments, etc.
|
||||||
|
* @param body the message body.
|
||||||
|
* @return stringified email message.
|
||||||
|
* @throws MessagingException passed through.
|
||||||
|
*/
|
||||||
|
private String format(MimeMessage message, String body)
|
||||||
|
throws MessagingException {
|
||||||
|
StringBuilder text = new StringBuilder(
|
||||||
|
"Message not sent due to mail.server.disabled:\n");
|
||||||
|
|
||||||
Enumeration<String> headers = message.getAllHeaderLines();
|
Enumeration<String> headers = message.getAllHeaderLines();
|
||||||
while (headers.hasMoreElements()) {
|
while (headers.hasMoreElements()) {
|
||||||
text.append(headers.nextElement()).append('\n');
|
text.append(headers.nextElement()).append('\n');
|
||||||
}
|
|
||||||
|
|
||||||
if (!attachments.isEmpty()) {
|
|
||||||
text.append("\nAttachments:\n");
|
|
||||||
for (FileAttachment f : attachments) {
|
|
||||||
text.append(f.name).append('\n');
|
|
||||||
}
|
|
||||||
text.append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
text.append('\n').append(fullMessage);
|
|
||||||
|
|
||||||
LOG.info(text.toString());
|
|
||||||
} else {
|
|
||||||
Transport.send(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!attachments.isEmpty()) {
|
||||||
|
text.append("\nAttachments:\n");
|
||||||
|
for (FileAttachment f : attachments) {
|
||||||
|
text.append(f.name).append('\n');
|
||||||
|
}
|
||||||
|
text.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
text.append('\n').append(body);
|
||||||
|
return text.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the formatted message for testing.
|
||||||
|
*
|
||||||
|
* @return the message flattened to a String.
|
||||||
|
* @throws MessagingException passed through.
|
||||||
|
*/
|
||||||
|
String getMessage()
|
||||||
|
throws MessagingException {
|
||||||
|
return format(message, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -500,4 +500,5 @@ public final class Utils {
|
|||||||
return LocalDateTime.of(-4713, 11, 12, 0, 0, 0)
|
return LocalDateTime.of(-4713, 11, 12, 0, 0, 0)
|
||||||
.toInstant(ZoneOffset.UTC);
|
.toInstant(ZoneOffset.UTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -9,11 +9,15 @@ package org.dspace.ctask.general;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
@@ -135,24 +139,20 @@ public class BasicLinkChecker extends AbstractCurationTask {
|
|||||||
* @return The HTTP response code (e.g. 200 / 301 / 404 / 500)
|
* @return The HTTP response code (e.g. 200 / 301 / 404 / 500)
|
||||||
*/
|
*/
|
||||||
protected int getResponseStatus(String url, int redirects) {
|
protected int getResponseStatus(String url, int redirects) {
|
||||||
try {
|
RequestConfig config = RequestConfig.custom().setRedirectsEnabled(true).build();
|
||||||
URL theURL = new URL(url);
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config)) {
|
||||||
HttpURLConnection connection = (HttpURLConnection) theURL.openConnection();
|
CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(url));
|
||||||
connection.setInstanceFollowRedirects(true);
|
int statusCode = httpResponse.getStatusLine().getStatusCode();
|
||||||
int statusCode = connection.getResponseCode();
|
|
||||||
int maxRedirect = configurationService.getIntProperty("curate.checklinks.max-redirect", 0);
|
int maxRedirect = configurationService.getIntProperty("curate.checklinks.max-redirect", 0);
|
||||||
if ((statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM ||
|
if ((statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM ||
|
||||||
statusCode == HttpURLConnection.HTTP_SEE_OTHER)) {
|
statusCode == HttpURLConnection.HTTP_SEE_OTHER)) {
|
||||||
connection.disconnect();
|
String newUrl = httpResponse.getFirstHeader("Location").getValue();
|
||||||
String newUrl = connection.getHeaderField("Location");
|
|
||||||
if (newUrl != null && (maxRedirect >= redirects || maxRedirect == -1)) {
|
if (newUrl != null && (maxRedirect >= redirects || maxRedirect == -1)) {
|
||||||
redirects++;
|
redirects++;
|
||||||
return getResponseStatus(newUrl, redirects);
|
return getResponseStatus(newUrl, redirects);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return statusCode;
|
return statusCode;
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
// Must be a bad URL
|
// Must be a bad URL
|
||||||
log.debug("Bad link: " + ioe.getMessage());
|
log.debug("Bad link: " + ioe.getMessage());
|
||||||
|
@@ -30,13 +30,13 @@ import javax.xml.xpath.XPathExpressionException;
|
|||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
@@ -255,53 +255,50 @@ public class MetadataWebService extends AbstractCurationTask implements Namespac
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected int callService(String value, Item item, StringBuilder resultSb) throws IOException {
|
protected int callService(String value, Item item, StringBuilder resultSb) throws IOException {
|
||||||
|
|
||||||
String callUrl = urlTemplate.replaceAll("\\{" + templateParam + "\\}", value);
|
String callUrl = urlTemplate.replaceAll("\\{" + templateParam + "\\}", value);
|
||||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpGet req = new HttpGet(callUrl);
|
HttpGet req = new HttpGet(callUrl);
|
||||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||||
req.addHeader(entry.getKey(), entry.getValue());
|
req.addHeader(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
HttpResponse resp = client.execute(req);
|
try (CloseableHttpResponse resp = client.execute(req)) {
|
||||||
int status = Curator.CURATE_ERROR;
|
int status = Curator.CURATE_ERROR;
|
||||||
int statusCode = resp.getStatusLine().getStatusCode();
|
int statusCode = resp.getStatusLine().getStatusCode();
|
||||||
if (statusCode == HttpStatus.SC_OK) {
|
if (statusCode == HttpStatus.SC_OK) {
|
||||||
HttpEntity entity = resp.getEntity();
|
HttpEntity entity = resp.getEntity();
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
// boiler-plate handling taken from Apache 4.1 javadoc
|
// boiler-plate handling taken from Apache 4.1 javadoc
|
||||||
InputStream instream = entity.getContent();
|
InputStream instream = entity.getContent();
|
||||||
try {
|
try {
|
||||||
// This next line triggers a false-positive XXE warning from LGTM, even though we disallow DTD
|
// This next line triggers a false-positive XXE warning from LGTM, even though
|
||||||
// parsing during initialization of docBuilder in init()
|
// we disallow DTD parsing during initialization of docBuilder in init()
|
||||||
Document doc = docBuilder.parse(instream); // lgtm [java/xxe]
|
Document doc = docBuilder.parse(instream); // lgtm [java/xxe]
|
||||||
status = processResponse(doc, item, resultSb);
|
status = processResponse(doc, item, resultSb);
|
||||||
} catch (SAXException saxE) {
|
} catch (SAXException saxE) {
|
||||||
log.error("caught exception: " + saxE);
|
log.error("caught exception: " + saxE);
|
||||||
resultSb.append(" unable to read response document");
|
resultSb.append(" unable to read response document");
|
||||||
} catch (RuntimeException ex) {
|
} catch (RuntimeException ex) {
|
||||||
// In case of an unexpected exception you may want to abort
|
// In case of an unexpected exception you may want to abort
|
||||||
// the HTTP request in order to shut down the underlying
|
// the HTTP request in order to shut down the underlying
|
||||||
// connection and release it back to the connection manager.
|
// connection and release it back to the connection manager.
|
||||||
req.abort();
|
req.abort();
|
||||||
log.error("caught exception: " + ex);
|
log.error("caught exception: " + ex);
|
||||||
throw ex;
|
throw ex;
|
||||||
} finally {
|
} finally {
|
||||||
// Closing the input stream will trigger connection release
|
// Closing the input stream will trigger connection release
|
||||||
instream.close();
|
instream.close();
|
||||||
}
|
}
|
||||||
// When HttpClient instance is no longer needed,
|
} else {
|
||||||
// shut down the connection manager to ensure
|
log.error(" obtained no valid service response");
|
||||||
// immediate deallocation of all system resources
|
resultSb.append("no service response");
|
||||||
client.close();
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error(" obtained no valid service response");
|
log.error("service returned non-OK status: " + statusCode);
|
||||||
resultSb.append("no service response");
|
resultSb.append("no service response");
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.error("service returned non-OK status: " + statusCode);
|
|
||||||
resultSb.append("no service response");
|
|
||||||
}
|
}
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int processResponse(Document doc, Item item, StringBuilder resultSb) throws IOException {
|
protected int processResponse(Document doc, Item item, StringBuilder resultSb) throws IOException {
|
||||||
|
@@ -12,12 +12,12 @@ import java.net.URLEncoder;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
@@ -60,22 +60,20 @@ public class MicrosoftTranslator extends AbstractTranslator {
|
|||||||
String url = baseUrl + "?appId=" + apiKey;
|
String url = baseUrl + "?appId=" + apiKey;
|
||||||
url += "&to=" + to + "&from=" + from + "&text=" + text;
|
url += "&to=" + to + "&from=" + from + "&text=" + text;
|
||||||
|
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpGet hm = new HttpGet(url);
|
HttpGet hm = new HttpGet(url);
|
||||||
HttpResponse httpResponse = client.execute(hm);
|
try (CloseableHttpResponse httpResponse = client.execute(hm)) {
|
||||||
log.debug("Response code from API call is " + httpResponse);
|
log.debug("Response code from API call is " + httpResponse);
|
||||||
|
if (httpResponse.getStatusLine().getStatusCode() == 200) {
|
||||||
if (httpResponse.getStatusLine().getStatusCode() == 200) {
|
String response = IOUtils.toString(httpResponse.getEntity().getContent(),
|
||||||
String response = IOUtils.toString(httpResponse.getEntity().getContent(),
|
StandardCharsets.ISO_8859_1);
|
||||||
StandardCharsets.ISO_8859_1);
|
response = response
|
||||||
response = response
|
.replaceAll("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", "");
|
||||||
.replaceAll("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", "");
|
response = response.replaceAll("</string>", "");
|
||||||
response = response.replaceAll("</string>", "");
|
translatedText = response;
|
||||||
translatedText = response;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return translatedText;
|
return translatedText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -25,6 +25,8 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.commons.io.output.NullOutputStream;
|
import org.apache.commons.io.output.NullOutputStream;
|
||||||
|
import org.dspace.app.util.DSpaceObjectUtilsImpl;
|
||||||
|
import org.dspace.app.util.service.DSpaceObjectUtils;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
@@ -36,6 +38,7 @@ import org.dspace.eperson.service.EPersonService;
|
|||||||
import org.dspace.handle.factory.HandleServiceFactory;
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
import org.dspace.handle.service.HandleService;
|
import org.dspace.handle.service.HandleService;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +49,9 @@ import org.dspace.utils.DSpace;
|
|||||||
public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
||||||
|
|
||||||
protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||||
|
protected DSpaceObjectUtils dspaceObjectUtils = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
|
.getServiceByName(DSpaceObjectUtilsImpl.class.getName(), DSpaceObjectUtilsImpl.class);
|
||||||
|
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||||
protected Context context;
|
protected Context context;
|
||||||
private CurationClientOptions curationClientOptions;
|
private CurationClientOptions curationClientOptions;
|
||||||
|
|
||||||
@@ -346,9 +351,29 @@ public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
|||||||
|
|
||||||
if (this.commandLine.hasOption('i')) {
|
if (this.commandLine.hasOption('i')) {
|
||||||
this.id = this.commandLine.getOptionValue('i').toLowerCase();
|
this.id = this.commandLine.getOptionValue('i').toLowerCase();
|
||||||
|
DSpaceObject dso;
|
||||||
if (!this.id.equalsIgnoreCase("all")) {
|
if (!this.id.equalsIgnoreCase("all")) {
|
||||||
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
// First, try to parse the id as a UUID. If that fails, treat it as a handle.
|
||||||
DSpaceObject dso;
|
UUID uuid = null;
|
||||||
|
try {
|
||||||
|
uuid = UUID.fromString(id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// It's not a UUID, proceed to treat it as a handle.
|
||||||
|
}
|
||||||
|
if (uuid != null) {
|
||||||
|
try {
|
||||||
|
dso = dspaceObjectUtils.findDSpaceObject(context, uuid);
|
||||||
|
if (dso != null) {
|
||||||
|
// We already resolved an object, return early
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String error = "SQLException trying to find dso with uuid " + uuid;
|
||||||
|
super.handler.logError(error);
|
||||||
|
throw new RuntimeException(error, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we get here, the id is not a UUID, so we assume it's a handle.
|
||||||
try {
|
try {
|
||||||
dso = handleService.resolveToObject(this.context, id);
|
dso = handleService.resolveToObject(this.context, id);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableItem;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This plugin adds indicators to the solr document to determine if the item
|
||||||
|
* has geospatial metadata
|
||||||
|
*
|
||||||
|
* The facet is added to Discovery in the usual way (create a searchFilter bean
|
||||||
|
* and add it to the expected place) just with an empty list of used metadata
|
||||||
|
* fields because there are none.
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SolrServiceGeospatialFilterPlugin implements SolrServiceIndexPlugin {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ConfigurationService configurationService;
|
||||||
|
@Autowired
|
||||||
|
ItemService itemService;
|
||||||
|
@Override
|
||||||
|
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
|
||||||
|
if (indexableObject instanceof IndexableItem) {
|
||||||
|
Item item = ((IndexableItem) indexableObject).getIndexedObject();
|
||||||
|
// Get configured field name
|
||||||
|
String geospatialField = configurationService.getProperty("discovery.filter.geospatial.field");
|
||||||
|
if (geospatialField == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String[] fieldParts = geospatialField.split("\\.", 3);
|
||||||
|
if (fieldParts.length < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean hasGeospatialMetadata = itemService.getMetadataFirstValue(item,
|
||||||
|
fieldParts[0], fieldParts[1], fieldParts.length > 2 ? fieldParts[2] : null, Item.ANY) != null;
|
||||||
|
|
||||||
|
// also add _keyword and _filter because
|
||||||
|
// they are needed in order to work as a facet and filter.
|
||||||
|
document.addField("has_geospatial_metadata", hasGeospatialMetadata);
|
||||||
|
document.addField("has_geospatial_metadata_keyword", hasGeospatialMetadata);
|
||||||
|
document.addField("has_geospatial_metadata_filter", hasGeospatialMetadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -38,6 +38,7 @@ import org.apache.solr.client.solrj.SolrServerException;
|
|||||||
import org.apache.solr.client.solrj.response.FacetField;
|
import org.apache.solr.client.solrj.response.FacetField;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
import org.apache.solr.client.solrj.response.json.BucketBasedJsonFacet;
|
import org.apache.solr.client.solrj.response.json.BucketBasedJsonFacet;
|
||||||
|
import org.apache.solr.client.solrj.response.json.BucketJsonFacet;
|
||||||
import org.apache.solr.client.solrj.response.json.NestableJsonFacet;
|
import org.apache.solr.client.solrj.response.json.NestableJsonFacet;
|
||||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||||
import org.apache.solr.common.SolrDocument;
|
import org.apache.solr.common.SolrDocument;
|
||||||
@@ -70,6 +71,7 @@ import org.dspace.discovery.indexobject.IndexableCommunity;
|
|||||||
import org.dspace.discovery.indexobject.IndexableItem;
|
import org.dspace.discovery.indexobject.IndexableItem;
|
||||||
import org.dspace.discovery.indexobject.factory.IndexFactory;
|
import org.dspace.discovery.indexobject.factory.IndexFactory;
|
||||||
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
|
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
|
||||||
|
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||||
import org.dspace.eperson.service.GroupService;
|
import org.dspace.eperson.service.GroupService;
|
||||||
@@ -339,6 +341,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
try {
|
try {
|
||||||
final List<IndexFactory> indexableObjectServices = indexObjectServiceFactory.
|
final List<IndexFactory> indexableObjectServices = indexObjectServiceFactory.
|
||||||
getIndexFactories();
|
getIndexFactories();
|
||||||
|
int indexObject = 0;
|
||||||
for (IndexFactory indexableObjectService : indexableObjectServices) {
|
for (IndexFactory indexableObjectService : indexableObjectServices) {
|
||||||
if (type == null || StringUtils.equals(indexableObjectService.getType(), type)) {
|
if (type == null || StringUtils.equals(indexableObjectService.getType(), type)) {
|
||||||
final Iterator<IndexableObject> indexableObjects = indexableObjectService.findAll(context);
|
final Iterator<IndexableObject> indexableObjects = indexableObjectService.findAll(context);
|
||||||
@@ -346,6 +349,10 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
final IndexableObject indexableObject = indexableObjects.next();
|
final IndexableObject indexableObject = indexableObjects.next();
|
||||||
indexContent(context, indexableObject, force);
|
indexContent(context, indexableObject, force);
|
||||||
context.uncacheEntity(indexableObject.getIndexedObject());
|
context.uncacheEntity(indexableObject.getIndexedObject());
|
||||||
|
indexObject++;
|
||||||
|
if ((indexObject % 100) == 0 && indexableObjectService instanceof ItemIndexFactory) {
|
||||||
|
context.uncacheEntities();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -988,8 +995,8 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
}
|
}
|
||||||
//Resolve our facet field values
|
//Resolve our facet field values
|
||||||
resolveFacetFields(context, query, result, skipLoadingResponse, solrQueryResponse);
|
resolveFacetFields(context, query, result, skipLoadingResponse, solrQueryResponse);
|
||||||
//Add total entries count for metadata browsing
|
//Resolve our json facet field values used for metadata browsing
|
||||||
resolveEntriesCount(result, solrQueryResponse);
|
resolveJsonFacetFields(context, result, solrQueryResponse);
|
||||||
}
|
}
|
||||||
// If any stale entries are found in the current page of results,
|
// If any stale entries are found in the current page of results,
|
||||||
// we remove those stale entries and rerun the same query again.
|
// we remove those stale entries and rerun the same query again.
|
||||||
@@ -1016,33 +1023,38 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the total count of entries for metadata index browsing. The count is calculated by the
|
* Process the 'json.facet' response, which is currently only used for metadata browsing
|
||||||
* <code>json.facet</code> parameter with the following value:
|
|
||||||
*
|
*
|
||||||
* <pre><code>
|
* @param context context object
|
||||||
* {
|
* @param result the result object to add the facet results to
|
||||||
* "entries_count": {
|
* @param solrQueryResponse the solr query response
|
||||||
* "type": "terms",
|
* @throws SQLException if database error
|
||||||
* "field": "facetNameField_filter",
|
|
||||||
* "limit": 0,
|
|
||||||
* "prefix": "prefix_value",
|
|
||||||
* "numBuckets": true
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* </code></pre>
|
|
||||||
*
|
|
||||||
* This value is returned in the <code>facets</code> field of the Solr response.
|
|
||||||
*
|
|
||||||
* @param result DiscoverResult object where the total entries count will be stored
|
|
||||||
* @param solrQueryResponse QueryResponse object containing the solr response
|
|
||||||
*/
|
*/
|
||||||
private void resolveEntriesCount(DiscoverResult result, QueryResponse solrQueryResponse) {
|
private void resolveJsonFacetFields(Context context, DiscoverResult result, QueryResponse solrQueryResponse)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
NestableJsonFacet response = solrQueryResponse.getJsonFacetingResponse();
|
NestableJsonFacet response = solrQueryResponse.getJsonFacetingResponse();
|
||||||
if (response != null) {
|
if (response != null && response.getBucketBasedFacetNames() != null) {
|
||||||
BucketBasedJsonFacet facet = response.getBucketBasedFacets("entries_count");
|
for (String facetName : response.getBucketBasedFacetNames()) {
|
||||||
if (facet != null) {
|
BucketBasedJsonFacet facet = response.getBucketBasedFacets(facetName);
|
||||||
result.setTotalEntries(facet.getNumBucketsCount());
|
if (facet != null) {
|
||||||
|
result.setTotalEntries(facet.getNumBucketsCount());
|
||||||
|
for (BucketJsonFacet bucket : facet.getBuckets()) {
|
||||||
|
String facetValue = bucket.getVal() != null ? bucket.getVal().toString() : "";
|
||||||
|
String field = facetName + "_filter";
|
||||||
|
String displayedValue = transformDisplayedValue(context, field, facetValue);
|
||||||
|
String authorityValue = transformAuthorityValue(context, field, facetValue);
|
||||||
|
String sortValue = transformSortValue(context, field, facetValue);
|
||||||
|
String filterValue = displayedValue;
|
||||||
|
if (StringUtils.isNotBlank(authorityValue)) {
|
||||||
|
filterValue = authorityValue;
|
||||||
|
}
|
||||||
|
result.addFacetResult(facetName,
|
||||||
|
new DiscoverResult.FacetResult(filterValue, displayedValue,
|
||||||
|
authorityValue, sortValue, bucket.getCount(),
|
||||||
|
DiscoveryConfigurationParameters.TYPE_TEXT));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1266,7 +1278,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
try {
|
try {
|
||||||
SolrQuery solrQuery = new SolrQuery();
|
SolrQuery solrQuery = new SolrQuery();
|
||||||
//Set the query to handle since this is unique
|
//Set the query to handle since this is unique
|
||||||
solrQuery.setQuery(SearchUtils.RESOURCE_UNIQUE_ID + ": " + new IndexableItem(item).getUniqueIndexID());
|
solrQuery.setQuery(SearchUtils.RESOURCE_UNIQUE_ID + ":" + new IndexableItem(item).getUniqueIndexID());
|
||||||
//Only return obj identifier fields in result doc
|
//Only return obj identifier fields in result doc
|
||||||
solrQuery.setFields(SearchUtils.RESOURCE_TYPE_FIELD, SearchUtils.RESOURCE_ID_FIELD);
|
solrQuery.setFields(SearchUtils.RESOURCE_TYPE_FIELD, SearchUtils.RESOURCE_ID_FIELD);
|
||||||
//Add the more like this parameters !
|
//Add the more like this parameters !
|
||||||
|
@@ -10,8 +10,10 @@ package org.dspace.discovery.configuration;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@@ -197,15 +199,19 @@ public class DiscoveryConfigurationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return All configurations for {@link org.dspace.discovery.configuration.DiscoverySearchFilterFacet}
|
* Get the unique set of configured Discovery facets. This is used when inspecting configuration
|
||||||
|
* to include hierarchical vocabularies in the browse menu.
|
||||||
|
*
|
||||||
|
* @return All unique instances of {@link org.dspace.discovery.configuration.DiscoverySearchFilterFacet}
|
||||||
|
* included in "sidebarFacets" bean, across all Discovery configurations.
|
||||||
*/
|
*/
|
||||||
public List<DiscoverySearchFilterFacet> getAllFacetsConfig() {
|
public List<DiscoverySearchFilterFacet> getAllUniqueFacetsConfig() {
|
||||||
List<DiscoverySearchFilterFacet> configs = new ArrayList<>();
|
Set<DiscoverySearchFilterFacet> configs = new LinkedHashSet<>();
|
||||||
for (String key : map.keySet()) {
|
for (String key : map.keySet()) {
|
||||||
DiscoveryConfiguration config = map.get(key);
|
DiscoveryConfiguration config = map.get(key);
|
||||||
configs.addAll(config.getSidebarFacets());
|
configs.addAll(config.getSidebarFacets());
|
||||||
}
|
}
|
||||||
return configs;
|
return new ArrayList<>(configs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@@ -181,6 +181,11 @@ public abstract class IndexFactoryImpl<T extends IndexableObject, S> implements
|
|||||||
*/
|
*/
|
||||||
protected void addFacetIndex(SolrInputDocument document, String field, String sortValue, String authority,
|
protected void addFacetIndex(SolrInputDocument document, String field, String sortValue, String authority,
|
||||||
String fvalue) {
|
String fvalue) {
|
||||||
|
// If facet value is null/blank, then we cannot index
|
||||||
|
if (StringUtils.isBlank(fvalue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// the separator for the filter can be eventually configured
|
// the separator for the filter can be eventually configured
|
||||||
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
|
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
|
||||||
.getProperty("discovery.solr.facets.split.char");
|
.getProperty("discovery.solr.facets.split.char");
|
||||||
|
@@ -17,15 +17,15 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.eperson.service.CaptchaService;
|
import org.dspace.eperson.service.CaptchaService;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -82,18 +82,17 @@ public class CaptchaServiceImpl implements CaptchaService {
|
|||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpResponse httpResponse;
|
final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
GoogleCaptchaResponse googleResponse;
|
try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
|
||||||
final ObjectMapper objectMapper = new ObjectMapper();
|
GoogleCaptchaResponse googleResponse = objectMapper.readValue(httpResponse.getEntity().getContent(),
|
||||||
try {
|
GoogleCaptchaResponse.class);
|
||||||
httpResponse = httpClient.execute(httpPost);
|
validateGoogleResponse(googleResponse, action);
|
||||||
googleResponse = objectMapper.readValue(httpResponse.getEntity().getContent(), GoogleCaptchaResponse.class);
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
throw new RuntimeException("Error during verify google recaptcha site", e);
|
throw new RuntimeException("Error during verify google recaptcha site", e);
|
||||||
}
|
}
|
||||||
validateGoogleResponse(googleResponse, action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean responseSanityCheck(String response) {
|
private boolean responseSanityCheck(String response) {
|
||||||
|
@@ -131,7 +131,8 @@ public class SubscribeServiceImpl implements SubscribeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSubscribed(Context context, EPerson eperson, DSpaceObject dSpaceObject) throws SQLException {
|
public boolean isSubscribed(Context context, EPerson eperson, DSpaceObject dSpaceObject) throws SQLException {
|
||||||
return subscriptionDAO.findByEPersonAndDso(context, eperson, dSpaceObject, -1, -1) != null;
|
List<Subscription> subscriptions = subscriptionDAO.findByEPersonAndDso(context, eperson, dSpaceObject, -1, -1);
|
||||||
|
return subscriptions != null && !subscriptions.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -10,12 +10,45 @@ package org.dspace.eperson.factory;
|
|||||||
import org.dspace.eperson.service.CaptchaService;
|
import org.dspace.eperson.service.CaptchaService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory to get services for Captcha protection of DSpace forms / endpoints
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
*/
|
||||||
public abstract class CaptchaServiceFactory {
|
public abstract class CaptchaServiceFactory {
|
||||||
|
|
||||||
public abstract CaptchaService getCaptchaService();
|
/**
|
||||||
|
* Get the singleton instance of this class
|
||||||
|
* @return singleton instance of this class
|
||||||
|
*/
|
||||||
public static CaptchaServiceFactory getInstance() {
|
public static CaptchaServiceFactory getInstance() {
|
||||||
return DSpaceServicesFactory.getInstance().getServiceManager()
|
return DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
.getServiceByName("captchaServiceFactory", CaptchaServiceFactory.class);
|
.getServiceByName("captchaServiceFactory", CaptchaServiceFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured CaptchService
|
||||||
|
* TODO: This will be fully "operational" once we have full coverage of all
|
||||||
|
* forms by all supported captcha providers. Until then, REST repositories
|
||||||
|
* should request the specific captcha service required.
|
||||||
|
* @return the configured CaptchaService
|
||||||
|
*/
|
||||||
|
public abstract CaptchaService getCaptchaService();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured Altcha CaptchaService. This is needed by REST repositories
|
||||||
|
* processing captcha payloads for forms that are *only* protected by Altcha.
|
||||||
|
* TODO: We are working towards full coverage of all forms by all providers
|
||||||
|
* @return the configured Altcha CaptchaService
|
||||||
|
*/
|
||||||
|
public abstract CaptchaService getAltchaCaptchaService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured Google CaptchaService. This is needed by REST repositories
|
||||||
|
* processing captcha payloads for forms that are *only* protected by Google.
|
||||||
|
* TODO: We are working towards full coverage of all forms by all providers
|
||||||
|
* @return the configured Google CaptchaService
|
||||||
|
*/
|
||||||
|
public abstract CaptchaService getGoogleCaptchaService();
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,11 @@ import org.dspace.services.ConfigurationService;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory to get services for Captcha protection of DSpace forms / endpoints
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
*/
|
||||||
public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -25,9 +30,16 @@ public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ConfigurationService configurationService;
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured CaptchService
|
||||||
|
* TODO: This will be fully "operational" once we have full coverage of all
|
||||||
|
* forms by all supported captcha providers. Until then, REST repositories
|
||||||
|
* should request the specific captcha service required.
|
||||||
|
* @return the configured CaptchaService
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CaptchaService getCaptchaService() {
|
public CaptchaService getCaptchaService() {
|
||||||
String provider = configurationService.getProperty("captcha.provider");
|
String provider = configurationService.getProperty("captcha.provider", "google");
|
||||||
|
|
||||||
if ("altcha".equalsIgnoreCase(provider)) {
|
if ("altcha".equalsIgnoreCase(provider)) {
|
||||||
return altchaCaptchaService;
|
return altchaCaptchaService;
|
||||||
@@ -35,4 +47,26 @@ public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
|||||||
|
|
||||||
return googleCaptchaService; // default to Google ReCaptcha
|
return googleCaptchaService; // default to Google ReCaptcha
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured Altcha CaptchaService. This is needed by REST repositories
|
||||||
|
* processing captcha payloads for forms that are *only* protected by Altcha.
|
||||||
|
* TODO: We are working towards full coverage of all forms by all providers
|
||||||
|
* @return the configured Altcha CaptchaService
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CaptchaService getAltchaCaptchaService() {
|
||||||
|
return altchaCaptchaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured Google CaptchaService. This is needed by REST repositories
|
||||||
|
* processing captcha payloads for forms that are *only* protected by Google.
|
||||||
|
* TODO: We are working towards full coverage of all forms by all providers
|
||||||
|
* @return the configured Google CaptchaService
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CaptchaService getGoogleCaptchaService() {
|
||||||
|
return googleCaptchaService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,13 +27,13 @@ import org.apache.http.HttpStatus;
|
|||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.NoHttpResponseException;
|
import org.apache.http.NoHttpResponseException;
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.app.util.Util;
|
import org.dspace.app.util.Util;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -120,33 +120,34 @@ public class OpenaireRestConnector {
|
|||||||
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
|
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
HttpResponse getResponse = httpClient.execute(httpPost);
|
||||||
|
|
||||||
JSONObject responseObject = null;
|
JSONObject responseObject = null;
|
||||||
try (InputStream is = getResponse.getEntity().getContent();
|
try (InputStream is = getResponse.getEntity().getContent();
|
||||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
||||||
String inputStr;
|
String inputStr;
|
||||||
// verify if we have basic json
|
// verify if we have basic json
|
||||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")
|
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")
|
||||||
&& inputStr.contains("expires_in")) {
|
&& inputStr.contains("expires_in")) {
|
||||||
try {
|
try {
|
||||||
responseObject = new JSONObject(inputStr);
|
responseObject = new JSONObject(inputStr);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Not as valid as I'd hoped, move along
|
// Not as valid as I'd hoped, move along
|
||||||
responseObject = null;
|
responseObject = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (responseObject == null || !responseObject.has("access_token") || !responseObject.has("expires_in")) {
|
||||||
if (responseObject == null || !responseObject.has("access_token") || !responseObject.has("expires_in")) {
|
throw new IOException("Unable to grab the access token using provided service url, " +
|
||||||
throw new IOException("Unable to grab the access token using provided service url, client id and secret");
|
"client id and secret");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OpenaireRestToken(responseObject.get("access_token").toString(),
|
|
||||||
Long.valueOf(responseObject.get("expires_in").toString()));
|
|
||||||
|
|
||||||
|
return new OpenaireRestToken(responseObject.get("access_token").toString(),
|
||||||
|
Long.valueOf(responseObject.get("expires_in").toString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,42 +172,43 @@ public class OpenaireRestConnector {
|
|||||||
httpGet.addHeader("Authorization", "Bearer " + accessToken);
|
httpGet.addHeader("Authorization", "Bearer " + accessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
getResponse = httpClient.execute(httpGet);
|
getResponse = httpClient.execute(httpGet);
|
||||||
|
|
||||||
StatusLine status = getResponse.getStatusLine();
|
StatusLine status = getResponse.getStatusLine();
|
||||||
|
|
||||||
// registering errors
|
// registering errors
|
||||||
switch (status.getStatusCode()) {
|
switch (status.getStatusCode()) {
|
||||||
case HttpStatus.SC_NOT_FOUND:
|
case HttpStatus.SC_NOT_FOUND:
|
||||||
// 404 - Not found
|
// 404 - Not found
|
||||||
case HttpStatus.SC_FORBIDDEN:
|
case HttpStatus.SC_FORBIDDEN:
|
||||||
// 403 - Invalid Access Token
|
// 403 - Invalid Access Token
|
||||||
case 429:
|
case 429:
|
||||||
// 429 - Rate limit abuse for unauthenticated user
|
// 429 - Rate limit abuse for unauthenticated user
|
||||||
Header[] limitUsed = getResponse.getHeaders("x-ratelimit-used");
|
Header[] limitUsed = getResponse.getHeaders("x-ratelimit-used");
|
||||||
Header[] limitMax = getResponse.getHeaders("x-ratelimit-limit");
|
Header[] limitMax = getResponse.getHeaders("x-ratelimit-limit");
|
||||||
|
|
||||||
if (limitUsed.length > 0) {
|
if (limitUsed.length > 0) {
|
||||||
String limitMsg = limitUsed[0].getValue();
|
String limitMsg = limitUsed[0].getValue();
|
||||||
if (limitMax.length > 0) {
|
if (limitMax.length > 0) {
|
||||||
limitMsg = limitMsg.concat(" of " + limitMax[0].getValue());
|
limitMsg = limitMsg.concat(" of " + limitMax[0].getValue());
|
||||||
|
}
|
||||||
|
getGotError(new NoHttpResponseException(status.getReasonPhrase() + " with usage limit "
|
||||||
|
+ limitMsg),
|
||||||
|
url + '/' + file);
|
||||||
|
} else {
|
||||||
|
// 429 - Rate limit abuse
|
||||||
|
getGotError(new NoHttpResponseException(status.getReasonPhrase()), url + '/' + file);
|
||||||
}
|
}
|
||||||
getGotError(
|
break;
|
||||||
new NoHttpResponseException(status.getReasonPhrase() + " with usage limit " + limitMsg),
|
default:
|
||||||
url + '/' + file);
|
// 200 or other
|
||||||
} else {
|
break;
|
||||||
// 429 - Rate limit abuse
|
}
|
||||||
getGotError(new NoHttpResponseException(status.getReasonPhrase()), url + '/' + file);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// 200 or other
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not close this httpClient
|
// do not close this httpClient
|
||||||
result = getResponse.getEntity().getContent();
|
result = getResponse.getEntity().getContent();
|
||||||
|
}
|
||||||
} catch (MalformedURLException e1) {
|
} catch (MalformedURLException e1) {
|
||||||
getGotError(e1, url + '/' + file);
|
getGotError(e1, url + '/' + file);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@@ -7,17 +7,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.external;
|
package org.dspace.external;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Antoine Snyers (antoine at atmire.com)
|
* @author Antoine Snyers (antoine at atmire.com)
|
||||||
@@ -39,7 +40,7 @@ public class OrcidRestConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InputStream get(String path, String accessToken) {
|
public InputStream get(String path, String accessToken) {
|
||||||
HttpResponse getResponse = null;
|
CloseableHttpResponse getResponse = null;
|
||||||
InputStream result = null;
|
InputStream result = null;
|
||||||
path = trimSlashes(path);
|
path = trimSlashes(path);
|
||||||
|
|
||||||
@@ -49,11 +50,13 @@ public class OrcidRestConnector {
|
|||||||
httpGet.addHeader("Content-Type", "application/vnd.orcid+xml");
|
httpGet.addHeader("Content-Type", "application/vnd.orcid+xml");
|
||||||
httpGet.addHeader("Authorization","Bearer " + accessToken);
|
httpGet.addHeader("Authorization","Bearer " + accessToken);
|
||||||
}
|
}
|
||||||
try {
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
|
||||||
getResponse = httpClient.execute(httpGet);
|
getResponse = httpClient.execute(httpGet);
|
||||||
//do not close this httpClient
|
try (InputStream responseStream = getResponse.getEntity().getContent()) {
|
||||||
result = getResponse.getEntity().getContent();
|
// Read all the content of the response stream into a byte array to prevent TruncatedChunkException
|
||||||
|
byte[] content = responseStream.readAllBytes();
|
||||||
|
result = new ByteArrayInputStream(content);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
getGotError(e, fullPath);
|
getGotError(e, fullPath);
|
||||||
}
|
}
|
||||||
|
@@ -7,24 +7,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.external.provider.impl;
|
package org.dspace.external.provider.impl;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.dto.MetadataValueDTO;
|
import org.dspace.content.dto.MetadataValueDTO;
|
||||||
@@ -32,8 +25,9 @@ import org.dspace.external.OrcidRestConnector;
|
|||||||
import org.dspace.external.model.ExternalDataObject;
|
import org.dspace.external.model.ExternalDataObject;
|
||||||
import org.dspace.external.provider.AbstractExternalDataProvider;
|
import org.dspace.external.provider.AbstractExternalDataProvider;
|
||||||
import org.dspace.external.provider.orcid.xml.XMLtoBio;
|
import org.dspace.external.provider.orcid.xml.XMLtoBio;
|
||||||
import org.json.JSONObject;
|
import org.dspace.orcid.model.factory.OrcidFactoryUtils;
|
||||||
import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier;
|
import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier;
|
||||||
|
import org.orcid.jaxb.model.v3.release.record.Email;
|
||||||
import org.orcid.jaxb.model.v3.release.record.Person;
|
import org.orcid.jaxb.model.v3.release.record.Person;
|
||||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -60,6 +54,11 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
|
|
||||||
private XMLtoBio converter;
|
private XMLtoBio converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum retries to allow for the access token retrieval
|
||||||
|
*/
|
||||||
|
private int maxClientRetries = 3;
|
||||||
|
|
||||||
public static final String ORCID_ID_SYNTAX = "\\d{4}-\\d{4}-\\d{4}-(\\d{3}X|\\d{4})";
|
public static final String ORCID_ID_SYNTAX = "\\d{4}-\\d{4}-\\d{4}-(\\d{3}X|\\d{4})";
|
||||||
private static final int MAX_INDEX = 10000;
|
private static final int MAX_INDEX = 10000;
|
||||||
|
|
||||||
@@ -78,47 +77,37 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
* @throws java.io.IOException passed through from HTTPclient.
|
* @throws java.io.IOException passed through from HTTPclient.
|
||||||
*/
|
*/
|
||||||
public void init() throws IOException {
|
public void init() throws IOException {
|
||||||
if (StringUtils.isNotBlank(clientSecret) && StringUtils.isNotBlank(clientId)
|
// Initialize access token at spring instantiation. If it fails, the access token will be null rather
|
||||||
&& StringUtils.isNotBlank(OAUTHUrl)) {
|
// than causing a fatal Spring startup error
|
||||||
String authenticationParameters = "?client_id=" + clientId +
|
initializeAccessToken();
|
||||||
"&client_secret=" + clientSecret +
|
}
|
||||||
"&scope=/read-public&grant_type=client_credentials";
|
|
||||||
HttpPost httpPost = new HttpPost(OAUTHUrl + authenticationParameters);
|
|
||||||
httpPost.addHeader("Accept", "application/json");
|
|
||||||
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
/**
|
||||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
* Initialize access token, logging an error and decrementing remaining retries if an IOException is thrown.
|
||||||
|
* If the optional access token result is empty, set to null instead.
|
||||||
JSONObject responseObject = null;
|
*/
|
||||||
try (InputStream is = getResponse.getEntity().getContent();
|
public void initializeAccessToken() {
|
||||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
// If we have reaches max retries or the access token is already set, return immediately
|
||||||
String inputStr;
|
if (maxClientRetries <= 0 || StringUtils.isNotBlank(accessToken)) {
|
||||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
return;
|
||||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")) {
|
}
|
||||||
try {
|
try {
|
||||||
responseObject = new JSONObject(inputStr);
|
accessToken = OrcidFactoryUtils.retrieveAccessToken(clientId, clientSecret, OAUTHUrl).orElse(null);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
//Not as valid as I'd hoped, move along
|
log.error("Error retrieving ORCID access token, {} retries left", --maxClientRetries);
|
||||||
responseObject = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (responseObject != null && responseObject.has("access_token")) {
|
|
||||||
accessToken = (String) responseObject.get("access_token");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ExternalDataObject> getExternalDataObject(String id) {
|
public Optional<ExternalDataObject> getExternalDataObject(String id) {
|
||||||
|
initializeAccessToken();
|
||||||
Person person = getBio(id);
|
Person person = getBio(id);
|
||||||
ExternalDataObject externalDataObject = convertToExternalDataObject(person);
|
ExternalDataObject externalDataObject = convertToExternalDataObject(person);
|
||||||
return Optional.of(externalDataObject);
|
return Optional.of(externalDataObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExternalDataObject convertToExternalDataObject(Person person) {
|
protected ExternalDataObject convertToExternalDataObject(Person person) {
|
||||||
|
initializeAccessToken();
|
||||||
ExternalDataObject externalDataObject = new ExternalDataObject(sourceIdentifier);
|
ExternalDataObject externalDataObject = new ExternalDataObject(sourceIdentifier);
|
||||||
if (person.getName() != null) {
|
if (person.getName() != null) {
|
||||||
String lastName = "";
|
String lastName = "";
|
||||||
@@ -126,13 +115,20 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
if (person.getName().getFamilyName() != null) {
|
if (person.getName().getFamilyName() != null) {
|
||||||
lastName = person.getName().getFamilyName().getContent();
|
lastName = person.getName().getFamilyName().getContent();
|
||||||
externalDataObject.addMetadata(new MetadataValueDTO("person", "familyName", null, null,
|
externalDataObject.addMetadata(new MetadataValueDTO("person", "familyName", null, null,
|
||||||
lastName));
|
lastName));
|
||||||
}
|
}
|
||||||
if (person.getName().getGivenNames() != null) {
|
if (person.getName().getGivenNames() != null) {
|
||||||
firstName = person.getName().getGivenNames().getContent();
|
firstName = person.getName().getGivenNames().getContent();
|
||||||
externalDataObject.addMetadata(new MetadataValueDTO("person", "givenName", null, null,
|
externalDataObject.addMetadata(new MetadataValueDTO("person", "givenName", null, null,
|
||||||
firstName));
|
firstName));
|
||||||
|
}
|
||||||
|
if (person.getEmails().getEmails() != null && !person.getEmails().getEmails().isEmpty()) {
|
||||||
|
Email email = person.getEmails().getEmails().get(0);
|
||||||
|
if (person.getEmails().getEmails().size() > 1) {
|
||||||
|
email = person.getEmails().getEmails().stream().filter(Email::isPrimary).findFirst().orElse(email);
|
||||||
|
}
|
||||||
|
externalDataObject.addMetadata(new MetadataValueDTO("person", "email", null,
|
||||||
|
null, email.getEmail()));
|
||||||
}
|
}
|
||||||
externalDataObject.setId(person.getName().getPath());
|
externalDataObject.setId(person.getName().getPath());
|
||||||
externalDataObject
|
externalDataObject
|
||||||
@@ -140,7 +136,7 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
new MetadataValueDTO("person", "identifier", "orcid", null, person.getName().getPath()));
|
new MetadataValueDTO("person", "identifier", "orcid", null, person.getName().getPath()));
|
||||||
externalDataObject
|
externalDataObject
|
||||||
.addMetadata(new MetadataValueDTO("dc", "identifier", "uri", null,
|
.addMetadata(new MetadataValueDTO("dc", "identifier", "uri", null,
|
||||||
orcidUrl + "/" + person.getName().getPath()));
|
orcidUrl + "/" + person.getName().getPath()));
|
||||||
if (!StringUtils.isBlank(lastName) && !StringUtils.isBlank(firstName)) {
|
if (!StringUtils.isBlank(lastName) && !StringUtils.isBlank(firstName)) {
|
||||||
externalDataObject.setDisplayValue(lastName + ", " + firstName);
|
externalDataObject.setDisplayValue(lastName + ", " + firstName);
|
||||||
externalDataObject.setValue(lastName + ", " + firstName);
|
externalDataObject.setValue(lastName + ", " + firstName);
|
||||||
@@ -151,8 +147,8 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
externalDataObject.setDisplayValue(firstName);
|
externalDataObject.setDisplayValue(firstName);
|
||||||
externalDataObject.setValue(firstName);
|
externalDataObject.setValue(firstName);
|
||||||
}
|
}
|
||||||
} else if (person.getPath() != null ) {
|
} else if (person.getPath() != null) {
|
||||||
externalDataObject.setId(StringUtils.substringBetween(person.getPath(),"/","/person"));
|
externalDataObject.setId(StringUtils.substringBetween(person.getPath(), "/", "/person"));
|
||||||
}
|
}
|
||||||
return externalDataObject;
|
return externalDataObject;
|
||||||
}
|
}
|
||||||
@@ -167,14 +163,13 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
if (!isValid(id)) {
|
if (!isValid(id)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
if (orcidRestConnector == null) {
|
||||||
Person person = converter.convertSinglePerson(bioDocument);
|
log.error("ORCID REST connector is null, returning null ORCID Person Bio");
|
||||||
try {
|
return null;
|
||||||
bioDocument.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
}
|
||||||
return person;
|
initializeAccessToken();
|
||||||
|
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
||||||
|
return converter.convertSinglePerson(bioDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,12 +183,18 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ExternalDataObject> searchExternalDataObjects(String query, int start, int limit) {
|
public List<ExternalDataObject> searchExternalDataObjects(String query, int start, int limit) {
|
||||||
|
initializeAccessToken();
|
||||||
if (limit > 100) {
|
if (limit > 100) {
|
||||||
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
||||||
}
|
}
|
||||||
if (start > MAX_INDEX) {
|
if (start > MAX_INDEX) {
|
||||||
throw new IllegalArgumentException("The starting number of results to retrieve cannot exceed 10000.");
|
throw new IllegalArgumentException("The starting number of results to retrieve cannot exceed 10000.");
|
||||||
}
|
}
|
||||||
|
// Check REST connector is initialized
|
||||||
|
if (orcidRestConnector == null) {
|
||||||
|
log.error("ORCID REST connector is not initialized, returning empty list");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
String searchPath = "search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)
|
String searchPath = "search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)
|
||||||
+ "&start=" + start
|
+ "&start=" + start
|
||||||
@@ -205,7 +206,7 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
for (Result result : results) {
|
for (Result result : results) {
|
||||||
OrcidIdentifier orcidIdentifier = result.getOrcidIdentifier();
|
OrcidIdentifier orcidIdentifier = result.getOrcidIdentifier();
|
||||||
if (orcidIdentifier != null) {
|
if (orcidIdentifier != null) {
|
||||||
log.debug("Found OrcidId=" + orcidIdentifier.toString());
|
log.debug("Found OrcidId=" + orcidIdentifier.getPath());
|
||||||
String orcid = orcidIdentifier.getPath();
|
String orcid = orcidIdentifier.getPath();
|
||||||
Person bio = getBio(orcid);
|
Person bio = getBio(orcid);
|
||||||
if (bio != null) {
|
if (bio != null) {
|
||||||
@@ -213,14 +214,6 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
bioDocument.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
if (Objects.isNull(bios)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return bios.stream().map(bio -> convertToExternalDataObject(bio)).collect(Collectors.toList());
|
return bios.stream().map(bio -> convertToExternalDataObject(bio)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +224,11 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfResults(String query) {
|
public int getNumberOfResults(String query) {
|
||||||
|
if (orcidRestConnector == null) {
|
||||||
|
log.error("ORCID REST connector is null, returning 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
initializeAccessToken();
|
||||||
String searchPath = "search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)
|
String searchPath = "search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)
|
||||||
+ "&start=" + 0
|
+ "&start=" + 0
|
||||||
+ "&rows=" + 0;
|
+ "&rows=" + 0;
|
||||||
|
@@ -97,7 +97,7 @@ public class SHERPAv2JournalDataProvider extends AbstractExternalDataProvider {
|
|||||||
if (CollectionUtils.isNotEmpty(sherpaJournal.getIssns())) {
|
if (CollectionUtils.isNotEmpty(sherpaJournal.getIssns())) {
|
||||||
String issn = sherpaJournal.getIssns().get(0);
|
String issn = sherpaJournal.getIssns().get(0);
|
||||||
externalDataObject.addMetadata(new MetadataValueDTO(
|
externalDataObject.addMetadata(new MetadataValueDTO(
|
||||||
"dc", "identifier", "issn", null, issn));
|
"creativeworkseries", "issn", null, null, issn));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -106,8 +106,7 @@ public class SHERPAv2JournalISSNDataProvider extends AbstractExternalDataProvide
|
|||||||
String issn = sherpaJournal.getIssns().get(0);
|
String issn = sherpaJournal.getIssns().get(0);
|
||||||
externalDataObject.setId(issn);
|
externalDataObject.setId(issn);
|
||||||
externalDataObject.addMetadata(new MetadataValueDTO(
|
externalDataObject.addMetadata(new MetadataValueDTO(
|
||||||
"dc", "identifier", "issn", null, issn));
|
"creativeworkseries", "issn", null, null, issn));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("New external data object. Title=" + externalDataObject.getValue() + ". ID="
|
log.debug("New external data object. Title=" + externalDataObject.getValue() + ". ID="
|
||||||
|
@@ -108,8 +108,9 @@ public class ExternalDataServiceImpl implements ExternalDataService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.info(LogHelper.getHeader(context, "create_item_from_externalDataObject", "Created item" +
|
log.info(LogHelper.getHeader(context, "create_item_from_externalDataObject", "Created item" +
|
||||||
"with id: " + item.getID() + " from source: " + externalDataObject.getSource() + " with identifier: " +
|
" with id: " + item.getID() +
|
||||||
externalDataObject.getId()));
|
" from source: " + externalDataObject.getSource() +
|
||||||
|
" with identifier: " + externalDataObject.getId()));
|
||||||
try {
|
try {
|
||||||
List<SuggestionProvider> providers = suggestionService.getSuggestionProviders();
|
List<SuggestionProvider> providers = suggestionService.getSuggestionProviders();
|
||||||
if (providers != null) {
|
if (providers != null) {
|
||||||
|
@@ -18,9 +18,9 @@ import org.apache.http.client.methods.CloseableHttpResponse;
|
|||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.google.GoogleAnalyticsEvent;
|
import org.dspace.google.GoogleAnalyticsEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +42,7 @@ public class GoogleAnalyticsClientImpl implements GoogleAnalyticsClient {
|
|||||||
public GoogleAnalyticsClientImpl(String keyPrefix, GoogleAnalyticsClientRequestBuilder requestBuilder) {
|
public GoogleAnalyticsClientImpl(String keyPrefix, GoogleAnalyticsClientRequestBuilder requestBuilder) {
|
||||||
this.keyPrefix = keyPrefix;
|
this.keyPrefix = keyPrefix;
|
||||||
this.requestBuilder = requestBuilder;
|
this.requestBuilder = requestBuilder;
|
||||||
this.httpclient = HttpClients.createDefault();
|
this.httpclient = DSpaceHttpClientFactory.getInstance().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -15,11 +15,14 @@ import java.util.List;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchemaEnum;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.LogHelper;
|
import org.dspace.core.LogHelper;
|
||||||
@@ -62,9 +65,6 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private HandleService handleService;
|
private HandleService handleService;
|
||||||
|
|
||||||
@Autowired(required = true)
|
|
||||||
private ItemService itemService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After all the properties are set check that the versioning is enabled
|
* After all the properties are set check that the versioning is enabled
|
||||||
*
|
*
|
||||||
@@ -171,6 +171,16 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
|||||||
throw new RuntimeException("The current user is not authorized to change this item.", ex);
|
throw new RuntimeException("The current user is not authorized to change this item.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dso instanceof Collection || dso instanceof Community) {
|
||||||
|
try {
|
||||||
|
// Update the metadata with the handle for collections and communities.
|
||||||
|
modifyHandleMetadata(context, dso, getCanonical(id));
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new RuntimeException("A problem with the database connection occured.", ex);
|
||||||
|
} catch (AuthorizeException ex) {
|
||||||
|
throw new RuntimeException("The current user is not authorized to change this item.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -489,27 +499,29 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
|||||||
* Remove all handles from an item's metadata and add the supplied handle instead.
|
* Remove all handles from an item's metadata and add the supplied handle instead.
|
||||||
*
|
*
|
||||||
* @param context The relevant DSpace Context.
|
* @param context The relevant DSpace Context.
|
||||||
* @param item which item to modify
|
* @param dso which dso to modify
|
||||||
* @param handle which handle to add
|
* @param handle which handle to add
|
||||||
* @throws SQLException if database error
|
* @throws SQLException if database error
|
||||||
* @throws AuthorizeException if authorization error
|
* @throws AuthorizeException if authorization error
|
||||||
*/
|
*/
|
||||||
protected void modifyHandleMetadata(Context context, Item item, String handle)
|
protected void modifyHandleMetadata(Context context, DSpaceObject dso, String handle)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
// we want to exchange the old handle against the new one. To do so, we
|
// we want to exchange the old handle against the new one. To do so, we
|
||||||
// load all identifiers, clear the metadata field, re add all
|
// load all identifiers, clear the metadata field, re add all
|
||||||
// identifiers which are not from type handle and add the new handle.
|
// identifiers which are not from type handle and add the new handle.
|
||||||
String handleref = handleService.getCanonicalForm(handle);
|
String handleref = handleService.getCanonicalForm(handle);
|
||||||
List<MetadataValue> identifiers = itemService
|
DSpaceObjectService<DSpaceObject> dSpaceObjectService =
|
||||||
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
ContentServiceFactory.getInstance().getDSpaceObjectService(dso);
|
||||||
itemService.clearMetadata(context, item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
List<MetadataValue> identifiers = dSpaceObjectService
|
||||||
|
.getMetadata(dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||||
|
dSpaceObjectService.clearMetadata(context, dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||||
for (MetadataValue identifier : identifiers) {
|
for (MetadataValue identifier : identifiers) {
|
||||||
if (this.supports(identifier.getValue())) {
|
if (this.supports(identifier.getValue())) {
|
||||||
// ignore handles
|
// ignore handles
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
itemService.addMetadata(context,
|
dSpaceObjectService.addMetadata(context,
|
||||||
item,
|
dso,
|
||||||
identifier.getMetadataField(),
|
identifier.getMetadataField(),
|
||||||
identifier.getLanguage(),
|
identifier.getLanguage(),
|
||||||
identifier.getValue(),
|
identifier.getValue(),
|
||||||
@@ -517,9 +529,9 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
|||||||
identifier.getConfidence());
|
identifier.getConfidence());
|
||||||
}
|
}
|
||||||
if (!StringUtils.isEmpty(handleref)) {
|
if (!StringUtils.isEmpty(handleref)) {
|
||||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
dSpaceObjectService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||||
"identifier", "uri", null, handleref);
|
"identifier", "uri", null, handleref);
|
||||||
}
|
}
|
||||||
itemService.update(context, item);
|
dSpaceObjectService.update(context, dso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,10 +36,10 @@ import org.apache.http.entity.ContentType;
|
|||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.crosswalk.CrosswalkException;
|
import org.dspace.content.crosswalk.CrosswalkException;
|
||||||
@@ -719,7 +719,7 @@ public class DataCiteConnector
|
|||||||
httpContext.setCredentialsProvider(credentialsProvider);
|
httpContext.setCredentialsProvider(credentialsProvider);
|
||||||
|
|
||||||
HttpEntity entity = null;
|
HttpEntity entity = null;
|
||||||
try ( CloseableHttpClient httpclient = HttpClientBuilder.create().build(); ) {
|
try (CloseableHttpClient httpclient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpResponse response = httpclient.execute(req, httpContext);
|
HttpResponse response = httpclient.execute(req, httpContext);
|
||||||
|
|
||||||
StatusLine status = response.getStatusLine();
|
StatusLine status = response.getStatusLine();
|
||||||
|
@@ -26,9 +26,9 @@ import org.apache.http.client.protocol.HttpClientContext;
|
|||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.identifier.DOI;
|
import org.dspace.identifier.DOI;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ public class EZIDRequest {
|
|||||||
this.authority = authority;
|
this.authority = authority;
|
||||||
}
|
}
|
||||||
|
|
||||||
client = HttpClientBuilder.create().build();
|
client = DSpaceHttpClientFactory.getInstance().build();
|
||||||
httpContext = HttpClientContext.create();
|
httpContext = HttpClientContext.create();
|
||||||
if (null != username) {
|
if (null != username) {
|
||||||
URI uri = new URI(scheme, host, path, null);
|
URI uri = new URI(scheme, host, path, null);
|
||||||
@@ -124,7 +124,7 @@ public class EZIDRequest {
|
|||||||
this.authority = authority;
|
this.authority = authority;
|
||||||
}
|
}
|
||||||
|
|
||||||
client = HttpClientBuilder.create().build();
|
client = DSpaceHttpClientFactory.getInstance().build();
|
||||||
httpContext = HttpClientContext.create();
|
httpContext = HttpClientContext.create();
|
||||||
if (null != username) {
|
if (null != username) {
|
||||||
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||||
|
@@ -12,12 +12,14 @@ import static org.dspace.iiif.canvasdimension.Util.checkDimensions;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.iiif.util.IIIFSharedUtils;
|
import org.dspace.iiif.util.IIIFSharedUtils;
|
||||||
|
|
||||||
@@ -35,14 +37,10 @@ public class IIIFApiQueryServiceImpl implements IIIFApiQueryService {
|
|||||||
public int[] getImageDimensions(Bitstream bitstream) {
|
public int[] getImageDimensions(Bitstream bitstream) {
|
||||||
int[] arr = new int[2];
|
int[] arr = new int[2];
|
||||||
String path = IIIFSharedUtils.getInfoJsonPath(bitstream);
|
String path = IIIFSharedUtils.getInfoJsonPath(bitstream);
|
||||||
URL url;
|
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
try {
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
url = new URL(path);
|
CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(path));
|
||||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
in = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
|
||||||
con.setRequestMethod("GET");
|
|
||||||
in = new BufferedReader(
|
|
||||||
new InputStreamReader(con.getInputStream()));
|
|
||||||
String inputLine;
|
String inputLine;
|
||||||
StringBuilder response = new StringBuilder();
|
StringBuilder response = new StringBuilder();
|
||||||
while ((inputLine = in.readLine()) != null) {
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
@@ -17,7 +17,6 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.importer.external.datamodel.ImportRecord;
|
import org.dspace.importer.external.datamodel.ImportRecord;
|
||||||
import org.dspace.importer.external.datamodel.Query;
|
import org.dspace.importer.external.datamodel.Query;
|
||||||
@@ -144,7 +143,7 @@ public class MultipleParallelImportMetadataSourceServiceImpl implements QuerySou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImportRecord getRecord(Query query) throws MetadataSourceException {
|
public ImportRecord getRecord(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for multiple external data sources");
|
throw new UnsupportedOperationException("This method is not implemented for multiple external data sources");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -21,7 +21,6 @@ import java.util.concurrent.Callable;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
@@ -99,7 +98,7 @@ public class ADSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for CrossRef");
|
throw new UnsupportedOperationException("This method is not implemented for CrossRef");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -15,7 +15,6 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import jakarta.ws.rs.client.Client;
|
import jakarta.ws.rs.client.Client;
|
||||||
import jakarta.ws.rs.client.ClientBuilder;
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
import jakarta.ws.rs.client.Invocation;
|
import jakarta.ws.rs.client.Invocation;
|
||||||
@@ -162,7 +161,7 @@ public class ArXivImportMetadataSourceServiceImpl extends AbstractImportMetadata
|
|||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
// FIXME: we need this method?
|
// FIXME: we need this method?
|
||||||
throw new MethodNotFoundException("This method is not implemented for ArXiv");
|
throw new UnsupportedOperationException("This method is not implemented for ArXiv");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,7 +20,6 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
@@ -113,7 +112,7 @@ public class CiniiImportMetadataSourceServiceImpl extends AbstractImportMetadata
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for Cinii");
|
throw new UnsupportedOperationException("This method is not implemented for Cinii");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
|
@@ -20,7 +20,6 @@ import java.util.concurrent.Callable;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
@@ -112,7 +111,7 @@ public class CrossRefImportMetadataSourceServiceImpl extends AbstractImportMetad
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for CrossRef");
|
throw new UnsupportedOperationException("This method is not implemented for CrossRef");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getID(String id) {
|
public String getID(String id) {
|
||||||
|
@@ -17,7 +17,6 @@ import java.util.Map;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -204,7 +203,7 @@ public class DataCiteImportMetadataSourceServiceImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for DataCite");
|
throw new UnsupportedOperationException("This method is not implemented for DataCite");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getID(String query) {
|
public String getID(String query) {
|
||||||
|
@@ -17,19 +17,16 @@ import java.util.Optional;
|
|||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpHost;
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.config.RequestConfig.Builder;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.client.methods.HttpRequestBase;
|
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
@@ -53,16 +50,11 @@ public class LiveImportClientImpl implements LiveImportClient {
|
|||||||
@Override
|
@Override
|
||||||
public String executeHttpGetRequest(int timeout, String URL, Map<String, Map<String, String>> params) {
|
public String executeHttpGetRequest(int timeout, String URL, Map<String, Map<String, String>> params) {
|
||||||
HttpGet method = null;
|
HttpGet method = null;
|
||||||
|
RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(timeout).build();
|
||||||
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
||||||
.orElseGet(HttpClients::createDefault)) {
|
.orElse(DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config))) {
|
||||||
|
|
||||||
Builder requestConfigBuilder = RequestConfig.custom();
|
|
||||||
requestConfigBuilder.setConnectionRequestTimeout(timeout);
|
|
||||||
RequestConfig defaultRequestConfig = requestConfigBuilder.build();
|
|
||||||
|
|
||||||
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
||||||
method = new HttpGet(uri);
|
method = new HttpGet(uri);
|
||||||
method.setConfig(defaultRequestConfig);
|
|
||||||
|
|
||||||
Map<String, String> headerParams = params.get(HEADER_PARAMETERS);
|
Map<String, String> headerParams = params.get(HEADER_PARAMETERS);
|
||||||
if (MapUtils.isNotEmpty(headerParams)) {
|
if (MapUtils.isNotEmpty(headerParams)) {
|
||||||
@@ -71,7 +63,6 @@ public class LiveImportClientImpl implements LiveImportClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configureProxy(method, defaultRequestConfig);
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Performing GET request to \"" + uri + "\"...");
|
log.debug("Performing GET request to \"" + uri + "\"...");
|
||||||
}
|
}
|
||||||
@@ -95,21 +86,17 @@ public class LiveImportClientImpl implements LiveImportClient {
|
|||||||
@Override
|
@Override
|
||||||
public String executeHttpPostRequest(String URL, Map<String, Map<String, String>> params, String entry) {
|
public String executeHttpPostRequest(String URL, Map<String, Map<String, String>> params, String entry) {
|
||||||
HttpPost method = null;
|
HttpPost method = null;
|
||||||
|
RequestConfig config = RequestConfig.custom().build();
|
||||||
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
||||||
.orElseGet(HttpClients::createDefault)) {
|
.orElse(DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config))) {
|
||||||
|
|
||||||
Builder requestConfigBuilder = RequestConfig.custom();
|
|
||||||
RequestConfig defaultRequestConfig = requestConfigBuilder.build();
|
|
||||||
|
|
||||||
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
||||||
method = new HttpPost(uri);
|
method = new HttpPost(uri);
|
||||||
method.setConfig(defaultRequestConfig);
|
|
||||||
if (StringUtils.isNotBlank(entry)) {
|
if (StringUtils.isNotBlank(entry)) {
|
||||||
method.setEntity(new StringEntity(entry));
|
method.setEntity(new StringEntity(entry));
|
||||||
}
|
}
|
||||||
setHeaderParams(method, params);
|
setHeaderParams(method, params);
|
||||||
|
|
||||||
configureProxy(method, defaultRequestConfig);
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Performing POST request to \"" + uri + "\"..." );
|
log.debug("Performing POST request to \"" + uri + "\"..." );
|
||||||
}
|
}
|
||||||
@@ -129,17 +116,6 @@ public class LiveImportClientImpl implements LiveImportClient {
|
|||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureProxy(HttpRequestBase method, RequestConfig defaultRequestConfig) {
|
|
||||||
String proxyHost = configurationService.getProperty("http.proxy.host");
|
|
||||||
String proxyPort = configurationService.getProperty("http.proxy.port");
|
|
||||||
if (StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(proxyPort)) {
|
|
||||||
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
|
|
||||||
.setProxy(new HttpHost(proxyHost, Integer.parseInt(proxyPort), "http"))
|
|
||||||
.build();
|
|
||||||
method.setConfig(requestConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to set the header parameters to the HTTP Post method
|
* Allows to set the header parameters to the HTTP Post method
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,300 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.importer.external.metadatamapping.contributor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.importer.external.metadatamapping.MetadataFieldConfig;
|
||||||
|
import org.dspace.importer.external.metadatamapping.MetadataFieldMapping;
|
||||||
|
import org.dspace.importer.external.metadatamapping.MetadatumDTO;
|
||||||
|
/**
|
||||||
|
* A simple JsonPath Metadata processor
|
||||||
|
* that allow extract value from json object
|
||||||
|
* by configuring the path in the query variable via the bean.
|
||||||
|
* moreover this can also perform more compact extractions
|
||||||
|
* by configuring specific json processor in "metadataProcessor"
|
||||||
|
*
|
||||||
|
* In addition from some array where `query` points to the values can be selected using some additional condition check.
|
||||||
|
* This can be expressed in jsonpath, but not in jsonpointer expression.
|
||||||
|
*
|
||||||
|
* e.g.
|
||||||
|
* query /descriptions
|
||||||
|
* conditionkey "descriptionType"
|
||||||
|
* conditionvalue "Abstract"
|
||||||
|
* retrievedvalue "description"
|
||||||
|
*
|
||||||
|
* and json
|
||||||
|
*
|
||||||
|
* "descriptions": [
|
||||||
|
* {"description":"Description A","descriptionType":"Abstract"},
|
||||||
|
* {"description":"Description B","descriptionType":"Other"}
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* should deliver the value "Description A".
|
||||||
|
* In addition there is some metadataPostProcessor modifying and changing the retrieved value,
|
||||||
|
* e.g. mapping to controlled values
|
||||||
|
*
|
||||||
|
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
|
||||||
|
* @author Florian Gantner (florian.gantner@uni-bamberg.de)
|
||||||
|
*/
|
||||||
|
public class EnhancedJsonPathAttributeConditionMetadataContributor implements MetadataContributor<String> {
|
||||||
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
private String query;
|
||||||
|
private String conditionKey;
|
||||||
|
private String conditionValue;
|
||||||
|
private String elementAttribute;
|
||||||
|
private MetadataFieldConfig field;
|
||||||
|
protected JsonPathMetadataProcessor metadataProcessor;
|
||||||
|
protected JsonPathMetadataProcessor metadataPostProcessor;
|
||||||
|
/**
|
||||||
|
* Initialize SimpleJsonPathMetadataContributor with a query, prefixToNamespaceMapping and MetadataFieldConfig
|
||||||
|
*
|
||||||
|
* @param query The JSonPath query
|
||||||
|
* @param field the matadata field to map the result of the Json path query
|
||||||
|
* <a href="https://github.com/DSpace/DSpace/tree/master/dspace-api/src/main/java/org/dspace/importer/external#metadata-mapping-">MetadataFieldConfig</a>
|
||||||
|
*/
|
||||||
|
public EnhancedJsonPathAttributeConditionMetadataContributor(String query, MetadataFieldConfig field) {
|
||||||
|
this.query = query;
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Unused by this implementation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setMetadataFieldMapping(MetadataFieldMapping<String, MetadataContributor<String>> rt) {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Empty constructor for SimpleJsonPathMetadataContributor
|
||||||
|
*/
|
||||||
|
public EnhancedJsonPathAttributeConditionMetadataContributor() {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return the MetadataFieldConfig used while retrieving MetadatumDTO
|
||||||
|
*
|
||||||
|
* @return MetadataFieldConfig
|
||||||
|
*/
|
||||||
|
public MetadataFieldConfig getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Setting the MetadataFieldConfig
|
||||||
|
*
|
||||||
|
* @param field MetadataFieldConfig used while retrieving MetadatumDTO
|
||||||
|
*/
|
||||||
|
public void setField(MetadataFieldConfig field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return query used to create the JSonPath
|
||||||
|
*
|
||||||
|
* @return the query this instance is based on
|
||||||
|
*/
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return query used to create the JSonPath
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return condition attribute key which is checked
|
||||||
|
*
|
||||||
|
* @return the attribute key which is checked
|
||||||
|
*/
|
||||||
|
public String getConditionKey() {
|
||||||
|
return conditionKey;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The key of the json attribute which is checked for the condition
|
||||||
|
*
|
||||||
|
* @param conditionKey
|
||||||
|
*/
|
||||||
|
public void setConditionKey(String conditionKey) {
|
||||||
|
this.conditionKey = conditionKey;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return condition attribute value which is checked
|
||||||
|
*
|
||||||
|
* @return the attribute value which is checked
|
||||||
|
*/
|
||||||
|
public String getConditionValue() {
|
||||||
|
return conditionValue;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The value of the json attribute which must match the condition
|
||||||
|
*
|
||||||
|
* @param conditionValue
|
||||||
|
*/
|
||||||
|
public void setConditionValue(String conditionValue) {
|
||||||
|
this.conditionValue = conditionValue;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return element attribute key where the final value is retrieved from
|
||||||
|
*
|
||||||
|
* @return the attribute key for the element
|
||||||
|
*/
|
||||||
|
public String getElementAttribute() {
|
||||||
|
return elementAttribute;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The json attribute where the value is retrieved from
|
||||||
|
*
|
||||||
|
* @param elementAttribute
|
||||||
|
*/
|
||||||
|
public void setElementAttribute(String elementAttribute) {
|
||||||
|
this.elementAttribute = elementAttribute;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Used to process data got by jsonpath expression, like arrays to stringify, change date format or else
|
||||||
|
* If it is null, toString will be used.
|
||||||
|
*
|
||||||
|
* @param metadataProcessor
|
||||||
|
*/
|
||||||
|
public void setMetadataProcessor(JsonPathMetadataProcessor metadataProcessor) {
|
||||||
|
this.metadataProcessor = metadataProcessor;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Used to process data got by jsonpath expression, like arrays to stringify, change date format or else
|
||||||
|
* If it is null, toString will be used.
|
||||||
|
*
|
||||||
|
* @param metadataPostProcessor
|
||||||
|
*/
|
||||||
|
public void setMetadataPostProcessor(JsonPathMetadataProcessor metadataPostProcessor) {
|
||||||
|
this.metadataPostProcessor = metadataPostProcessor;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Retrieve the metadata associated with the given object.
|
||||||
|
* The toString() of the resulting object will be used.
|
||||||
|
*
|
||||||
|
* @param fullJson A class to retrieve metadata from.
|
||||||
|
* @return a collection of import records. Only the identifier of the found records may be put in the record.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Collection<MetadatumDTO> contributeMetadata(String fullJson) {
|
||||||
|
Collection<MetadatumDTO> metadata = new ArrayList<>();
|
||||||
|
Collection<String> metadataValue = new ArrayList<>();
|
||||||
|
if (Objects.nonNull(metadataProcessor)) {
|
||||||
|
metadataValue = metadataProcessor.processMetadata(fullJson);
|
||||||
|
} else {
|
||||||
|
JsonNode jsonNode = convertStringJsonToJsonNode(fullJson);
|
||||||
|
JsonNode node = jsonNode.at(query);
|
||||||
|
if (node.isArray()) {
|
||||||
|
Iterator<JsonNode> nodes = node.iterator();
|
||||||
|
while (nodes.hasNext()) {
|
||||||
|
JsonNode nodeV = nodes.next();
|
||||||
|
if (!checkCondition(nodeV)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (getElementAttribute() != null) {
|
||||||
|
JsonNode element = nodeV.get(getElementAttribute());
|
||||||
|
if (element != null && !element.isMissingNode()) {
|
||||||
|
String nodeValue = getStringValue(element);
|
||||||
|
if (StringUtils.isNotBlank(nodeValue)) {
|
||||||
|
metadataValue.add(nodeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String nodeValue = getStringValue(nodeV);
|
||||||
|
if (StringUtils.isNotBlank(nodeValue)) {
|
||||||
|
metadataValue.add(nodeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!node.isNull() && StringUtils.isNotBlank(node.toString())) {
|
||||||
|
if (getElementAttribute() != null && checkCondition(node)) {
|
||||||
|
JsonNode element = node.get(getElementAttribute());
|
||||||
|
if (element != null && !element.isMissingNode()) {
|
||||||
|
String nodeValue = getStringValue(element);
|
||||||
|
if (StringUtils.isNotBlank(nodeValue)) {
|
||||||
|
metadataValue.add(nodeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (checkCondition(node)) {
|
||||||
|
String nodeValue = getStringValue(node);
|
||||||
|
if (StringUtils.isNotBlank(nodeValue)) {
|
||||||
|
metadataValue.add(nodeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (metadataPostProcessor != null) {
|
||||||
|
Collection<String> postmetadataValues = new ArrayList<>();
|
||||||
|
for (String value: metadataValue) {
|
||||||
|
Collection<String> postmetadataValue = metadataPostProcessor.processMetadata(value);
|
||||||
|
if (postmetadataValue != null) {
|
||||||
|
postmetadataValues.addAll(postmetadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadataValue = postmetadataValues;
|
||||||
|
}
|
||||||
|
for (String value : metadataValue) {
|
||||||
|
MetadatumDTO metadatumDto = new MetadatumDTO();
|
||||||
|
metadatumDto.setValue(value);
|
||||||
|
metadatumDto.setElement(field.getElement());
|
||||||
|
metadatumDto.setQualifier(field.getQualifier());
|
||||||
|
metadatumDto.setSchema(field.getSchema());
|
||||||
|
metadata.add(metadatumDto);
|
||||||
|
}
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Check some jsonNode if some jsonpointer expression matches some condition for some match.
|
||||||
|
* The match is parsed as some regex condition
|
||||||
|
* @param node
|
||||||
|
* @return true if node matches the condition or false if not
|
||||||
|
*/
|
||||||
|
private boolean checkCondition(JsonNode node) {
|
||||||
|
if (getConditionKey() == null && getConditionValue() == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getConditionKey() != null) {
|
||||||
|
JsonNode conditionnode = node.get(getConditionKey());
|
||||||
|
if (getConditionValue() == null && conditionnode != null && !conditionnode.isMissingNode()) {
|
||||||
|
return true;
|
||||||
|
} else if (conditionnode != null && !conditionnode.isMissingNode() &&
|
||||||
|
conditionnode.toString().matches(getConditionValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (getConditionKey() == null && node.toString().matches(getConditionValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private String getStringValue(JsonNode node) {
|
||||||
|
if (node.isTextual()) {
|
||||||
|
return node.textValue();
|
||||||
|
}
|
||||||
|
if (node.isNumber()) {
|
||||||
|
return node.numberValue().toString();
|
||||||
|
}
|
||||||
|
log.error("It wasn't possible to convert the value of the following JsonNode:" + node.asText());
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
private JsonNode convertStringJsonToJsonNode(String json) {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JsonNode body = null;
|
||||||
|
try {
|
||||||
|
body = mapper.readTree(json);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.error("Unable to process json response.", e);
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.importer.external.metadatamapping.contributor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.util.SimpleMapConverter;
|
||||||
|
/**
|
||||||
|
* This Processor allows to map text values to controlled list of vocabularies using some mapConverter
|
||||||
|
*
|
||||||
|
* @author Florian Gantner (florian.gantner@uni-bamberg.de)
|
||||||
|
*/
|
||||||
|
public class MappingValueProcessor implements JsonPathMetadataProcessor {
|
||||||
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
private SimpleMapConverter converter;
|
||||||
|
@Override
|
||||||
|
public Collection<String> processMetadata(String value) {
|
||||||
|
Collection<String> mappedValues = new ArrayList<>();
|
||||||
|
mappedValues.add(converter.getValue(value));
|
||||||
|
return mappedValues;
|
||||||
|
}
|
||||||
|
public void setConverter(SimpleMapConverter converter) {
|
||||||
|
this.converter = converter;
|
||||||
|
}
|
||||||
|
}
|
@@ -15,7 +15,6 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import jakarta.ws.rs.client.Client;
|
import jakarta.ws.rs.client.Client;
|
||||||
import jakarta.ws.rs.client.ClientBuilder;
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
import jakarta.ws.rs.client.Invocation;
|
import jakarta.ws.rs.client.Invocation;
|
||||||
@@ -135,12 +134,12 @@ public class OpenAireImportMetadataSourceServiceImpl extends AbstractImportMetad
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for OpenAIRE");
|
throw new UnsupportedOperationException("This method is not implemented for OpenAIRE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for OpenAIRE");
|
throw new UnsupportedOperationException("This method is not implemented for OpenAIRE");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,7 +17,6 @@ import java.util.concurrent.Callable;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -131,7 +130,7 @@ public class OpenAlexImportMetadataSourceServiceImpl extends AbstractImportMetad
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> getRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> getRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for OpenAlex");
|
throw new UnsupportedOperationException("This method is not implemented for OpenAlex");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,12 +151,12 @@ public class OpenAlexImportMetadataSourceServiceImpl extends AbstractImportMetad
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for OpenAlex");
|
throw new UnsupportedOperationException("This method is not implemented for OpenAlex");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for OpenAlex");
|
throw new UnsupportedOperationException("This method is not implemented for OpenAlex");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -235,6 +235,10 @@ public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
SAXBuilder saxBuilder = new SAXBuilder();
|
SAXBuilder saxBuilder = new SAXBuilder();
|
||||||
|
// Disallow external entities & entity expansion to protect against XXE attacks
|
||||||
|
// (NOTE: We receive errors if we disable all DTDs for PubMed, so this is the best we can do)
|
||||||
|
saxBuilder.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
|
saxBuilder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
Document document = saxBuilder.build(new StringReader(src));
|
Document document = saxBuilder.build(new StringReader(src));
|
||||||
Element root = document.getRootElement();
|
Element root = document.getRootElement();
|
||||||
|
|
||||||
|
@@ -18,7 +18,6 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
@@ -153,7 +152,7 @@ public class PubmedEuropeMetadataSourceServiceImpl extends AbstractImportMetadat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for PubMed Europe");
|
throw new UnsupportedOperationException("This method is not implemented for PubMed Europe");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -19,7 +19,6 @@ import java.util.concurrent.Callable;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
@@ -91,12 +90,12 @@ public class RorImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for ROR");
|
throw new UnsupportedOperationException("This method is not implemented for ROR");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for ROR");
|
throw new UnsupportedOperationException("This method is not implemented for ROR");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -21,7 +21,6 @@ import java.util.concurrent.Callable;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import jakarta.ws.rs.BadRequestException;
|
import jakarta.ws.rs.BadRequestException;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
@@ -99,17 +98,17 @@ public class ScieloImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRecordsCount(Query query) throws MetadataSourceException {
|
public int getRecordsCount(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for Scielo");
|
throw new UnsupportedOperationException("This method is not implemented for Scielo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for Scielo");
|
throw new UnsupportedOperationException("This method is not implemented for Scielo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for Scielo");
|
throw new UnsupportedOperationException("This method is not implemented for Scielo");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -23,7 +23,6 @@ import java.util.concurrent.Callable;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -152,7 +151,7 @@ public class ScopusImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
|||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item)
|
public Collection<ImportRecord> findMatchingRecords(Item item)
|
||||||
throws MetadataSourceException {
|
throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for Scopus");
|
throw new UnsupportedOperationException("This method is not implemented for Scopus");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -19,7 +19,6 @@ import java.util.concurrent.Callable;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -104,7 +103,7 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for VuFind");
|
throw new UnsupportedOperationException("This method is not implemented for VuFind");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -22,7 +22,6 @@ import java.util.concurrent.Callable;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import jakarta.el.MethodNotFoundException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -57,7 +56,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
private static final String AI_PATTERN = "^AI=(.*)";
|
private static final String AI_PATTERN = "^AI=(.*)";
|
||||||
private static final Pattern ISI_PATTERN = Pattern.compile("^\\d{15}$");
|
private static final Pattern ISI_PATTERN = Pattern.compile("^\\d{15}$");
|
||||||
|
|
||||||
private int timeout = 1000;
|
private final int timeout = 1000;
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
private String urlSearch;
|
private String urlSearch;
|
||||||
@@ -109,17 +108,17 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRecordsCount(Query query) throws MetadataSourceException {
|
public int getRecordsCount(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for WOS");
|
throw new UnsupportedOperationException("This method is not implemented for WOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for WOS");
|
throw new UnsupportedOperationException("This method is not implemented for WOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
|
||||||
throw new MethodNotFoundException("This method is not implemented for WOS");
|
throw new UnsupportedOperationException("This method is not implemented for WOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +126,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
*/
|
*/
|
||||||
private class SearchNBByQueryCallable implements Callable<Integer> {
|
private class SearchNBByQueryCallable implements Callable<Integer> {
|
||||||
|
|
||||||
private String query;
|
private final String query;
|
||||||
|
|
||||||
private SearchNBByQueryCallable(String queryString) {
|
private SearchNBByQueryCallable(String queryString) {
|
||||||
this.query = queryString;
|
this.query = queryString;
|
||||||
@@ -156,7 +155,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
Element tot = xpath.evaluateFirst(root);
|
Element tot = xpath.evaluateFirst(root);
|
||||||
return Integer.valueOf(tot.getValue());
|
return Integer.valueOf(tot.getValue());
|
||||||
}
|
}
|
||||||
return null;
|
log.warn("API key is missing: cannot execute count request.");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
*/
|
*/
|
||||||
private class FindByIdCallable implements Callable<List<ImportRecord>> {
|
private class FindByIdCallable implements Callable<List<ImportRecord>> {
|
||||||
|
|
||||||
private String doi;
|
private final String doi;
|
||||||
|
|
||||||
private FindByIdCallable(String doi) {
|
private FindByIdCallable(String doi) {
|
||||||
this.doi = URLEncoder.encode(doi, StandardCharsets.UTF_8);
|
this.doi = URLEncoder.encode(doi, StandardCharsets.UTF_8);
|
||||||
@@ -186,6 +186,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
for (Element record : elements) {
|
for (Element record : elements) {
|
||||||
results.add(transformSourceRecords(record));
|
results.add(transformSourceRecords(record));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("API key is missing: cannot execute live import request.");
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@@ -203,7 +205,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
*/
|
*/
|
||||||
private class SearchByQueryCallable implements Callable<List<ImportRecord>> {
|
private class SearchByQueryCallable implements Callable<List<ImportRecord>> {
|
||||||
|
|
||||||
private Query query;
|
private final Query query;
|
||||||
|
|
||||||
private SearchByQueryCallable(String queryString, Integer maxResult, Integer start) {
|
private SearchByQueryCallable(String queryString, Integer maxResult, Integer start) {
|
||||||
query = new Query();
|
query = new Query();
|
||||||
@@ -233,6 +235,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
for (Element el : omElements) {
|
for (Element el : omElements) {
|
||||||
results.add(transformSourceRecords(el));
|
results.add(transformSourceRecords(el));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("API key is missing: cannot execute live import request.");
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@@ -271,9 +275,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
|||||||
} else if (isIsi(query)) {
|
} else if (isIsi(query)) {
|
||||||
return "UT=(" + query + ")";
|
return "UT=(" + query + ")";
|
||||||
}
|
}
|
||||||
StringBuilder queryBuilder = new StringBuilder("TS=(");
|
return "TS=(" + query + ")";
|
||||||
queryBuilder.append(query).append(")");
|
|
||||||
return queryBuilder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isIsi(String query) {
|
private boolean isIsi(String query) {
|
||||||
|
@@ -10,9 +10,6 @@ package org.dspace.license;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -28,9 +25,9 @@ import org.apache.http.client.methods.HttpGet;
|
|||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.jdom2.Attribute;
|
import org.jdom2.Attribute;
|
||||||
import org.jdom2.Document;
|
import org.jdom2.Document;
|
||||||
@@ -70,12 +67,7 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5);
|
||||||
|
|
||||||
client = builder
|
|
||||||
.disableAutomaticRetries()
|
|
||||||
.setMaxConnTotal(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// disallow DTD parsing to ensure no XXE attacks can occur.
|
// disallow DTD parsing to ensure no XXE attacks can occur.
|
||||||
// See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
// See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
@@ -333,23 +325,13 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
|
|||||||
@Override
|
@Override
|
||||||
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
|
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
|
||||||
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
||||||
|
|
||||||
String issueUrl = ccLicenseUrl + "/details?license-uri=" + licenseURI;
|
String issueUrl = ccLicenseUrl + "/details?license-uri=" + licenseURI;
|
||||||
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
URL request_url;
|
CloseableHttpResponse httpResponse = httpClient.execute(new HttpPost(issueUrl));
|
||||||
try {
|
|
||||||
request_url = new URL(issueUrl);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
URLConnection connection = request_url.openConnection();
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
try {
|
|
||||||
// parsing document from input stream
|
// parsing document from input stream
|
||||||
InputStream stream = connection.getInputStream();
|
InputStream stream = httpResponse.getEntity().getContent();
|
||||||
Document doc = parser.build(stream);
|
Document doc = parser.build(stream);
|
||||||
return doc;
|
return doc;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error while retrieving the license document for URI: " + licenseURI, e);
|
log.error("Error while retrieving the license document for URI: " + licenseURI, e);
|
||||||
}
|
}
|
||||||
|
@@ -35,13 +35,14 @@ import org.apache.http.HttpEntity;
|
|||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.client.methods.RequestBuilder;
|
import org.apache.http.client.methods.RequestBuilder;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.orcid.OrcidToken;
|
import org.dspace.orcid.OrcidToken;
|
||||||
import org.dspace.orcid.exception.OrcidClientException;
|
import org.dspace.orcid.exception.OrcidClientException;
|
||||||
import org.dspace.orcid.model.OrcidEntityType;
|
import org.dspace.orcid.model.OrcidEntityType;
|
||||||
@@ -254,10 +255,8 @@ public class OrcidClientImpl implements OrcidClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeSuccessful(HttpUriRequest httpUriRequest) {
|
private void executeSuccessful(HttpUriRequest httpUriRequest) {
|
||||||
try {
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpClient client = HttpClientBuilder.create().build();
|
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||||
HttpResponse response = client.execute(httpUriRequest);
|
|
||||||
|
|
||||||
if (isNotSuccessfull(response)) {
|
if (isNotSuccessfull(response)) {
|
||||||
throw new OrcidClientException(
|
throw new OrcidClientException(
|
||||||
getStatusCode(response),
|
getStatusCode(response),
|
||||||
@@ -272,21 +271,17 @@ public class OrcidClientImpl implements OrcidClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeAndParseJson(HttpUriRequest httpUriRequest, Class<T> clazz) {
|
private <T> T executeAndParseJson(HttpUriRequest httpUriRequest, Class<T> clazz) {
|
||||||
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpClient client = HttpClientBuilder.create().build();
|
return executeAndReturns(() -> {
|
||||||
|
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||||
return executeAndReturns(() -> {
|
if (isNotSuccessfull(response)) {
|
||||||
|
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||||
HttpResponse response = client.execute(httpUriRequest);
|
}
|
||||||
|
return objectMapper.readValue(response.getEntity().getContent(), clazz);
|
||||||
if (isNotSuccessfull(response)) {
|
});
|
||||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
} catch (IOException e) {
|
||||||
}
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
return objectMapper.readValue(response.getEntity().getContent(), clazz);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,44 +296,37 @@ public class OrcidClientImpl implements OrcidClient {
|
|||||||
* @throws OrcidClientException if the incoming response is not successful
|
* @throws OrcidClientException if the incoming response is not successful
|
||||||
*/
|
*/
|
||||||
private <T> T executeAndUnmarshall(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull, Class<T> clazz) {
|
private <T> T executeAndUnmarshall(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull, Class<T> clazz) {
|
||||||
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
HttpClient client = HttpClientBuilder.create().build();
|
return executeAndReturns(() -> {
|
||||||
|
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||||
return executeAndReturns(() -> {
|
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||||
|
return null;
|
||||||
HttpResponse response = client.execute(httpUriRequest);
|
}
|
||||||
|
if (isNotSuccessfull(response)) {
|
||||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||||
return null;
|
}
|
||||||
}
|
return unmarshall(response.getEntity(), clazz);
|
||||||
|
});
|
||||||
if (isNotSuccessfull(response)) {
|
} catch (IOException e) {
|
||||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshall(response.getEntity(), clazz);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrcidResponse execute(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull) {
|
private OrcidResponse execute(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull) {
|
||||||
HttpClient client = HttpClientBuilder.create().build();
|
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
|
return executeAndReturns(() -> {
|
||||||
return executeAndReturns(() -> {
|
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||||
|
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||||
HttpResponse response = client.execute(httpUriRequest);
|
return new OrcidResponse(getStatusCode(response), null, getContent(response));
|
||||||
|
}
|
||||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
if (isNotSuccessfull(response)) {
|
||||||
return new OrcidResponse(getStatusCode(response), null, getContent(response));
|
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||||
}
|
}
|
||||||
|
return new OrcidResponse(getStatusCode(response), getPutCode(response), getContent(response));
|
||||||
if (isNotSuccessfull(response)) {
|
});
|
||||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
} catch (IOException e) {
|
||||||
}
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
return new OrcidResponse(getStatusCode(response), getPutCode(response), getContent(response));
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
||||||
|
@@ -7,10 +7,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.orcid.model.factory;
|
package org.dspace.orcid.model.factory;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for Orcid factory classes. This is used to parse the
|
* Utility class for Orcid factory classes. This is used to parse the
|
||||||
@@ -65,4 +76,48 @@ public final class OrcidFactoryUtils {
|
|||||||
return configurations;
|
return configurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve access token from ORCID, given a client ID, client secret and OAuth URL
|
||||||
|
*
|
||||||
|
* @param clientId ORCID client ID
|
||||||
|
* @param clientSecret ORCID client secret
|
||||||
|
* @param oauthUrl ORCID oauth redirect URL
|
||||||
|
* @return response object as Optional string
|
||||||
|
* @throws IOException if any errors are encountered making the connection or reading a response
|
||||||
|
*/
|
||||||
|
public static Optional<String> retrieveAccessToken(String clientId, String clientSecret, String oauthUrl)
|
||||||
|
throws IOException {
|
||||||
|
if (StringUtils.isNotBlank(clientSecret) && StringUtils.isNotBlank(clientId)
|
||||||
|
&& StringUtils.isNotBlank(oauthUrl)) {
|
||||||
|
String authenticationParameters = "?client_id=" + clientId +
|
||||||
|
"&client_secret=" + clientSecret +
|
||||||
|
"&scope=/read-public&grant_type=client_credentials";
|
||||||
|
HttpPost httpPost = new HttpPost(oauthUrl + authenticationParameters);
|
||||||
|
httpPost.addHeader("Accept", "application/json");
|
||||||
|
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
HttpResponse response;
|
||||||
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||||
|
response = httpClient.execute(httpPost);
|
||||||
|
}
|
||||||
|
JSONObject responseObject = null;
|
||||||
|
if (response != null && response.getStatusLine().getStatusCode() == 200) {
|
||||||
|
try (InputStream is = response.getEntity().getContent();
|
||||||
|
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is,
|
||||||
|
StandardCharsets.UTF_8))) {
|
||||||
|
String inputStr;
|
||||||
|
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||||
|
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")) {
|
||||||
|
responseObject = new JSONObject(inputStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (responseObject != null && responseObject.has("access_token")) {
|
||||||
|
return Optional.of((String) responseObject.get("access_token"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return empty by default
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,9 +22,9 @@ import org.apache.http.client.methods.HttpPost;
|
|||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.QAEvent;
|
import org.dspace.content.QAEvent;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -114,20 +114,19 @@ public class QAEventActionServiceImpl implements QAEventActionService {
|
|||||||
* Make acknowledgement to the configured urls for the event status.
|
* Make acknowledgement to the configured urls for the event status.
|
||||||
*/
|
*/
|
||||||
private void makeAcknowledgement(String eventId, String source, String status) {
|
private void makeAcknowledgement(String eventId, String source, String status) {
|
||||||
String[] ackwnoledgeCallbacks = configurationService
|
String[] acknowledgeCallbacks = configurationService
|
||||||
.getArrayProperty("qaevents." + source + ".acknowledge-url");
|
.getArrayProperty("qaevents." + source + ".acknowledge-url");
|
||||||
if (ackwnoledgeCallbacks != null) {
|
if (acknowledgeCallbacks != null) {
|
||||||
for (String ackwnoledgeCallback : ackwnoledgeCallbacks) {
|
for (String acknowledgeCallback : acknowledgeCallbacks) {
|
||||||
if (StringUtils.isNotBlank(ackwnoledgeCallback)) {
|
if (StringUtils.isNotBlank(acknowledgeCallback)) {
|
||||||
ObjectNode node = jsonMapper.createObjectNode();
|
ObjectNode node = jsonMapper.createObjectNode();
|
||||||
node.put("eventId", eventId);
|
node.put("eventId", eventId);
|
||||||
node.put("status", status);
|
node.put("status", status);
|
||||||
StringEntity requestEntity = new StringEntity(node.toString(), ContentType.APPLICATION_JSON);
|
StringEntity requestEntity = new StringEntity(node.toString(), ContentType.APPLICATION_JSON);
|
||||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||||
HttpPost postMethod = new HttpPost(ackwnoledgeCallback);
|
HttpPost postMethod = new HttpPost(acknowledgeCallback);
|
||||||
postMethod.setEntity(requestEntity);
|
postMethod.setEntity(requestEntity);
|
||||||
try {
|
httpClient.execute(postMethod);
|
||||||
httpclient.execute(postMethod);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -117,9 +117,9 @@ public class Harvest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!withdrawn) {
|
if (!withdrawn) {
|
||||||
discoverQuery.addFilterQueries("archived: true OR withdrawn: false");
|
discoverQuery.addFilterQueries("archived:true OR withdrawn:false");
|
||||||
} else {
|
} else {
|
||||||
discoverQuery.addFilterQueries("archived: true OR withdrawn: true");
|
discoverQuery.addFilterQueries("archived:true OR withdrawn:true");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order by item ID, so that for a given harvest the order will be
|
// Order by item ID, so that for a given harvest the order will be
|
||||||
|
@@ -19,11 +19,11 @@ import org.apache.http.HttpResponse;
|
|||||||
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||||
import org.apache.http.conn.HttpClientConnectionManager;
|
import org.apache.http.conn.HttpClientConnectionManager;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.http.message.BasicHeaderElementIterator;
|
import org.apache.http.message.BasicHeaderElementIterator;
|
||||||
import org.apache.http.protocol.HTTP;
|
import org.apache.http.protocol.HTTP;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,7 +112,7 @@ public class HttpConnectionPoolService {
|
|||||||
* @return the client.
|
* @return the client.
|
||||||
*/
|
*/
|
||||||
public CloseableHttpClient getClient() {
|
public CloseableHttpClient getClient() {
|
||||||
CloseableHttpClient httpClient = HttpClientBuilder.create()
|
CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().builder(true).create()
|
||||||
.setKeepAliveStrategy(keepAliveStrategy)
|
.setKeepAliveStrategy(keepAliveStrategy)
|
||||||
.setConnectionManager(connManager)
|
.setConnectionManager(connManager)
|
||||||
.build();
|
.build();
|
||||||
|
@@ -54,7 +54,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrClient;
|
import org.apache.solr.client.solrj.SolrClient;
|
||||||
@@ -84,6 +83,7 @@ import org.apache.solr.common.params.MapSolrParams;
|
|||||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
import org.apache.solr.common.params.ShardParams;
|
import org.apache.solr.common.params.ShardParams;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
@@ -1208,7 +1208,7 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea
|
|||||||
+ "."
|
+ "."
|
||||||
+ i
|
+ i
|
||||||
+ ".csv");
|
+ ".csv");
|
||||||
try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) {
|
try (CloseableHttpClient hc = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||||
HttpResponse response = hc.execute(get);
|
HttpResponse response = hc.execute(get);
|
||||||
csvInputstream = response.getEntity().getContent();
|
csvInputstream = response.getEntity().getContent();
|
||||||
//Write the csv output to a file !
|
//Write the csv output to a file !
|
||||||
@@ -1350,7 +1350,7 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea
|
|||||||
|
|
||||||
HttpGet get = new HttpGet(solrRequestUrl);
|
HttpGet get = new HttpGet(solrRequestUrl);
|
||||||
List<String[]> rows;
|
List<String[]> rows;
|
||||||
try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) {
|
try (CloseableHttpClient hc = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||||
HttpResponse response = hc.execute(get);
|
HttpResponse response = hc.execute(get);
|
||||||
InputStream csvOutput = response.getEntity().getContent();
|
InputStream csvOutput = response.getEntity().getContent();
|
||||||
Reader csvReader = new InputStreamReader(csvOutput);
|
Reader csvReader = new InputStreamReader(csvOutput);
|
||||||
|
@@ -93,7 +93,7 @@ public class StatisticsLoggingConsumer implements Consumer {
|
|||||||
// We are mapping a new item make sure that the owning collection is
|
// We are mapping a new item make sure that the owning collection is
|
||||||
// updated
|
// updated
|
||||||
Item newItem = (Item) event.getObject(ctx);
|
Item newItem = (Item) event.getObject(ctx);
|
||||||
String updateQuery = "id: " + newItem.getID() + " AND type:"
|
String updateQuery = "id:" + newItem.getID() + " AND type:"
|
||||||
+ newItem.getType();
|
+ newItem.getType();
|
||||||
|
|
||||||
List<String> fieldNames = new ArrayList<String>();
|
List<String> fieldNames = new ArrayList<String>();
|
||||||
@@ -116,7 +116,7 @@ public class StatisticsLoggingConsumer implements Consumer {
|
|||||||
&& event.getObject(ctx) instanceof Item) {
|
&& event.getObject(ctx) instanceof Item) {
|
||||||
// Unmapping items
|
// Unmapping items
|
||||||
Item newItem = (Item) event.getObject(ctx);
|
Item newItem = (Item) event.getObject(ctx);
|
||||||
String updateQuery = "id: " + newItem.getID() + " AND type:"
|
String updateQuery = "id:" + newItem.getID() + " AND type:"
|
||||||
+ newItem.getType();
|
+ newItem.getType();
|
||||||
|
|
||||||
List<String> fieldNames = new ArrayList<String>();
|
List<String> fieldNames = new ArrayList<String>();
|
||||||
|
@@ -68,10 +68,10 @@ public class StatisticsBSAdapter {
|
|||||||
switch (visitType) {
|
switch (visitType) {
|
||||||
case ITEM_VISITS:
|
case ITEM_VISITS:
|
||||||
return solrLoggerService
|
return solrLoggerService
|
||||||
.queryTotal("type: " + Constants.ITEM + " AND id: " + item.getID(), resolveFilterQueries(), 0)
|
.queryTotal("type:" + Constants.ITEM + " AND id:" + item.getID(), resolveFilterQueries(), 0)
|
||||||
.getCount();
|
.getCount();
|
||||||
case BITSTREAM_VISITS:
|
case BITSTREAM_VISITS:
|
||||||
return solrLoggerService.queryTotal("type: " + Constants.BITSTREAM + " AND owningItem: " + item.getID(),
|
return solrLoggerService.queryTotal("type:" + Constants.BITSTREAM + " AND owningItem:" + item.getID(),
|
||||||
resolveFilterQueries(), 0).getCount();
|
resolveFilterQueries(), 0).getCount();
|
||||||
case TOTAL_VISITS:
|
case TOTAL_VISITS:
|
||||||
return getNumberOfVisits(ITEM_VISITS, item) + getNumberOfVisits(BITSTREAM_VISITS, item);
|
return getNumberOfVisits(ITEM_VISITS, item) + getNumberOfVisits(BITSTREAM_VISITS, item);
|
||||||
|
@@ -209,7 +209,7 @@ public class StatisticsDataSearches extends StatisticsData {
|
|||||||
protected String getQuery() {
|
protected String getQuery() {
|
||||||
String query;
|
String query;
|
||||||
if (currentDso != null) {
|
if (currentDso != null) {
|
||||||
query = "scopeType: " + currentDso.getType() + " AND ";
|
query = "scopeType:" + currentDso.getType() + " AND ";
|
||||||
if (currentDso instanceof DSpaceObjectLegacySupport) {
|
if (currentDso instanceof DSpaceObjectLegacySupport) {
|
||||||
query += " (scopeId:" + currentDso.getID() + " OR scopeId:" + ((DSpaceObjectLegacySupport) currentDso)
|
query += " (scopeId:" + currentDso.getID() + " OR scopeId:" + ((DSpaceObjectLegacySupport) currentDso)
|
||||||
.getLegacyId() + ")";
|
.getLegacyId() + ")";
|
||||||
|
@@ -237,7 +237,7 @@ public class StatisticsDataVisits extends StatisticsData {
|
|||||||
false, null, facetMinCount);
|
false, null, facetMinCount);
|
||||||
for (int j = 0; j < maxObjectCounts.length; j++) {
|
for (int j = 0; j < maxObjectCounts.length; j++) {
|
||||||
ObjectCount firstCount = maxObjectCounts[j];
|
ObjectCount firstCount = maxObjectCounts[j];
|
||||||
String newQuery = dataSetQuery.getFacetField() + ": " + ClientUtils
|
String newQuery = dataSetQuery.getFacetField() + ":" + ClientUtils
|
||||||
.escapeQueryChars(firstCount.getValue()) + " AND " + query;
|
.escapeQueryChars(firstCount.getValue()) + " AND " + query;
|
||||||
ObjectCount[] maxDateFacetCounts = solrLoggerService
|
ObjectCount[] maxDateFacetCounts = solrLoggerService
|
||||||
.queryFacetDate(newQuery, filterQuery, dataSetQuery.getMax(), dateFacet.getDateType(),
|
.queryFacetDate(newQuery, filterQuery, dataSetQuery.getMax(), dateFacet.getDateType(),
|
||||||
@@ -813,7 +813,7 @@ public class StatisticsDataVisits extends StatisticsData {
|
|||||||
String query = "";
|
String query = "";
|
||||||
//Check (& add if needed) the dsoType
|
//Check (& add if needed) the dsoType
|
||||||
if (dsoType != -1) {
|
if (dsoType != -1) {
|
||||||
query += "type: " + dsoType;
|
query += "type:" + dsoType;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check (& add if needed) the dsoId
|
//Check (& add if needed) the dsoId
|
||||||
|
@@ -146,7 +146,7 @@ public class StatisticsDataWorkflow extends StatisticsData {
|
|||||||
*/
|
*/
|
||||||
protected String getQuery() {
|
protected String getQuery() {
|
||||||
String query = "statistics_type:" + SolrLoggerServiceImpl.StatisticsType.WORKFLOW.text();
|
String query = "statistics_type:" + SolrLoggerServiceImpl.StatisticsType.WORKFLOW.text();
|
||||||
query += " AND NOT(previousWorkflowStep: SUBMIT)";
|
query += " AND NOT(previousWorkflowStep:SUBMIT)";
|
||||||
if (currentDso != null) {
|
if (currentDso != null) {
|
||||||
if (currentDso.getType() == Constants.COMMUNITY) {
|
if (currentDso.getType() == Constants.COMMUNITY) {
|
||||||
query += " AND owningComm:";
|
query += " AND owningComm:";
|
||||||
|
@@ -15,13 +15,13 @@ import java.time.LocalDate;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.statistics.export.OpenURLTracker;
|
import org.dspace.statistics.export.OpenURLTracker;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -69,16 +69,16 @@ public class OpenUrlServiceImpl implements OpenUrlService {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected int getResponseCodeFromUrl(final String urlStr) throws IOException {
|
protected int getResponseCodeFromUrl(final String urlStr) throws IOException {
|
||||||
HttpGet httpGet = new HttpGet(urlStr);
|
try (CloseableHttpClient httpClient = getHttpClient(getHttpClientRequestConfig())) {
|
||||||
HttpClient httpClient = getHttpClient(getHttpClientRequestConfig());
|
HttpGet httpGet = new HttpGet(urlStr);
|
||||||
HttpResponse httpResponse = httpClient.execute(httpGet);
|
try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
|
||||||
return httpResponse.getStatusLine().getStatusCode();
|
return httpResponse.getStatusLine().getStatusCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpClient getHttpClient(RequestConfig requestConfig) {
|
protected CloseableHttpClient getHttpClient(RequestConfig requestConfig) {
|
||||||
return HttpClientBuilder.create()
|
return DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(requestConfig);
|
||||||
.setDefaultRequestConfig(requestConfig)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RequestConfig getHttpClientRequestConfig() {
|
protected RequestConfig getHttpClientRequestConfig() {
|
||||||
|
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.storage.bitstore;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.BitstreamService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ByteSource implementation that provides access to DSpace Bitstream content.
|
||||||
|
* Extends Google Guava's ByteSource to allow streaming access to bitstream data.
|
||||||
|
*
|
||||||
|
* Author: Mark Diggory, Nathan Buckingham
|
||||||
|
*/
|
||||||
|
public class BitstreamByteSource extends ByteSource {
|
||||||
|
|
||||||
|
/** Service for accessing bitstream content */
|
||||||
|
private static final BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
|
||||||
|
|
||||||
|
/** The bitstream this source provides access to */
|
||||||
|
private final Bitstream bitstream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new BitstreamByteSource for the given bitstream.
|
||||||
|
*
|
||||||
|
* @param bitstream the DSpace bitstream to wrap
|
||||||
|
*/
|
||||||
|
public BitstreamByteSource(Bitstream bitstream) {
|
||||||
|
this.bitstream = bitstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the underlying bitstream.
|
||||||
|
*
|
||||||
|
* @return the DSpace bitstream object
|
||||||
|
*/
|
||||||
|
public Bitstream getBitstream() {
|
||||||
|
return bitstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a new input stream for reading the bitstream content.
|
||||||
|
*
|
||||||
|
* @return an input stream containing the bitstream data
|
||||||
|
* @throws IOException if there is an error retrieving the bitstream,
|
||||||
|
* including SQL or authorization errors
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InputStream openStream() throws IOException {
|
||||||
|
try {
|
||||||
|
return bitstreamService.retrieve(new Context(), bitstream);
|
||||||
|
} catch (SQLException | AuthorizeException e) {
|
||||||
|
throw new IOException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of the bitstream in bytes.
|
||||||
|
*
|
||||||
|
* @return the size of the bitstream in bytes
|
||||||
|
* @throws IOException if there is an error accessing the size
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long size() throws IOException {
|
||||||
|
return bitstream.getSizeBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -91,6 +91,11 @@ public class BitstreamStorageServiceImpl implements BitstreamStorageService, Ini
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIncomingExternal(int incoming) {
|
||||||
|
this.incoming = incoming;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
for (Map.Entry<Integer, BitStoreService> storeEntry : stores.entrySet()) {
|
for (Map.Entry<Integer, BitStoreService> storeEntry : stores.entrySet()) {
|
||||||
|
@@ -0,0 +1,582 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.storage.bitstore;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.google.common.hash.HashCode;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import com.google.common.net.MediaType;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.BitstreamFormat;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
import org.dspace.storage.bitstore.factory.StorageServiceFactory;
|
||||||
|
import org.dspace.storage.bitstore.service.BitstreamStorageService;
|
||||||
|
import org.jclouds.ContextBuilder;
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.options.ListContainerOptions;
|
||||||
|
import org.jclouds.blobstore.options.PutOptions.Builder;
|
||||||
|
import org.jclouds.io.ContentMetadata;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JCloudBitstream asset store service
|
||||||
|
*
|
||||||
|
* This class provides an implementation of the BitstreamStorageService using JClouds for cloud storage.
|
||||||
|
* It supports storing, retrieving, and removing bitstreams in a cloud storage container.
|
||||||
|
* The class also handles initialization and configuration of the JClouds BlobStoreContext.
|
||||||
|
*
|
||||||
|
* Additional details regarding configuration can be found at:
|
||||||
|
* Blobstore Configuration https://jclouds.apache.org/start/blobstore/
|
||||||
|
* Providers and API https://jclouds.apache.org/reference/providers/#blobstore
|
||||||
|
*
|
||||||
|
* Author: Mark Diggory, Nathan Buckingham
|
||||||
|
*/
|
||||||
|
public class JCloudBitStoreService extends BaseBitStoreService {
|
||||||
|
|
||||||
|
/** Logger for this class */
|
||||||
|
private static final Logger log = LogManager.getLogger(JCloudBitStoreService.class);
|
||||||
|
|
||||||
|
/** Properties for configuring the cloud storage provider */
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
/** The cloud storage provider or API to use (e.g. "aws-s3", "openstack-swift") */
|
||||||
|
private String providerOrApi;
|
||||||
|
|
||||||
|
/** JClouds ContextBuilder for creating the storage context */
|
||||||
|
private ContextBuilder builder;
|
||||||
|
|
||||||
|
/** JClouds BlobStoreContext for interacting with the cloud storage */
|
||||||
|
private BlobStoreContext blobStoreContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container/bucket name where assets are stored.
|
||||||
|
* Required for cloud storage providers.
|
||||||
|
*/
|
||||||
|
private String container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional subfolder path within the container/bucket.
|
||||||
|
* Allows organizing assets in a subfolder hierarchy.
|
||||||
|
*/
|
||||||
|
private String subfolder = null;
|
||||||
|
|
||||||
|
/** Authentication identity/access key for the cloud provider */
|
||||||
|
private String identity;
|
||||||
|
|
||||||
|
/** Authentication credential/secret key for the cloud provider */
|
||||||
|
private String credential;
|
||||||
|
|
||||||
|
/** Optional endpoint URL for the cloud storage service */
|
||||||
|
private String endpoint;
|
||||||
|
|
||||||
|
/** Whether to use relative paths when storing assets */
|
||||||
|
private boolean useRelativePath;
|
||||||
|
|
||||||
|
/** Whether this storage service is enabled */
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
/** Counter for tracking context refreshes */
|
||||||
|
private int counter = 0;
|
||||||
|
|
||||||
|
/** Maximum value for context refresh counter before forcing refresh */
|
||||||
|
private int maxCounter = -1;
|
||||||
|
|
||||||
|
/** Checksum algorithm used (MD5) */
|
||||||
|
private static final String CSA = "MD5";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public JCloudBitStoreService() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with provider or API.
|
||||||
|
*
|
||||||
|
* @param providerOrApi the provider or API to use for cloud storage
|
||||||
|
*/
|
||||||
|
public JCloudBitStoreService(String providerOrApi) {
|
||||||
|
this.providerOrApi = providerOrApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor with BlobStoreContext and provider or API.
|
||||||
|
*
|
||||||
|
* @param blobStoreContext the BlobStoreContext to use
|
||||||
|
* @param providerOrApi the provider or API to use for cloud storage
|
||||||
|
*/
|
||||||
|
protected JCloudBitStoreService(BlobStoreContext blobStoreContext, String providerOrApi) {
|
||||||
|
this.blobStoreContext = blobStoreContext;
|
||||||
|
this.providerOrApi = providerOrApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to use relative paths for storing bitstreams.
|
||||||
|
*
|
||||||
|
* @param useRelativePath true to use relative paths, false otherwise
|
||||||
|
*/
|
||||||
|
public void setUseRelativePath(boolean useRelativePath) {
|
||||||
|
this.useRelativePath = useRelativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the service is enabled.
|
||||||
|
*
|
||||||
|
* @param enabled true to enable the service, false otherwise
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the container name for storing bitstreams.
|
||||||
|
*
|
||||||
|
* @param container the container name
|
||||||
|
*/
|
||||||
|
public void setContainer(String container) {
|
||||||
|
this.container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subfolder within the bucket where objects are stored.
|
||||||
|
*
|
||||||
|
* @return the subfolder name
|
||||||
|
*/
|
||||||
|
public String getSubfolder() {
|
||||||
|
return subfolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the subfolder within the bucket where objects are stored.
|
||||||
|
*
|
||||||
|
* @param subfolder the subfolder name
|
||||||
|
*/
|
||||||
|
public void setSubfolder(String subfolder) {
|
||||||
|
this.subfolder = subfolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the identity for cloud storage authentication.
|
||||||
|
*
|
||||||
|
* @param identity the identity
|
||||||
|
*/
|
||||||
|
public void setIdentity(String identity) {
|
||||||
|
this.identity = identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the credentials for cloud storage authentication.
|
||||||
|
*
|
||||||
|
* @param credential the credentials
|
||||||
|
*/
|
||||||
|
public void setCredentials(@Nullable String credential) {
|
||||||
|
this.credential = credential;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the provider or API for cloud storage.
|
||||||
|
*
|
||||||
|
* @param providerOrApi the provider or API
|
||||||
|
*/
|
||||||
|
public void setProviderOrApi(String providerOrApi) {
|
||||||
|
this.providerOrApi = providerOrApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the endpoint for cloud storage.
|
||||||
|
*
|
||||||
|
* @param endpoint the endpoint
|
||||||
|
*/
|
||||||
|
public void setEndpoint(String endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum counter value for refreshing the context.
|
||||||
|
*
|
||||||
|
* @param maxCounter the maximum counter value
|
||||||
|
*/
|
||||||
|
public void setMaxCounter(int maxCounter) {
|
||||||
|
this.maxCounter = maxCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the properties for cloud storage configuration.
|
||||||
|
*
|
||||||
|
* @param overrides the properties
|
||||||
|
*/
|
||||||
|
public void setOverrides(Properties overrides) {
|
||||||
|
this.properties = overrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the service is enabled.
|
||||||
|
*
|
||||||
|
* @return true if the service is enabled, false otherwise
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the cloud storage context.
|
||||||
|
*
|
||||||
|
* @throws IOException if an error occurs during initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void init() throws IOException {
|
||||||
|
if (this.isInitialized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.builder = ContextBuilder.newBuilder(providerOrApi);
|
||||||
|
if (StringUtils.isNotEmpty(endpoint)) {
|
||||||
|
this.builder = this.builder.endpoint(endpoint);
|
||||||
|
}
|
||||||
|
if (properties != null && !properties.isEmpty()) {
|
||||||
|
this.builder = this.builder.overrides(properties);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(identity) && StringUtils.isNotEmpty(credential)) {
|
||||||
|
this.builder = this.builder.credentials(identity, credential);
|
||||||
|
}
|
||||||
|
blobStoreContext = this.builder.buildView(BlobStoreContext.class);
|
||||||
|
this.initialized = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(),e);
|
||||||
|
this.initialized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the cloud storage context if needed. Can be used to reset connection pool every
|
||||||
|
* {@code @maxCounter} requests if thrid party service start to show connection pooling issues.
|
||||||
|
* Defaults to never reset the connection pool.
|
||||||
|
*/
|
||||||
|
private synchronized void refreshContextIfNeeded() {
|
||||||
|
|
||||||
|
// do not reset context if maxCounter set to -1
|
||||||
|
if (maxCounter < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
// Close and Recreate connection between JClouds and remote service
|
||||||
|
if (counter == maxCounter) {
|
||||||
|
counter = 0;
|
||||||
|
blobStoreContext.close();
|
||||||
|
blobStoreContext = this.builder.buildView(BlobStoreContext.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a unique identifier for a bitstream.
|
||||||
|
*
|
||||||
|
* @return the generated identifier
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String generateId() {
|
||||||
|
return Utils.generateKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a bitstream as an InputStream.
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to retrieve
|
||||||
|
* @return the InputStream of the bitstream
|
||||||
|
* @throws IOException if an error occurs during retrieval
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InputStream get(final Bitstream bitstream) throws IOException {
|
||||||
|
final File file = getFile(bitstream);
|
||||||
|
return get(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a file as an InputStream.
|
||||||
|
*
|
||||||
|
* @param file the file to retrieve
|
||||||
|
* @return the InputStream of the file
|
||||||
|
* @throws IOException if an error occurs during retrieval
|
||||||
|
*/
|
||||||
|
private InputStream get(File file) throws IOException {
|
||||||
|
BlobStore blobStore = blobStoreContext.getBlobStore();
|
||||||
|
if (blobStore.blobExists(getContainer(), file.toString())) {
|
||||||
|
Blob blob = blobStore.getBlob(getContainer(), file.toString());
|
||||||
|
refreshContextIfNeeded();
|
||||||
|
return blob.getPayload().openStream();
|
||||||
|
}
|
||||||
|
throw new IOException("File not found: " + file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a bitstream from the cloud storage.
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to remove
|
||||||
|
* @throws IOException if an error occurs during removal
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void remove(Bitstream bitstream) throws IOException {
|
||||||
|
File file = getFile(bitstream);
|
||||||
|
BlobStore blobStore = blobStoreContext.getBlobStore();
|
||||||
|
blobStore.removeBlob(getContainer(), file.toString());
|
||||||
|
deleteParents(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility Method: Prefix the key with a subfolder, if this instance assets are stored within subfolder
|
||||||
|
*
|
||||||
|
* @param id DSpace bitstream internal ID
|
||||||
|
* @return full key prefixed with a subfolder, if applicable
|
||||||
|
*/
|
||||||
|
public String getFullKey(String id) {
|
||||||
|
StringBuilder bufFilename = new StringBuilder();
|
||||||
|
if (StringUtils.isNotEmpty(this.subfolder)) {
|
||||||
|
bufFilename.append(this.subfolder);
|
||||||
|
appendSeparator(bufFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.useRelativePath) {
|
||||||
|
bufFilename.append(getRelativePath(id));
|
||||||
|
} else {
|
||||||
|
bufFilename.append(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Container filepath for " + id + " is "
|
||||||
|
+ bufFilename.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufFilename.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the relative path for a bitstream.
|
||||||
|
*
|
||||||
|
* there are 2 cases:
|
||||||
|
* - conventional bitstream, conventional storage
|
||||||
|
* - registered bitstream, conventional storage
|
||||||
|
* conventional bitstream: dspace ingested, dspace random name/path
|
||||||
|
* registered bitstream: registered to dspace, any name/path
|
||||||
|
*
|
||||||
|
* @param sInternalId the internal ID of the bitstream
|
||||||
|
* @return the computed relative path
|
||||||
|
*/
|
||||||
|
private String getRelativePath(String sInternalId) {
|
||||||
|
BitstreamStorageService bitstreamStorageService = StorageServiceFactory.getInstance()
|
||||||
|
.getBitstreamStorageService();
|
||||||
|
|
||||||
|
String sIntermediatePath = StringUtils.EMPTY;
|
||||||
|
if (bitstreamStorageService.isRegisteredBitstream(sInternalId)) {
|
||||||
|
sInternalId = sInternalId.substring(2);
|
||||||
|
} else {
|
||||||
|
sInternalId = sanitizeIdentifier(sInternalId);
|
||||||
|
sIntermediatePath = getIntermediatePath(sInternalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sIntermediatePath + sInternalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes parent directories if they are empty.
|
||||||
|
*
|
||||||
|
* @param file the file whose parent directories to delete
|
||||||
|
*/
|
||||||
|
private void deleteParents(File file) {
|
||||||
|
if (file == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final BlobStore blobStore = blobStoreContext.getBlobStore();
|
||||||
|
for (int i = 0; i < directoryLevels; i++) {
|
||||||
|
final File directory = file.getParentFile();
|
||||||
|
final ListContainerOptions options = new ListContainerOptions();
|
||||||
|
options.inDirectory(directory.getPath());
|
||||||
|
long blobs = blobStore.countBlobs(getContainer(), options);
|
||||||
|
if (blobs != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
blobStore.deleteDirectory(getContainer(), directory.getPath());
|
||||||
|
file = directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a byte source as a bitstream.
|
||||||
|
*
|
||||||
|
* @param byteSource the byte source to store
|
||||||
|
* @param bitstream the bitstream to store
|
||||||
|
* @throws IOException if an error occurs during storage
|
||||||
|
*/
|
||||||
|
public void put(ByteSource byteSource, Bitstream bitstream) throws IOException {
|
||||||
|
|
||||||
|
String key = getFullKey(bitstream.getInternalId());
|
||||||
|
|
||||||
|
/* set type to sane default */
|
||||||
|
String type = MediaType.OCTET_STREAM.toString();
|
||||||
|
|
||||||
|
/* attempt to get type if the source is a Bitstream */
|
||||||
|
if (byteSource instanceof BitstreamByteSource) {
|
||||||
|
type = getMIMEType(((BitstreamByteSource) byteSource).getBitstream());
|
||||||
|
}
|
||||||
|
|
||||||
|
BlobStore blobStore = blobStoreContext.getBlobStore();
|
||||||
|
String container = getContainer();
|
||||||
|
|
||||||
|
if (!blobStore.containerExists(container)) {
|
||||||
|
blobStore.createContainerInLocation(null, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blob blob = blobStore.blobBuilder(key)
|
||||||
|
.payload(byteSource)
|
||||||
|
.contentDisposition(key)
|
||||||
|
.contentLength(byteSource.size())
|
||||||
|
.contentType(type)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/* Utilize large file transfer to S3 via multipart post */
|
||||||
|
blobStore.putBlob(container, blob, Builder.multipart());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a stream of bits.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If this method returns successfully, the bits have been stored.
|
||||||
|
* If an exception is thrown, the bits have not been stored.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to store
|
||||||
|
* @param in the stream of bits to store
|
||||||
|
* @throws IOException if a problem occurs while storing the bits
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void put(Bitstream bitstream, InputStream in) throws IOException {
|
||||||
|
String key = getFullKey(bitstream.getInternalId());
|
||||||
|
//Copy istream to temp file, and send the file, with some metadata
|
||||||
|
File scratchFile = File.createTempFile(bitstream.getInternalId(), "s3bs");
|
||||||
|
try {
|
||||||
|
|
||||||
|
FileUtils.copyInputStreamToFile(in, scratchFile);
|
||||||
|
long contentLength = scratchFile.length();
|
||||||
|
// The ETag may or may not be and MD5 digest of the object data.
|
||||||
|
// Therefore, we precalculate before uploading
|
||||||
|
String localChecksum = org.dspace.curate.Utils.checksum(scratchFile, CSA);
|
||||||
|
|
||||||
|
put(Files.asByteSource(scratchFile), bitstream);
|
||||||
|
|
||||||
|
bitstream.setSizeBytes(contentLength);
|
||||||
|
bitstream.setChecksum(localChecksum);
|
||||||
|
bitstream.setChecksumAlgorithm(CSA);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("put(" + bitstream.getInternalId() + ", is)", e);
|
||||||
|
throw new IOException(e);
|
||||||
|
} finally {
|
||||||
|
if (!scratchFile.delete()) {
|
||||||
|
scratchFile.deleteOnExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type of a bitstream.
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to get the MIME type for
|
||||||
|
* @return the MIME type of the bitstream
|
||||||
|
*/
|
||||||
|
public static String getMIMEType(final Bitstream bitstream) {
|
||||||
|
try {
|
||||||
|
BitstreamFormat format = bitstream.getFormat(new Context());
|
||||||
|
return format == null ? null : format.getMIMEType();
|
||||||
|
} catch (SQLException ignored) {
|
||||||
|
throw new RuntimeException(ignored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves metadata about a bitstream.
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to retrieve metadata for
|
||||||
|
* @param attrs the list of attributes to retrieve
|
||||||
|
* @return a map of metadata attributes and their values
|
||||||
|
* @throws IOException if an error occurs during retrieval
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Map<String, Object> about(Bitstream bitstream, List<String> attrs) throws IOException {
|
||||||
|
File file = getFile(bitstream);
|
||||||
|
BlobStore blobStore = blobStoreContext.getBlobStore();
|
||||||
|
BlobMetadata blobMetadata = blobStore.blobMetadata(getContainer(), file.toString());
|
||||||
|
Map<String, Object> metadata = new HashMap<>();
|
||||||
|
if (blobMetadata != null) {
|
||||||
|
ContentMetadata contentMetadata = blobMetadata.getContentMetadata();
|
||||||
|
|
||||||
|
if (contentMetadata != null) {
|
||||||
|
metadata.put("size_bytes", String.valueOf(contentMetadata.getContentLength()));
|
||||||
|
final HashCode hashCode = contentMetadata.getContentMD5AsHashCode();
|
||||||
|
if (hashCode != null) {
|
||||||
|
metadata.put("checksum", Utils.toHex(contentMetadata.getContentMD5AsHashCode().asBytes()));
|
||||||
|
metadata.put("checksum_algorithm", CSA);
|
||||||
|
}
|
||||||
|
metadata.put("modified", String.valueOf(blobMetadata.getLastModified().getTime()));
|
||||||
|
|
||||||
|
metadata.put("ContentDisposition", contentMetadata.getContentDisposition());
|
||||||
|
metadata.put("ContentEncoding", contentMetadata.getContentEncoding());
|
||||||
|
metadata.put("ContentLanguage", contentMetadata.getContentLanguage());
|
||||||
|
metadata.put("ContentType", contentMetadata.getContentType());
|
||||||
|
|
||||||
|
if (contentMetadata.getExpires() != null) {
|
||||||
|
metadata.put("Expires", contentMetadata.getExpires().getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the file corresponding to a bitstream.
|
||||||
|
*
|
||||||
|
* @param bitstream the bitstream to get the file for
|
||||||
|
* @return the file corresponding to the bitstream
|
||||||
|
* @throws IOException if an error occurs during retrieval
|
||||||
|
*/
|
||||||
|
public File getFile(Bitstream bitstream) throws IOException {
|
||||||
|
String id = bitstream.getInternalId();
|
||||||
|
id = getFullKey(id);
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Local filename for " + bitstream.getInternalId() + " is " + id);
|
||||||
|
}
|
||||||
|
return new File(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the container name for storing bitstreams.
|
||||||
|
*
|
||||||
|
* @return the container name
|
||||||
|
*/
|
||||||
|
private String getContainer() {
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
@@ -191,4 +191,11 @@ public interface BitstreamStorageService {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Long getLastModified(Bitstream bitstream) throws IOException;
|
Long getLastModified(Bitstream bitstream) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number for the incoming store
|
||||||
|
* @param incoming
|
||||||
|
*/
|
||||||
|
public void setIncomingExternal(int incoming);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
<name-map collection-handle="123456789/collection-test" submission-name="collectiontest"/>
|
<name-map collection-handle="123456789/collection-test" submission-name="collectiontest"/>
|
||||||
<name-map collection-entity-type="CustomEntityType" submission-name="entitytypetest"/>
|
<name-map collection-entity-type="CustomEntityType" submission-name="entitytypetest"/>
|
||||||
<name-map collection-handle="123456789/test-duplicate-detection" submission-name="test-duplicate-detection"/>
|
<name-map collection-handle="123456789/test-duplicate-detection" submission-name="test-duplicate-detection"/>
|
||||||
|
<name-map collection-handle="123456789/collection-test-patch" submission-name="publicationTestPatch"/>
|
||||||
<name-map collection-handle="123456789/enforced-relation" submission-name="enforcedRelation"/>
|
<name-map collection-handle="123456789/enforced-relation" submission-name="enforcedRelation"/>
|
||||||
</submission-map>
|
</submission-map>
|
||||||
|
|
||||||
@@ -195,6 +196,11 @@
|
|||||||
<processing-class>org.dspace.app.rest.submit.step.NotifyStep</processing-class>
|
<processing-class>org.dspace.app.rest.submit.step.NotifyStep</processing-class>
|
||||||
<type>coarnotify</type>
|
<type>coarnotify</type>
|
||||||
</step-definition>
|
</step-definition>
|
||||||
|
<step-definition id="upload-no-required-metadata" mandatory="true">
|
||||||
|
<heading>submit.progressbar.upload-no-required-metadata</heading>
|
||||||
|
<processing-class>org.dspace.app.rest.submit.step.UploadStep</processing-class>
|
||||||
|
<type>upload</type>
|
||||||
|
</step-definition>
|
||||||
|
|
||||||
<step-definition id="publicationStep" mandatory="true">
|
<step-definition id="publicationStep" mandatory="true">
|
||||||
<heading>submit.progressbar.describe.stepone</heading>
|
<heading>submit.progressbar.describe.stepone</heading>
|
||||||
@@ -311,6 +317,12 @@
|
|||||||
<step id="publicationStep"></step>
|
<step id="publicationStep"></step>
|
||||||
</submission-process>
|
</submission-process>
|
||||||
|
|
||||||
|
<submission-process name="publicationTestPatch">
|
||||||
|
<step id="collection" />
|
||||||
|
<step id="traditionalpageone" />
|
||||||
|
<step id="upload-no-required-metadata" />
|
||||||
|
<step id="license" />
|
||||||
|
</submission-process>
|
||||||
</submission-definitions>
|
</submission-definitions>
|
||||||
|
|
||||||
</item-submission>
|
</item-submission>
|
||||||
|
@@ -158,6 +158,7 @@ proxies.trusted.include_ui_ip = true
|
|||||||
|
|
||||||
# For the tests we have to disable this health indicator because there isn't a mock server and the calculated status was DOWN
|
# For the tests we have to disable this health indicator because there isn't a mock server and the calculated status was DOWN
|
||||||
management.health.solrOai.enabled = false
|
management.health.solrOai.enabled = false
|
||||||
|
management.health.seo.enabled = false
|
||||||
|
|
||||||
# Enable researcher profiles and orcid synchronization for tests
|
# Enable researcher profiles and orcid synchronization for tests
|
||||||
researcher-profile.entity-type = Person
|
researcher-profile.entity-type = Person
|
||||||
@@ -192,4 +193,13 @@ ldn.notify.inbox.block-untrusted-ip = true
|
|||||||
# ERROR LOGGING #
|
# ERROR LOGGING #
|
||||||
###########################################
|
###########################################
|
||||||
# Log full stacktrace of other common 4xx errors (for easier debugging of these errors in tests)
|
# Log full stacktrace of other common 4xx errors (for easier debugging of these errors in tests)
|
||||||
logging.server.include-stacktrace-for-httpcode = 422, 400
|
logging.server.include-stacktrace-for-httpcode = 422, 400
|
||||||
|
|
||||||
|
### JCloudSettings
|
||||||
|
|
||||||
|
# Enabled the JCloudStore
|
||||||
|
assetstore.jcloud.enabled = true
|
||||||
|
assetstore.jcloud.subfolder = assetstore
|
||||||
|
assetstore.jcloud.provider = filesystem
|
||||||
|
assetstore.jcloud.container = assetstore-jclouds-container
|
||||||
|
assetstore.jcloud.basedir = target/testing/dspace
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
<property name="map">
|
<property name="map">
|
||||||
<map>
|
<map>
|
||||||
<entry key="upload" value-ref="uploadConfigurationDefault" />
|
<entry key="upload" value-ref="uploadConfigurationDefault" />
|
||||||
|
<entry key="upload-no-required-metadata" value-ref="uploadConfigurationPublicationTestPatch" />
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -116,4 +117,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="uploadConfigurationPublicationTestPatch" class="org.dspace.submit.model.UploadConfiguration">
|
||||||
|
<property name="name" value="upload-no-required-metadata"/>
|
||||||
|
<property name="metadata" value="bitstream-metadata" />
|
||||||
|
<property name="options">
|
||||||
|
<list>
|
||||||
|
<ref bean="administrator"/>
|
||||||
|
<ref bean="openAccess"/>
|
||||||
|
<ref bean="embargoed" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<bean id="dspace.DSpaceAuthorityIndexer" class="org.dspace.authority.indexer.DSpaceAuthorityIndexer"/>
|
<bean id="dspace.DSpaceAuthorityIndexer" class="org.dspace.authority.indexer.DSpaceAuthorityIndexer"/>
|
||||||
|
|
||||||
<alias name="OrcidSource" alias="AuthoritySource"/>
|
<alias name="OrcidSource" alias="AuthoritySource"/>
|
||||||
<bean name="OrcidSource" class="org.dspace.authority.orcid.MockOrcid" />
|
<bean name="OrcidSource" class="org.dspace.authority.orcid.MockOrcid" init-method="init" />
|
||||||
|
|
||||||
<bean name="AuthorityTypes" class="org.dspace.authority.AuthorityTypes">
|
<bean name="AuthorityTypes" class="org.dspace.authority.AuthorityTypes">
|
||||||
<property name="types">
|
<property name="types">
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user