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: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
time: "02:00"
|
||||
# Allow up to 10 open PRs for dependencies
|
||||
open-pull-requests-limit: 10
|
||||
# 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:
|
||||
# Architectures / Platforms for which we will build Docker images
|
||||
arch: [ 'linux/amd64', 'linux/arm64' ]
|
||||
os: [ ubuntu-latest ]
|
||||
isPr:
|
||||
- ${{ 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.
|
||||
# The below exclude therefore ensures we do NOT build ARM64 for PRs.
|
||||
exclude:
|
||||
- isPr: true
|
||||
os: ubuntu-latest
|
||||
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:
|
||||
# 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 }}
|
||||
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
|
||||
- name: Setup Docker Buildx
|
||||
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:
|
||||
|
||||
* 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 Java SDK for AWS KMS (com.amazonaws:aws-java-sdk-kms:1.12.261 - 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)
|
||||
* JMES Path Query library (com.amazonaws:jmespath-java: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.781 - 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.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)
|
||||
* 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/)
|
||||
* 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)
|
||||
* Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.16.0 - https://github.com/FasterXML/jackson)
|
||||
* Jackson-core (com.fasterxml.jackson.core:jackson-core:2.16.0 - https://github.com/FasterXML/jackson-core)
|
||||
* jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.16.0 - https://github.com/FasterXML/jackson)
|
||||
* Jackson dataformat: CBOR (com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.12.6 - http://github.com/FasterXML/jackson-dataformats-binary)
|
||||
* Internet Time Utility (com.ethlo.time:itu:1.7.0 - https://github.com/ethlo/itu)
|
||||
* ClassMate (com.fasterxml:classmate:1.5.1 - https://github.com/FasterXML/java-classmate)
|
||||
* Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.18.2 - https://github.com/FasterXML/jackson)
|
||||
* Jackson-core (com.fasterxml.jackson.core:jackson-core:2.18.2 - https://github.com/FasterXML/jackson-core)
|
||||
* 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-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 datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.4 - 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: 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.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: 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-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.15.4 - 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)
|
||||
* 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.1.0 - https://github.com/cowtowncoder/java-uuid-generator)
|
||||
* 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/)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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-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)
|
||||
* 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)
|
||||
* 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/)
|
||||
* Gson (com.google.code.gson:gson:2.10.1 - https://github.com/google/gson/gson)
|
||||
* error-prone annotations (com.google.errorprone:error_prone_annotations:2.10.0 - https://errorprone.info/error_prone_annotations)
|
||||
* Gson (com.google.code.gson:gson:2.12.1 - https://github.com/google/gson)
|
||||
* 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: Google Core Libraries for Java (com.google.guava:guava:32.0.0-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: Google Core Libraries for Java (com.google.guava:guava:32.1.3-jre - https://github.com/google/guava)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* Google Guice - Core Library (com.google.inject:guice:7.0.0 - https://github.com/google/guice/guice)
|
||||
* Google Guice - Extensions - AssistedInject (com.google.inject.extensions:guice-assistedinject:7.0.0 - https://github.com/google/guice/extensions-parent/guice-assistedinject)
|
||||
* 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/)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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 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)
|
||||
* opencsv (com.opencsv:opencsv:5.9 - http://opencsv.sf.net)
|
||||
* JsonSchemaValidator (com.networknt:json-schema-validator:1.0.76 - https://github.com/networknt/json-schema-validator)
|
||||
* 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)
|
||||
* 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)
|
||||
@@ -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)
|
||||
* 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)
|
||||
* Apache Commons BeanUtils (commons-beanutils:commons-beanutils:1.9.4 - 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 Codec (commons-codec:commons-codec:1.16.0 - https://commons.apache.org/proper/commons-codec/)
|
||||
* 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.9.0 - https://commons.apache.org/proper/commons-cli/)
|
||||
* 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/)
|
||||
* 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/)
|
||||
* Apache Commons Logging (commons-logging:commons-logging:1.3.0 - 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 Logging (commons-logging:commons-logging:1.3.5 - https://commons.apache.org/proper/commons-logging/)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* micrometer-commons (io.micrometer:micrometer-commons:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
||||
* micrometer-core (io.micrometer:micrometer-core:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
||||
* micrometer-jakarta9 (io.micrometer:micrometer-jakarta9:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
||||
* micrometer-observation (io.micrometer:micrometer-observation:1.12.6 - https://github.com/micrometer-metrics/micrometer)
|
||||
* Netty/Buffer (io.netty:netty-buffer:4.1.106.Final - https://netty.io/netty-buffer/)
|
||||
* micrometer-commons (io.micrometer:micrometer-commons:1.14.5 - 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.14.4 - 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.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/HTTP (io.netty:netty-codec-http:4.1.53.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/Common (io.netty:netty-common:4.1.106.Final - https://netty.io/netty-common/)
|
||||
* Netty/Codec/HTTP (io.netty:netty-codec-http:4.1.86.Final - https://netty.io/netty-codec-http/)
|
||||
* Netty/Codec/HTTP2 (io.netty:netty-codec-http2:4.1.86.Final - https://netty.io/netty-codec-http2/)
|
||||
* 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/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/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/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/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/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/)
|
||||
* 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-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)
|
||||
* 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-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-core (io.swagger:swagger-core:1.6.2 - 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-parser (io.swagger:swagger-parser:1.0.52 - 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: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.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.9 - https://github.com/swagger-api/swagger-core/modules/swagger-core)
|
||||
* 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.64 - http://nexus.sonatype.org/oss-repository-hosting.html/swagger-parser-project/modules/swagger-parser)
|
||||
* 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-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-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-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-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-core:2.0.23 - 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-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 (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.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.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.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 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)
|
||||
* 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)
|
||||
* 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.14.11 - https://bytebuddy.net/byte-buddy)
|
||||
* 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)
|
||||
* 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/)
|
||||
* 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.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)
|
||||
* 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)
|
||||
* Apache Ant Core (org.apache.ant:ant:1.10.14 - https://ant.apache.org/)
|
||||
* Apache Ant Launcher (org.apache.ant:ant-launcher:1.10.14 - https://ant.apache.org/)
|
||||
* Apache Commons BCEL (org.apache.bcel:bcel:6.7.0 - https://commons.apache.org/proper/commons-bcel)
|
||||
* Apache Ant Core (org.apache.ant:ant:1.10.15 - 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.10.0 - https://commons.apache.org/proper/commons-bcel)
|
||||
* 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)
|
||||
* 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 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 Configuration (org.apache.commons:commons-configuration2:2.10.1 - 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 DBCP (org.apache.commons:commons-dbcp2:2.11.0 - https://commons.apache.org/dbcp/)
|
||||
* 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.11.0 - https://commons.apache.org/proper/commons-configuration/)
|
||||
* 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.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.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 Pool (org.apache.commons:commons-pool2:2.12.0 - 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 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.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 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)
|
||||
@@ -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 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.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.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.2.4 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2.4/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 :: DOM (org.apache.james:apache-mime4j-dom:0.8.11 - 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/)
|
||||
* Apache Jena - ARQ (org.apache.jena:jena-arq:4.9.0 - https://jena.apache.org/jena-arq/)
|
||||
* Apache Jena - Base (org.apache.jena:jena-base:4.9.0 - https://jena.apache.org/jena-base/)
|
||||
* Apache Jena - Core (org.apache.jena:jena-core:4.9.0 - https://jena.apache.org/jena-core/)
|
||||
* Apache Jena - DBOE Base (org.apache.jena:jena-dboe-base:4.9.0 - https://jena.apache.org/jena-dboe-base/)
|
||||
* Apache Jena - DBOE Indexes (org.apache.jena:jena-dboe-index:4.9.0 - https://jena.apache.org/jena-dboe-index/)
|
||||
* Apache Jena - DBOE Storage (org.apache.jena:jena-dboe-storage:4.9.0 - https://jena.apache.org/jena-dboe-storage/)
|
||||
* 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 - DBOE Transactions (org.apache.jena:jena-dboe-transaction:4.9.0 - https://jena.apache.org/jena-dboe-transaction/)
|
||||
* Apache Jena - IRI (org.apache.jena:jena-iri:4.9.0 - https://jena.apache.org/jena-iri/)
|
||||
* Apache Jena - RDF Connection (org.apache.jena:jena-rdfconnection:4.9.0 - https://jena.apache.org/jena-rdfconnection/)
|
||||
* Apache Jena - RDF Patch (org.apache.jena:jena-rdfpatch:4.9.0 - https://jena.apache.org/jena-rdfpatch/)
|
||||
* Apache Jena - SHACL (org.apache.jena:jena-shacl:4.9.0 - https://jena.apache.org/jena-shacl/)
|
||||
* Apache Jena - ShEx (org.apache.jena:jena-shex:4.9.0 - https://jena.apache.org/jena-shex/)
|
||||
* Apache Jena - TDB1 (Native Triple Store) (org.apache.jena:jena-tdb:4.9.0 - https://jena.apache.org/jena-tdb/)
|
||||
* Apache Jena - TDB2 (Native Triple Store) (org.apache.jena:jena-tdb2:4.9.0 - https://jena.apache.org/jena-tdb2/)
|
||||
* 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.12 - http://james.apache.org/mime4j/apache-mime4j-core)
|
||||
* Apache James :: Mime4j :: DOM (org.apache.james:apache-mime4j-dom:0.8.12 - http://james.apache.org/mime4j/apache-mime4j-dom)
|
||||
* jclouds blobstore core (org.apache.jclouds:jclouds-blobstore:2.6.0 - https://jclouds.apache.org/jclouds-blobstore/)
|
||||
* jclouds Components Core (org.apache.jclouds:jclouds-core:2.6.0 - https://jclouds.apache.org/jclouds-core/)
|
||||
* jclouds filesystem core (org.apache.jclouds.api:filesystem:2.6.0 - https://jclouds.apache.org/filesystem/)
|
||||
* jclouds s3 api (org.apache.jclouds.api:s3:2.6.0 - https://jclouds.apache.org/s3/)
|
||||
* jclouds sts api (org.apache.jclouds.api:sts:2.6.0 - https://jclouds.apache.org/sts/)
|
||||
* jclouds Amazon Simple Storage Service (S3) provider (org.apache.jclouds.provider:aws-s3:2.6.0 - https://jclouds.apache.org/aws-s3/)
|
||||
* Apache Jena - Libraries POM (org.apache.jena:apache-jena-libs:4.10.0 - https://jena.apache.org/apache-jena-libs/)
|
||||
* Apache Jena - ARQ (org.apache.jena:jena-arq:4.10.0 - https://jena.apache.org/jena-arq/)
|
||||
* Apache Jena - Base (org.apache.jena:jena-base:4.10.0 - https://jena.apache.org/jena-base/)
|
||||
* Apache Jena - Core (org.apache.jena:jena-core:4.10.0 - https://jena.apache.org/jena-core/)
|
||||
* Apache Jena - DBOE Base (org.apache.jena:jena-dboe-base:4.10.0 - https://jena.apache.org/jena-dboe-base/)
|
||||
* Apache Jena - DBOE Indexes (org.apache.jena:jena-dboe-index:4.10.0 - https://jena.apache.org/jena-dboe-index/)
|
||||
* Apache Jena - DBOE Storage (org.apache.jena:jena-dboe-storage:4.10.0 - https://jena.apache.org/jena-dboe-storage/)
|
||||
* 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 - DBOE Transactions (org.apache.jena:jena-dboe-transaction:4.10.0 - https://jena.apache.org/jena-dboe-transaction/)
|
||||
* 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 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 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 API (org.apache.logging.log4j:log4j-api:2.23.1 - 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 JUL Adapter (org.apache.logging.log4j:log4j-jul:2.23.1 - https://logging.apache.org/log4j/2.x/log4j/log4j-jul/)
|
||||
* 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.24.3 - https://logging.apache.org/log4j/2.x/log4j/log4j-api/)
|
||||
* 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.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 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 2.0 Binding (org.apache.logging.log4j:log4j-slf4j2-impl:2.21.1 - 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/)
|
||||
* Lucene Common Analyzers (org.apache.lucene:lucene-analyzers-common:8.11.3 - 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 Kuromoji Japanese Morphological Analyzer (org.apache.lucene:lucene-analyzers-kuromoji:8.11.3 - 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 Phonetic Filters (org.apache.lucene:lucene-analyzers-phonetic:8.11.3 - 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 Stempel Analyzer (org.apache.lucene:lucene-analyzers-stempel:8.11.3 - 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 Classification (org.apache.lucene:lucene-classification:8.11.3 - 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 Core (org.apache.lucene:lucene-core:8.11.3 - 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 Grouping (org.apache.lucene:lucene-grouping:8.11.3 - 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 Join (org.apache.lucene:lucene-join:8.11.3 - 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 Miscellaneous (org.apache.lucene:lucene-misc:8.11.3 - 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 QueryParsers (org.apache.lucene:lucene-queryparser:8.11.3 - 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 Spatial Extras (org.apache.lucene:lucene-spatial-extras:8.11.3 - 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 Suggest (org.apache.lucene:lucene-suggest:8.11.3 - https://lucene.apache.org/lucene-parent/lucene-suggest)
|
||||
* Apache FontBox (org.apache.pdfbox:fontbox:2.0.31 - http://pdfbox.apache.org/)
|
||||
* Apache Log4j SLF4J Binding (org.apache.logging.log4j:log4j-slf4j-impl:2.17.2 - https://logging.apache.org/log4j/2.x/log4j-slf4j-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.17.2 - https://logging.apache.org/log4j/2.x/log4j-web/)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-icu)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-nori)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-analyzers-smartcn)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-backward-codecs)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-codecs)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-expressions)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-highlighter)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-memory)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-queries)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-sandbox)
|
||||
* 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.4 - https://lucene.apache.org/lucene-parent/lucene-spatial3d)
|
||||
* 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.33 - http://pdfbox.apache.org/)
|
||||
* 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 PDFBox (org.apache.pdfbox:pdfbox:2.0.31 - 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 XmpBox (org.apache.pdfbox:xmpbox:2.0.31 - https://www.apache.org/pdfbox-parent/xmpbox/)
|
||||
* Apache POI - Common (org.apache.poi:poi:5.2.5 - 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 (org.apache.poi:poi-ooxml-lite:5.2.5 - https://poi.apache.org/)
|
||||
* Apache POI (org.apache.poi:poi-scratchpad:5.2.5 - https://poi.apache.org/)
|
||||
* Apache Solr Core (org.apache.solr:solr-core:8.11.3 - https://lucene.apache.org/solr-parent/solr-core)
|
||||
* Apache Solr Solrj (org.apache.solr:solr-solrj:8.11.3 - https://lucene.apache.org/solr-parent/solr-solrj)
|
||||
* 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.33 - https://www.apache.org/pdfbox-parent/pdfbox-tools/)
|
||||
* Apache XmpBox (org.apache.pdfbox:xmpbox:2.0.33 - https://www.apache.org/pdfbox-parent/xmpbox/)
|
||||
* 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.4.0 - 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.4.0 - https://poi.apache.org/)
|
||||
* Apache XML Security for Java (org.apache.santuario:xmlsec:2.3.4 - https://santuario.apache.org/)
|
||||
* 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 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 Tika core (org.apache.tika:tika-core:2.9.2 - 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 audiovideo parser module (org.apache.tika:tika-parser-audiovideo-module:2.9.2 - 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 code parser module (org.apache.tika:tika-parser-code-module:2.9.2 - 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 digest commons (org.apache.tika:tika-parser-digest-commons:2.9.2 - 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 html parser module (org.apache.tika:tika-parser-html-module:2.9.2 - 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 mail commons (org.apache.tika:tika-parser-mail-commons:2.9.2 - 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 Microsoft parser module (org.apache.tika:tika-parser-microsoft-module:2.9.2 - 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 news parser module (org.apache.tika:tika-parser-news-module:2.9.2 - 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 PDF parser module (org.apache.tika:tika-parser-pdf-module:2.9.2 - 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 text parser module (org.apache.tika:tika-parser-text-module:2.9.2 - 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 XML parser module (org.apache.tika:tika-parser-xml-module:2.9.2 - 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 ZIP commons (org.apache.tika:tika-parser-zip-commons:2.9.2 - 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/)
|
||||
* tomcat-embed-core (org.apache.tomcat.embed:tomcat-embed-core:10.1.24 - https://tomcat.apache.org/)
|
||||
* tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:10.1.24 - https://tomcat.apache.org/)
|
||||
* tomcat-embed-websocket (org.apache.tomcat.embed:tomcat-embed-websocket:10.1.24 - 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 - JSR 223 Scripting (org.apache.velocity:velocity-engine-scripting:2.2 - http://velocity.apache.org/engine/devel/velocity-engine-scripting/)
|
||||
* Apache Thrift (org.apache.thrift:libthrift:0.19.0 - http://thrift.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.3 - https://tika.apache.org/tika-parser-apple-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.3 - https://tika.apache.org/tika-parser-cad-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.3 - https://tika.apache.org/tika-parser-crypto-module/)
|
||||
* 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.3 - https://tika.apache.org/tika-parser-font-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.3 - https://tika.apache.org/tika-parser-image-module/)
|
||||
* 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.3 - https://tika.apache.org/tika-parser-mail-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.3 - https://tika.apache.org/tika-parser-miscoffice-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.3 - https://tika.apache.org/tika-parser-ocr-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.3 - https://tika.apache.org/tika-parser-pkg-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.3 - https://tika.apache.org/tika-parser-webarchive-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.3 - https://tika.apache.org/tika-parser-xmp-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.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.36 - 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.36 - https://tomcat.apache.org/)
|
||||
* 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.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 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 - 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)
|
||||
* 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)
|
||||
* 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/)
|
||||
* 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)
|
||||
* Cryptacular Library (org.cryptacular:cryptacular:1.2.5 - http://www.cryptacular.org)
|
||||
* 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)
|
||||
* 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 :: 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 :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-deploy)
|
||||
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-http)
|
||||
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-io)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-http/)
|
||||
* 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 :: 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 :: 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.54.v20240208 - https://eclipse.org/jetty/jetty-security)
|
||||
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-server)
|
||||
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-servlet)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-server/)
|
||||
* 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.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 :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util-ajax)
|
||||
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-webapp)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-util-ajax/)
|
||||
* 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.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 :: 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 :: 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.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)
|
||||
* 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-database-postgresql (org.flywaydb:flyway-database-postgresql:10.10.0 - https://flywaydb.org/flyway-database-postgresql)
|
||||
* flyway-core (org.flywaydb:flyway-core:10.22.0 - https://flywaydb.org/flyway-core)
|
||||
* 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)
|
||||
* 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 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)
|
||||
* 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)
|
||||
* Javassist (org.javassist:javassist:3.29.2-GA - http://www.javassist.org/)
|
||||
* JBoss Logging 3 (org.jboss.logging:jboss-logging:3.4.3.Final - http://www.jboss.org)
|
||||
* Javassist (org.javassist:javassist:3.30.2-GA - https://www.javassist.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)
|
||||
* 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)
|
||||
* 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 Core (org.mock-server:mockserver-core:5.11.2 - http://www.mock-server.com)
|
||||
* MockServer JUnit 4 Integration (org.mock-server:mockserver-junit-rule:5.11.2 - http://www.mock-server.com)
|
||||
* MockServer & Proxy Netty (org.mock-server:mockserver-netty:5.11.2 - http://www.mock-server.com)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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.15.0 - https://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.15.0 - https://www.mock-server.com)
|
||||
* jwarc (org.netpreserve:jwarc:0.31.1 - https://github.com/iipc/jwarc)
|
||||
* Objenesis (org.objenesis:objenesis:3.2 - http://objenesis.org/objenesis)
|
||||
* parboiled-core (org.parboiled:parboiled-core:1.3.1 - http://parboiled.org)
|
||||
* parboiled-java (org.parboiled:parboiled-java:1.3.1 - http://parboiled.org)
|
||||
* org.roaringbitmap:RoaringBitmap (org.roaringbitmap:RoaringBitmap:0.9.45 - https://github.com/RoaringBitmap/RoaringBitmap)
|
||||
* org.roaringbitmap:shims (org.roaringbitmap:shims:0.9.45 - https://github.com/RoaringBitmap/RoaringBitmap)
|
||||
* OpenSAML :: Core (org.opensaml:opensaml-core:4.3.2 - http://shibboleth.net/opensaml-core/)
|
||||
* OpenSAML :: Messaging API (org.opensaml:opensaml-messaging-api:4.3.2 - http://shibboleth.net/opensaml-messaging-api/)
|
||||
* OpenSAML :: Profile API (org.opensaml:opensaml-profile-api:4.3.2 - http://shibboleth.net/opensaml-profile-api/)
|
||||
* 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/)
|
||||
* 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-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-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/)
|
||||
* JSONassert (org.skyscreamer:jsonassert:1.5.1 - https://github.com/skyscreamer/JSONassert)
|
||||
* JCL 1.2 implemented over SLF4J (org.slf4j:jcl-over-slf4j:2.0.11 - http://www.slf4j.org)
|
||||
* Spring AOP (org.springframework:spring-aop:6.1.8 - https://github.com/spring-projects/spring-framework)
|
||||
* Spring Beans (org.springframework:spring-beans:6.1.8 - 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 Support (org.springframework:spring-context-support:6.1.8 - https://github.com/spring-projects/spring-framework)
|
||||
* Spring Core (org.springframework:spring-core:6.1.8 - 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 Commons Logging Bridge (org.springframework:spring-jcl:6.1.8 - https://github.com/spring-projects/spring-framework)
|
||||
* Spring JDBC (org.springframework:spring-jdbc:6.1.8 - 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 TestContext Framework (org.springframework:spring-test:6.1.8 - https://github.com/spring-projects/spring-framework)
|
||||
* Spring Transaction (org.springframework:spring-tx:6.1.8 - 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 MVC (org.springframework:spring-webmvc:6.1.8 - 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-actuator (org.springframework.boot:spring-boot-actuator:3.2.6 - 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-autoconfigure (org.springframework.boot:spring-boot-autoconfigure:3.2.6 - https://spring.io/projects/spring-boot)
|
||||
* 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.16 - http://www.slf4j.org)
|
||||
* Spring AOP (org.springframework:spring-aop:6.2.4 - 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.2.4 - 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.2.4 - 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.2.4 - 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.2.4 - 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.2.4 - 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.2.4 - https://github.com/spring-projects/spring-framework)
|
||||
* 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.4.3 - 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.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-starter (org.springframework.boot:spring-boot-starter:3.2.6 - 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-aop (org.springframework.boot:spring-boot-starter-aop:3.2.6 - 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-data-rest (org.springframework.boot:spring-boot-starter-data-rest:3.2.6 - 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-log4j2 (org.springframework.boot:spring-boot-starter-log4j2:3.2.6 - 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-test (org.springframework.boot:spring-boot-starter-test:3.2.6 - 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-web (org.springframework.boot:spring-boot-starter-web:3.2.6 - 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-autoconfigure (org.springframework.boot:spring-boot-test-autoconfigure:3.2.6 - 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 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 - 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 HATEOAS (org.springframework.hateoas:spring-hateoas:2.2.2 - https://github.com/spring-projects/spring-hateoas)
|
||||
* 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.4.3 - 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.4.3 - 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.4.3 - 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.4.3 - 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.4.3 - 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.4.3 - 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.4.3 - https://spring.io/projects/spring-data)
|
||||
* 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.4.3 - https://www.spring.io/spring-data/spring-data-rest-parent/spring-data-rest-webmvc)
|
||||
* 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-security-config (org.springframework.security:spring-security-config:6.2.4 - 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-crypto (org.springframework.security:spring-security-crypto:6.2.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-web (org.springframework.security:spring-security-web: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.4.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-saml2-service-provider (org.springframework.security:spring-security-saml2-service-provider:6.4.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)
|
||||
* 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.9.1 - https://www.xmlunit.org/)
|
||||
* org.xmlunit:xmlunit-placeholders (org.xmlunit:xmlunit-placeholders:2.8.0 - https://www.xmlunit.org/xmlunit-placeholders/)
|
||||
* 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/)
|
||||
* org.xmlunit:xmlunit-placeholders (org.xmlunit:xmlunit-placeholders:2.9.1 - https://www.xmlunit.org/xmlunit-placeholders/)
|
||||
* SnakeYAML (org.yaml:snakeyaml:2.3 - https://bitbucket.org/snakeyaml/snakeyaml)
|
||||
* Xerces2-j (xerces:xercesImpl:2.12.2 - https://xerces.apache.org/xerces2-j/)
|
||||
|
||||
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/)
|
||||
* 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.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/)
|
||||
* 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)
|
||||
* 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/)
|
||||
* 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)
|
||||
* 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 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)
|
||||
* 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-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-util (org.ow2.asm:asm-util:7.1 - http://asm.ow2.org/)
|
||||
* PostgreSQL JDBC Driver (org.postgresql:postgresql:42.7.3 - https://jdbc.postgresql.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.5 - https://jdbc.postgresql.org)
|
||||
* Reflections (org.reflections:reflections:0.9.12 - http://github.com/ronmamo/reflections)
|
||||
* 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/)
|
||||
|
||||
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)
|
||||
* 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 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)
|
||||
* 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)
|
||||
@@ -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)
|
||||
* 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)
|
||||
* HK2 API module (org.glassfish.hk2:hk2-api:3.0.5 - 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)
|
||||
* HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.5 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils)
|
||||
* 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.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
||||
* 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)
|
||||
* 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)
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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)
|
||||
* 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.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)
|
||||
|
||||
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 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/)
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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-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)
|
||||
* 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)
|
||||
@@ -546,16 +576,16 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
||||
Eclipse Public License:
|
||||
|
||||
* 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 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 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 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)
|
||||
* 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)
|
||||
* 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/)
|
||||
@@ -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 :: 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 :: Deployers (org.eclipse.jetty:jetty-deploy:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-deploy)
|
||||
* Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-http)
|
||||
* Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-io)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-http/)
|
||||
* 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 :: 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 :: 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.54.v20240208 - https://eclipse.org/jetty/jetty-security)
|
||||
* Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-server)
|
||||
* Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-servlet)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-server/)
|
||||
* 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.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 :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-util-ajax)
|
||||
* Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.54.v20240208 - https://eclipse.org/jetty/jetty-webapp)
|
||||
* 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.57.v20241219 - https://jetty.org/jetty-util-ajax/)
|
||||
* 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.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 :: 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 :: 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.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)
|
||||
* 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)
|
||||
* ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.5 - 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 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.6 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator)
|
||||
* 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)
|
||||
* 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)
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||
* 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.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)
|
||||
* 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)
|
||||
* 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)
|
||||
* Jetty Utilities (org.mortbay.jetty:jetty-util:6.1.26 - http://www.eclipse.org/jetty/jetty-parent/project/jetty-util)
|
||||
|
||||
GENERAL PUBLIC LICENSE, version 3 (GPL-3.0):
|
||||
|
||||
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.5.0 - https://github.com/albfernandez/juniversalchardet)
|
||||
|
||||
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)
|
||||
* 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)
|
||||
* 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-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)
|
||||
* 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/)
|
||||
* 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 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-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/)
|
||||
* 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)
|
||||
|
||||
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)
|
||||
* 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)
|
||||
* 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)
|
||||
* 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)
|
||||
* Bouncy Castle S/MIME API (org.bouncycastle:bcmail-jdk18on:1.77 - https://www.bouncycastle.org/java.html)
|
||||
* 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.78.1 - https://www.bouncycastle.org/java.html)
|
||||
* Bouncy Castle Provider (org.bouncycastle:bcprov-jdk15on:1.67 - http://www.bouncycastle.org/java.html)
|
||||
* 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)
|
||||
* 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-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||
* Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||
* Bouncy Castle ASN.1 Extension and Utility APIs (org.bouncycastle:bcutil-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||||
* 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)
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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)
|
||||
* Checker Qual (org.checkerframework:checker-qual:3.49.0 - https://checkerframework.org/)
|
||||
* 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)
|
||||
* 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)
|
||||
* SLF4J API Module (org.slf4j:slf4j-api:2.0.11 - http://www.slf4j.org)
|
||||
* SLF4J Extensions Module (org.slf4j:slf4j-ext:1.7.28 - http://www.slf4j.org)
|
||||
* SLF4J API Module (org.slf4j:slf4j-api:2.0.16 - http://www.slf4j.org)
|
||||
* HAL Browser (org.webjars:hal-browser:ad9b865 - 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)
|
||||
@@ -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)
|
||||
* 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)
|
||||
* core-js (org.webjars.npm:core-js:3.37.1 - https://www.webjars.org)
|
||||
* @json-editor/json-editor (org.webjars.npm:json-editor__json-editor:2.6.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.15.1 - https://www.webjars.org)
|
||||
|
||||
Mozilla Public License:
|
||||
|
||||
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.4.0 - https://github.com/albfernandez/juniversalchardet)
|
||||
* H2 Database Engine (com.h2database:h2:2.2.224 - https://h2database.com)
|
||||
* juniversalchardet (com.github.albfernandez:juniversalchardet:2.5.0 - https://github.com/albfernandez/juniversalchardet)
|
||||
* 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/)
|
||||
* 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)
|
||||
|
||||
Public Domain:
|
||||
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.1.5 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2)
|
||||
* AOP alliance (aopalliance:aopalliance:1.0 - http://aopalliance.sourceforge.net)
|
||||
* 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)
|
||||
* 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)
|
||||
* LatencyUtils (org.latencyutils:LatencyUtils:2.0.3 - http://latencyutils.github.io/LatencyUtils/)
|
||||
* 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:
|
||||
|
||||
@@ -703,16 +738,16 @@ https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines
|
||||
|
||||
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:
|
||||
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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-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)
|
||||
|
||||
jQuery license:
|
||||
|
||||
* jersey-core-client (org.glassfish.jersey.core:jersey-client:3.1.5 - 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-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)
|
||||
|
@@ -7,4 +7,5 @@
|
||||
<!-- 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 -->
|
||||
<suppress checks="Indentation" files="src[/\\]test[/\\]java"/>
|
||||
<suppress checks="Regexp" files="DSpaceHttpClientFactory\.java"/>
|
||||
</suppressions>
|
||||
|
@@ -136,5 +136,22 @@ For more information on CheckStyle configurations below, see: http://checkstyle.
|
||||
<module name="OneStatementPerLine"/>
|
||||
<!-- Require that "catch" statements are not empty (must at least contain a comment) -->
|
||||
<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>
|
||||
|
@@ -93,7 +93,7 @@ services:
|
||||
additional_contexts:
|
||||
solrconfigs: ./dspace/solr/
|
||||
args:
|
||||
SOLR_VERSION: "${SOLR_VER:-8.11}"
|
||||
SOLR_VERSION: "${SOLR_VER:-9.8}"
|
||||
networks:
|
||||
dspacenet:
|
||||
ports:
|
||||
@@ -105,10 +105,15 @@ services:
|
||||
volumes:
|
||||
# Keep Solr data directory between reboots
|
||||
- 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:
|
||||
# * 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:
|
||||
# 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:
|
||||
- /bin/bash
|
||||
- '-c'
|
||||
@@ -126,7 +131,8 @@ services:
|
||||
cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent
|
||||
precreate-core suggestion /opt/solr/server/solr/configsets/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:
|
||||
assetstore:
|
||||
pgdata:
|
||||
|
@@ -177,7 +177,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>jaxb2-maven-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>workflow-curation</id>
|
||||
@@ -500,10 +500,6 @@
|
||||
<groupId>jakarta.annotation</groupId>
|
||||
<artifactId>jakarta.annotation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.el</groupId>
|
||||
<artifactId>jakarta.el-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
@@ -653,11 +649,18 @@
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- guava is needed by OAuth, Guice, Mockserver, ORCID, s3mock, Solr, JClouds -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Gson is needed by JENA, borker-client, OAuth, Handle and JClouds -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
@@ -731,7 +734,7 @@
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
<version>1.12.781</version>
|
||||
<version>1.12.783</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 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>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Used for Solr core export/import -->
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>5.10</version>
|
||||
<version>5.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Email templating -->
|
||||
@@ -860,6 +864,55 @@
|
||||
</exclusions>
|
||||
</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 -->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
@@ -876,7 +929,20 @@
|
||||
<dependency>
|
||||
<groupId>org.xhtmlrenderer</groupId>
|
||||
<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>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@@ -21,6 +21,13 @@ import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
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.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.BitstreamFormat;
|
||||
@@ -41,7 +48,7 @@ import org.xml.sax.SAXException;
|
||||
* <P>
|
||||
* <code>RegistryLoader -bitstream bitstream-formats.xml</code>
|
||||
* <P>
|
||||
* <code>RegistryLoader -dc dc-types.xml</code>
|
||||
* <code>RegistryLoader -metadata dc-types.xml</code>
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @version $Revision$
|
||||
@@ -50,7 +57,7 @@ public class RegistryLoader {
|
||||
/**
|
||||
* 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()
|
||||
.getBitstreamFormatService();
|
||||
@@ -67,50 +74,99 @@ public class RegistryLoader {
|
||||
* @throws Exception if error
|
||||
*/
|
||||
public static void main(String[] argv) throws Exception {
|
||||
String usage = "Usage: " + RegistryLoader.class.getName()
|
||||
+ " (-bitstream | -metadata) registry-file.xml";
|
||||
|
||||
Context context = null;
|
||||
// Set up command-line options and parse arguments
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
Options options = createCommandLineOptions();
|
||||
|
||||
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
|
||||
// authorisation
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Work out what we're loading
|
||||
if (argv[0].equalsIgnoreCase("-bitstream")) {
|
||||
RegistryLoader.loadBitstreamFormats(context, argv[1]);
|
||||
} else if (argv[0].equalsIgnoreCase("-metadata")) {
|
||||
// Call MetadataImporter, as it handles Metadata schema updates
|
||||
MetadataImporter.loadRegistry(argv[1], true);
|
||||
} else {
|
||||
System.err.println(usage);
|
||||
try {
|
||||
// Work out what we're loading
|
||||
if (line.hasOption('b')) {
|
||||
String filename = line.getOptionValue('b');
|
||||
if (StringUtils.isEmpty(filename)) {
|
||||
System.err.println("No file path provided for bitstream format registry");
|
||||
printHelp(options);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// Commit changes and close Context
|
||||
context.complete();
|
||||
|
||||
System.exit(0);
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
System.err.println(usage);
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println("Error parsing command-line arguments: " + e.getMessage());
|
||||
printHelp(options);
|
||||
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
|
||||
*
|
||||
@@ -221,7 +277,7 @@ public class RegistryLoader {
|
||||
* contains:
|
||||
* <P>
|
||||
* <code>
|
||||
* <foo><mimetype>application/pdf</mimetype></foo>
|
||||
* <foo><mimetype>application/pdf</mimetype></foo>
|
||||
* </code>
|
||||
* passing this the <code>foo</code> node and <code>mimetype</code> will
|
||||
* return <code>application/pdf</code>.
|
||||
@@ -262,10 +318,10 @@ public class RegistryLoader {
|
||||
* document contains:
|
||||
* <P>
|
||||
* <code>
|
||||
* <foo>
|
||||
* <bar>val1</bar>
|
||||
* <bar>val2</bar>
|
||||
* </foo>
|
||||
* <foo>
|
||||
* <bar>val1</bar>
|
||||
* <bar>val2</bar>
|
||||
* </foo>
|
||||
* </code>
|
||||
* passing this the <code>foo</code> node and <code>bar</code> will
|
||||
* return <code>val1</code> and <code>val2</code>.
|
||||
@@ -295,4 +351,4 @@ public class RegistryLoader {
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
@@ -416,7 +416,7 @@ public class BulkAccessControl extends DSpaceRunnable<BulkAccessControlScriptCon
|
||||
discoverQuery.setQuery(query);
|
||||
discoverQuery.setStart(start);
|
||||
discoverQuery.setMaxResults(limit);
|
||||
|
||||
discoverQuery.setSortField("search.resourceid", DiscoverQuery.SORT_ORDER.asc);
|
||||
return discoverQuery;
|
||||
}
|
||||
|
||||
|
@@ -142,7 +142,8 @@ public class MetadataExportFilteredItemsReport extends DSpaceRunnable
|
||||
|
||||
FilteredItems items = contentReportService.findFilteredItems(context, query);
|
||||
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.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||
context.restoreAuthSystemState();
|
||||
|
@@ -143,7 +143,7 @@ public class MetadataExportSearch extends DSpaceRunnable<MetadataExportSearchScr
|
||||
|
||||
Iterator<Item> itemIterator = searchService.iteratorSearch(context, dso, discoverQuery);
|
||||
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.writeFilestream(context, getFileNameOrExportFile(), dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||
context.restoreAuthSystemState();
|
||||
|
@@ -23,6 +23,7 @@ import java.util.UUID;
|
||||
|
||||
import jakarta.annotation.Nullable;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.util.RelationshipUtils;
|
||||
@@ -89,7 +90,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
||||
/**
|
||||
* The authority controlled fields
|
||||
*/
|
||||
protected static Set<String> authorityControlled;
|
||||
protected Set<String> authorityControlled;
|
||||
|
||||
/**
|
||||
* The prefix of the authority controlled field
|
||||
@@ -742,10 +743,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
||||
if (value == null || !value.contains(csv.getAuthoritySeparator())) {
|
||||
simplyCopyValue(value, dcv);
|
||||
} else {
|
||||
String[] parts = value.split(csv.getAuthoritySeparator());
|
||||
dcv.setValue(parts[0]);
|
||||
dcv.setAuthority(parts[1]);
|
||||
dcv.setConfidence((parts.length > 2 ? Integer.valueOf(parts[2]) : Choices.CF_ACCEPTED));
|
||||
resolveValueAndAuthority(value, dcv);
|
||||
}
|
||||
|
||||
// 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())) {
|
||||
simplyCopyValue(value, dcv);
|
||||
} else {
|
||||
String[] parts = value.split(csv.getEscapedAuthoritySeparator());
|
||||
dcv.setValue(parts[0]);
|
||||
dcv.setAuthority(parts[1]);
|
||||
dcv.setConfidence((parts.length > 2 ? Integer.valueOf(parts[2]) : Choices.CF_ACCEPTED));
|
||||
resolveValueAndAuthority(value, dcv);
|
||||
}
|
||||
return dcv;
|
||||
}
|
||||
@@ -1176,6 +1171,35 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
||||
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
|
||||
*
|
||||
@@ -1368,10 +1392,10 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
||||
/**
|
||||
* 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;
|
||||
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) {
|
||||
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.entity.StringEntity;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.app.ldn.model.Notification;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
@@ -34,21 +34,13 @@ public class SendLDNMessageAction implements LDNAction {
|
||||
|
||||
private static final Logger log = LogManager.getLogger(SendLDNMessageAction.class);
|
||||
|
||||
private CloseableHttpClient client = null;
|
||||
private CloseableHttpClient client;
|
||||
|
||||
public SendLDNMessageAction() {
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
client = builder
|
||||
.disableAutomaticRetries()
|
||||
.setMaxConnTotal(5)
|
||||
.build();
|
||||
}
|
||||
|
||||
public SendLDNMessageAction(CloseableHttpClient client) {
|
||||
this();
|
||||
if (client != null) {
|
||||
this.client = client;
|
||||
}
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@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"
|
||||
// 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
|
||||
try (
|
||||
CloseableHttpResponse response = client.execute(httpPost);
|
||||
) {
|
||||
if (client == null) {
|
||||
client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5);
|
||||
}
|
||||
try (CloseableHttpResponse response = client.execute(httpPost)) {
|
||||
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
||||
result = LDNActionStatus.CONTINUE;
|
||||
} else if (isRedirect(response.getStatusLine().getStatusCode())) {
|
||||
@@ -77,6 +70,7 @@ public class SendLDNMessageAction implements LDNAction {
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
}
|
||||
client.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -91,9 +85,9 @@ public class SendLDNMessageAction implements LDNAction {
|
||||
statusCode == HttpStatus.SC_TEMPORARY_REDIRECT;
|
||||
}
|
||||
|
||||
private LDNActionStatus handleRedirect(CloseableHttpResponse oldresponse,
|
||||
private LDNActionStatus handleRedirect(CloseableHttpResponse oldResponse,
|
||||
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;
|
||||
if (url == null) {
|
||||
throw new HttpException("Error following redirect, unable to reach"
|
||||
@@ -102,17 +96,14 @@ public class SendLDNMessageAction implements LDNAction {
|
||||
LDNActionStatus result = LDNActionStatus.ABORT;
|
||||
try {
|
||||
request.setURI(new URI(url));
|
||||
try (
|
||||
CloseableHttpResponse response = client.execute(request);
|
||||
) {
|
||||
try (CloseableHttpResponse response = client.execute(request)) {
|
||||
if (isSuccessful(response.getStatusLine().getStatusCode())) {
|
||||
return LDNActionStatus.CONTINUE;
|
||||
result = LDNActionStatus.CONTINUE;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error following redirect:", e);
|
||||
}
|
||||
|
||||
return LDNActionStatus.ABORT;
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -141,7 +141,7 @@ public class TikaTextExtractionFilter
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
try {
|
||||
writer.append(new String(ch), start, length);
|
||||
writer.append(new String(ch, start, length));
|
||||
} catch (IOException e) {
|
||||
String errorMsg = String.format("Could not append to temporary file at %s " +
|
||||
"when performing text extraction",
|
||||
@@ -159,7 +159,7 @@ public class TikaTextExtractionFilter
|
||||
@Override
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
try {
|
||||
writer.append(new String(ch), start, length);
|
||||
writer.append(new String(ch, start, length));
|
||||
} catch (IOException e) {
|
||||
String errorMsg = String.format("Could not append to temporary file at %s " +
|
||||
"when performing text extraction",
|
||||
|
@@ -17,15 +17,15 @@ import jakarta.annotation.PostConstruct;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
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.utils.URIBuilder;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.app.sherpa.v2.SHERPAPublisherResponse;
|
||||
import org.dspace.app.sherpa.v2.SHERPAResponse;
|
||||
import org.dspace.app.sherpa.v2.SHERPAUtils;
|
||||
@@ -45,8 +45,6 @@ import org.springframework.cache.annotation.Cacheable;
|
||||
*/
|
||||
public class SHERPAService {
|
||||
|
||||
private CloseableHttpClient client = null;
|
||||
|
||||
private int maxNumberOfTries;
|
||||
private long sleepBetweenTimeouts;
|
||||
private int timeout = 5000;
|
||||
@@ -59,19 +57,6 @@ public class SHERPAService {
|
||||
@Autowired
|
||||
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.
|
||||
*/
|
||||
@@ -132,46 +117,47 @@ public class SHERPAService {
|
||||
timeout,
|
||||
sleepBetweenTimeouts));
|
||||
|
||||
try {
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5)) {
|
||||
Thread.sleep(sleepBetweenTimeouts);
|
||||
|
||||
// Construct a default HTTP method (first result)
|
||||
method = constructHttpGet(type, field, predicate, value, start, limit);
|
||||
|
||||
// Execute the method
|
||||
HttpResponse response = client.execute(method);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
try (CloseableHttpResponse response = client.execute(method)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||
+ response.getStatusLine().getReasonPhrase());
|
||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||
+ response.getStatusLine().getReasonPhrase());
|
||||
|
||||
if (statusCode != HttpStatus.SC_OK) {
|
||||
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: "
|
||||
+ statusCode);
|
||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||
}
|
||||
|
||||
HttpEntity responseBody = response.getEntity();
|
||||
|
||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||
if (null != responseBody) {
|
||||
log.debug("Non-null SHERPA response received for query of " + value);
|
||||
InputStream content = null;
|
||||
try {
|
||||
content = responseBody.getContent();
|
||||
sherpaResponse =
|
||||
new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON);
|
||||
} catch (IOException e) {
|
||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (content != null) {
|
||||
content.close();
|
||||
}
|
||||
if (statusCode != HttpStatus.SC_OK) {
|
||||
sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: "
|
||||
+ statusCode);
|
||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||
}
|
||||
|
||||
HttpEntity responseBody = response.getEntity();
|
||||
|
||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||
if (null != responseBody) {
|
||||
log.debug("Non-null SHERPA response received for query of " + value);
|
||||
InputStream content = null;
|
||||
try {
|
||||
content = responseBody.getContent();
|
||||
sherpaResponse =
|
||||
new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON);
|
||||
} catch (IOException e) {
|
||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (content != null) {
|
||||
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) {
|
||||
String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage();
|
||||
@@ -235,45 +221,46 @@ public class SHERPAService {
|
||||
timeout,
|
||||
sleepBetweenTimeouts));
|
||||
|
||||
try {
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5)) {
|
||||
Thread.sleep(sleepBetweenTimeouts);
|
||||
|
||||
// Construct a default HTTP method (first result)
|
||||
method = constructHttpGet(type, field, predicate, value, start, limit);
|
||||
|
||||
// Execute the method
|
||||
HttpResponse response = client.execute(method);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
try (CloseableHttpResponse response = client.execute(method)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||
+ response.getStatusLine().getReasonPhrase());
|
||||
log.debug(response.getStatusLine().getStatusCode() + ": "
|
||||
+ response.getStatusLine().getReasonPhrase());
|
||||
|
||||
if (statusCode != HttpStatus.SC_OK) {
|
||||
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: "
|
||||
+ statusCode);
|
||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||
}
|
||||
|
||||
HttpEntity responseBody = response.getEntity();
|
||||
|
||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||
if (null != responseBody) {
|
||||
log.debug("Non-null SHERPA response received for query of " + value);
|
||||
InputStream content = null;
|
||||
try {
|
||||
content = responseBody.getContent();
|
||||
sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON);
|
||||
} catch (IOException e) {
|
||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (content != null) {
|
||||
content.close();
|
||||
}
|
||||
if (statusCode != HttpStatus.SC_OK) {
|
||||
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: "
|
||||
+ statusCode);
|
||||
String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
log.error("Error from SHERPA HTTP request: " + errorBody);
|
||||
}
|
||||
|
||||
HttpEntity responseBody = response.getEntity();
|
||||
|
||||
// If the response body is valid, pass to SHERPAResponse for parsing as JSON
|
||||
if (null != responseBody) {
|
||||
log.debug("Non-null SHERPA response received for query of " + value);
|
||||
InputStream content = null;
|
||||
try {
|
||||
content = responseBody.getContent();
|
||||
sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON);
|
||||
} catch (IOException e) {
|
||||
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (content != null) {
|
||||
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) {
|
||||
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();
|
||||
log.error(errorMessage, e);
|
||||
sherpaResponse = new SHERPAResponse(errorMessage);
|
||||
} catch (InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
String errorMessage = "Encountered exception while sleeping thread: " + e.getMessage();
|
||||
log.error(errorMessage, e);
|
||||
sherpaResponse = new SHERPAResponse(errorMessage);
|
||||
|
@@ -1231,8 +1231,8 @@ public class LogAnalyser {
|
||||
}
|
||||
accessionedQuery.append("]");
|
||||
discoverQuery.addFilterQueries(accessionedQuery.toString());
|
||||
discoverQuery.addFilterQueries("withdrawn: false");
|
||||
discoverQuery.addFilterQueries("archived: true");
|
||||
discoverQuery.addFilterQueries("withdrawn:false");
|
||||
discoverQuery.addFilterQueries("archived:true");
|
||||
|
||||
return (int) SearchUtils.getSearchService().search(context, discoverQuery).getTotalSearchResults();
|
||||
}
|
||||
|
@@ -119,8 +119,11 @@ public class PublicationLoaderRunnable
|
||||
DiscoverResultItemIterator researchers = findResearchers();
|
||||
while (researchers.hasNext()) {
|
||||
Item researcher = researchers.next();
|
||||
researcher = context.reloadEntity(researcher);
|
||||
publicationLoader.importRecords(context, researcher);
|
||||
setLastImportMetadataValue(researcher);
|
||||
context.commit();
|
||||
context.uncacheEntity(researcher);
|
||||
}
|
||||
} finally {
|
||||
context.restoreAuthSystemState();
|
||||
|
@@ -64,20 +64,36 @@ public class InitializeEntities {
|
||||
*/
|
||||
public static void main(String[] argv) throws SQLException, AuthorizeException, ParseException {
|
||||
InitializeEntities initializeEntities = new InitializeEntities();
|
||||
// Set up command-line options and parse arguments
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
Options options = createCommandLineOptions();
|
||||
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);
|
||||
// Get the file location from the command line
|
||||
String fileLocation = getFileLocationFromCommandLine(line);
|
||||
// Run the script
|
||||
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) {
|
||||
if (line.hasOption("h")) {
|
||||
if (line.hasOption("h") || !line.hasOption("f")) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp("Initialize Entities", options);
|
||||
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) {
|
||||
String query = line.getOptionValue("f");
|
||||
if (StringUtils.isEmpty(query)) {
|
||||
@@ -88,13 +104,25 @@ public class InitializeEntities {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the command-line options
|
||||
* @return the command-line options
|
||||
*/
|
||||
protected static Options createCommandLineOptions() {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
Context context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
@@ -102,6 +130,12 @@ public class InitializeEntities {
|
||||
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 {
|
||||
try {
|
||||
File fXmlFile = new File(fileLocation);
|
||||
@@ -158,15 +192,15 @@ public class InitializeEntities {
|
||||
|
||||
for (int j = 0; j < leftCardinalityList.getLength(); j++) {
|
||||
Node node = leftCardinalityList.item(j);
|
||||
leftCardinalityMin = getString(leftCardinalityMin,(Element) node, "min");
|
||||
leftCardinalityMax = getString(leftCardinalityMax,(Element) node, "max");
|
||||
leftCardinalityMin = getCardinalityMinString(leftCardinalityMin,(Element) node, "min");
|
||||
leftCardinalityMax = getCardinalityMinString(leftCardinalityMax,(Element) node, "max");
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < rightCardinalityList.getLength(); j++) {
|
||||
Node node = rightCardinalityList.item(j);
|
||||
rightCardinalityMin = getString(rightCardinalityMin,(Element) node, "min");
|
||||
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
||||
rightCardinalityMin = getCardinalityMinString(rightCardinalityMin,(Element) node, "min");
|
||||
rightCardinalityMax = getCardinalityMinString(rightCardinalityMax,(Element) node, "max");
|
||||
|
||||
}
|
||||
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) {
|
||||
leftCardinalityMin = node.getElementsByTagName(minOrMax).item(0).getTextContent();
|
||||
}
|
||||
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,
|
||||
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||
String rightCardinalityMin, String rightCardinalityMax,
|
||||
|
@@ -100,6 +100,14 @@ public class OpenSearchServiceImpl implements OpenSearchService {
|
||||
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
|
||||
public String getContentType(String format) {
|
||||
return "html".equals(format) ? "text/html" :
|
||||
|
@@ -257,8 +257,14 @@ public class SyndicationFeed {
|
||||
String pubDateString = getOneDC(item, dateField);
|
||||
if (pubDateString != null) {
|
||||
ZonedDateTime pubDate = new DCDate(pubDateString).toDate();
|
||||
entry.setPublishedDate(java.util.Date.from(pubDate.toInstant()));
|
||||
hasDate = true;
|
||||
// If date string could not be parsed as a date, then pubDate will be null
|
||||
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
|
||||
entry.setUpdatedDate(java.util.Date.from(item.getLastModified()));
|
||||
|
@@ -13,12 +13,12 @@ import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.app.util.dao.WebAppDAO;
|
||||
import org.dspace.app.util.service.WebAppService;
|
||||
import org.dspace.core.Context;
|
||||
@@ -77,8 +77,8 @@ public class WebAppServiceImpl implements WebAppService {
|
||||
for (WebApp app : webApps) {
|
||||
method = new HttpHead(app.getUrl());
|
||||
int status;
|
||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
||||
HttpResponse response = client.execute(method);
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
CloseableHttpResponse response = client.execute(method);
|
||||
status = response.getStatusLine().getStatusCode();
|
||||
}
|
||||
if (status != HttpStatus.SC_OK) {
|
||||
|
@@ -112,4 +112,10 @@ public interface OpenSearchService {
|
||||
|
||||
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.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
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.RequestBuilder;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.authenticate.oidc.OidcClient;
|
||||
import org.dspace.authenticate.oidc.OidcClientException;
|
||||
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) {
|
||||
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
return executeAndReturns(() -> {
|
||||
|
||||
HttpResponse response = client.execute(httpUriRequest);
|
||||
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OidcClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
|
||||
return objectMapper.readValue(getContent(response), clazz);
|
||||
|
||||
});
|
||||
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
return executeAndReturns(() -> {
|
||||
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OidcClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
return objectMapper.readValue(getContent(response), clazz);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
||||
|
@@ -7,27 +7,22 @@
|
||||
*/
|
||||
package org.dspace.authority.orcid;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
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.Logger;
|
||||
import org.dspace.authority.AuthorityValue;
|
||||
import org.dspace.authority.SolrAuthorityInterface;
|
||||
import org.dspace.external.OrcidRestConnector;
|
||||
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.record.Person;
|
||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||
@@ -50,6 +45,11 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* Maximum retries to allow for the access token retrieval
|
||||
*/
|
||||
private int maxClientRetries = 3;
|
||||
|
||||
public void setOAUTHUrl(String oAUTHUrl) {
|
||||
OAUTHUrl = oAUTHUrl;
|
||||
}
|
||||
@@ -62,46 +62,32 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
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
|
||||
*/
|
||||
public void init() {
|
||||
if (StringUtils.isBlank(accessToken)
|
||||
&& StringUtils.isNotBlank(clientSecret)
|
||||
&& StringUtils.isNotBlank(clientId)
|
||||
&& 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");
|
||||
// Initialize access token at spring instantiation. If it fails, the access token will be null rather
|
||||
// than causing a fatal Spring startup error
|
||||
initializeAccessToken();
|
||||
}
|
||||
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
||||
|
||||
JSONObject responseObject = null;
|
||||
try (InputStream is = getResponse.getEntity().getContent();
|
||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
||||
String inputStr;
|
||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")) {
|
||||
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);
|
||||
}
|
||||
public void initializeAccessToken() {
|
||||
// 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)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
accessToken = OrcidFactoryUtils.retrieveAccessToken(clientId, clientSecret, OAUTHUrl).orElse(null);
|
||||
} catch (IOException e) {
|
||||
log.error("Error retrieving ORCID access token, {} retries left", --maxClientRetries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +102,7 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
*/
|
||||
@Override
|
||||
public List<AuthorityValue> queryAuthorities(String text, int max) {
|
||||
init();
|
||||
initializeAccessToken();
|
||||
List<Person> bios = queryBio(text, max);
|
||||
List<AuthorityValue> result = new ArrayList<>();
|
||||
for (Person person : bios) {
|
||||
@@ -135,7 +121,7 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
*/
|
||||
@Override
|
||||
public AuthorityValue queryAuthorityID(String id) {
|
||||
init();
|
||||
initializeAccessToken();
|
||||
Person person = getBio(id);
|
||||
AuthorityValue valueFromPerson = Orcidv3AuthorityValue.create(person);
|
||||
return valueFromPerson;
|
||||
@@ -151,11 +137,14 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
if (!isValid(id)) {
|
||||
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);
|
||||
XMLtoBio converter = new XMLtoBio();
|
||||
Person person = converter.convertSinglePerson(bioDocument);
|
||||
return person;
|
||||
return converter.convertSinglePerson(bioDocument);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,10 +156,16 @@ public class Orcidv3SolrAuthorityImpl implements SolrAuthorityInterface {
|
||||
* @return List<Person>
|
||||
*/
|
||||
public List<Person> queryBio(String text, int start, int rows) {
|
||||
init();
|
||||
if (rows > 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;
|
||||
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
||||
|
@@ -21,7 +21,7 @@ import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
import jakarta.persistence.Table;
|
||||
import org.apache.solr.common.StringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.HibernateProxyHelper;
|
||||
|
@@ -19,6 +19,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.dao.ResourcePolicyDAO;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
@@ -51,6 +52,9 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
||||
@Autowired
|
||||
private GroupService groupService;
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
|
||||
protected ResourcePolicyServiceImpl() {
|
||||
}
|
||||
|
||||
@@ -422,6 +426,6 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
||||
} else if (group != null && groupService.isMember(context, eperson, group)) {
|
||||
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.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverFacetField;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
@@ -34,7 +33,6 @@ import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.SearchUtils;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||
import org.dspace.discovery.indexobject.IndexableItem;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
@@ -181,32 +179,28 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
addLocationScopeFilter(query);
|
||||
addDefaultFilterQueries(query);
|
||||
if (distinct) {
|
||||
DiscoverFacetField dff;
|
||||
|
||||
// To get the number of distinct values we use the next "json.facet" query param
|
||||
// {"entries_count": {"type":"terms","field": "<fieldName>_filter", "limit":0, "numBuckets":true}}"
|
||||
// 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
|
||||
// Example of json.facet query:
|
||||
// {"<fieldName>": {"type":"terms","field": "<fieldName>_filter", "limit":0, "offset":0,
|
||||
// "sort":"index desc", "numBuckets":true, "prefix":"<startsWith>"}}
|
||||
ObjectNode jsonFacet = JsonNodeFactory.instance.objectNode();
|
||||
ObjectNode entriesCount = JsonNodeFactory.instance.objectNode();
|
||||
entriesCount.put("type", "terms");
|
||||
entriesCount.put("field", facetField + "_filter");
|
||||
entriesCount.put("limit", 0);
|
||||
entriesCount.put("numBuckets", true);
|
||||
jsonFacet.set("entries_count", entriesCount);
|
||||
|
||||
if (StringUtils.isNotBlank(startsWith)) {
|
||||
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);
|
||||
ObjectNode entriesFacet = JsonNodeFactory.instance.objectNode();
|
||||
entriesFacet.put("type", "terms");
|
||||
entriesFacet.put("field", facetField + "_filter");
|
||||
entriesFacet.put("limit", limit);
|
||||
entriesFacet.put("offset", offset);
|
||||
entriesFacet.put("numBuckets", true);
|
||||
if (ascending) {
|
||||
entriesFacet.put("sort", "index");
|
||||
} else {
|
||||
dff = new DiscoverFacetField(facetField,
|
||||
DiscoveryConfigurationParameters.TYPE_TEXT, limit,
|
||||
DiscoveryConfigurationParameters.SORT.VALUE, offset);
|
||||
entriesFacet.put("sort", "index desc");
|
||||
}
|
||||
query.addFacetField(dff);
|
||||
query.setFacetMinCount(1);
|
||||
if (StringUtils.isNotBlank(startsWith)) {
|
||||
// Add the prefix to the json facet query
|
||||
entriesFacet.put("prefix", startsWith);
|
||||
}
|
||||
jsonFacet.set(facetField, entriesFacet);
|
||||
query.setMaxResults(0);
|
||||
query.addProperty("json.facet", jsonFacet.toString());
|
||||
} else {
|
||||
@@ -282,26 +276,15 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
List<FacetResult> facet = resp.getFacetResult(facetField);
|
||||
int count = doCountQuery();
|
||||
int start = 0;
|
||||
int max = facet.size();
|
||||
List<String[]> result = new ArrayList<>();
|
||||
if (ascending) {
|
||||
for (int i = start; i < (start + max) && i < count; i++) {
|
||||
FacetResult c = facet.get(i);
|
||||
String freq = showFrequencies ? String.valueOf(c.getCount())
|
||||
: "";
|
||||
result.add(new String[] {c.getDisplayedValue(),
|
||||
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});
|
||||
}
|
||||
|
||||
for (int i = 0; i < max && i < count; i++) {
|
||||
FacetResult c = facet.get(i);
|
||||
String freq = showFrequencies ? String.valueOf(c.getCount())
|
||||
: "";
|
||||
result.add(new String[] {c.getDisplayedValue(),
|
||||
c.getAuthorityKey(), freq});
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -362,9 +345,9 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
}
|
||||
|
||||
if (isAscending) {
|
||||
query.setQuery("bi_" + column + "_sort" + ": [* TO \"" + value + "\"}");
|
||||
query.setQuery("bi_" + column + "_sort" + ":[* TO \"" + value + "\"}");
|
||||
} else {
|
||||
query.setQuery("bi_" + column + "_sort" + ": {\"" + value + "\" TO *]");
|
||||
query.setQuery("bi_" + column + "_sort" + ":{\"" + value + "\" TO *]");
|
||||
query.addFilterQueries("-(bi_" + column + "_sort" + ":" + value + "*)");
|
||||
}
|
||||
DiscoverResult resp = null;
|
||||
|
@@ -1021,7 +1021,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
if (StringUtils.isNotBlank(q)) {
|
||||
StringBuilder buildQuery = new StringBuilder();
|
||||
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());
|
||||
}
|
||||
DiscoverResult resp = searchService.search(context, discoverQuery);
|
||||
|
@@ -187,11 +187,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
String authority) {
|
||||
List<MetadataValue> metadata = getMetadata(dso, schema, element, qualifier, lang);
|
||||
List<MetadataValue> result = new ArrayList<>(metadata);
|
||||
if (!authority.equals(Item.ANY)) {
|
||||
if (!Item.ANY.equals(authority)) {
|
||||
Iterator<MetadataValue> iterator = result.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MetadataValue metadataValue = iterator.next();
|
||||
if (!authority.equals(metadataValue.getAuthority())) {
|
||||
if (!StringUtils.equals(authority, metadataValue.getAuthority())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -509,7 +509,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
MetadataField metadataField = metadataValue.getMetadataField();
|
||||
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
|
||||
// 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
|
||||
return false;
|
||||
}
|
||||
@@ -520,9 +520,9 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
// Value is qualified, so no match
|
||||
return false;
|
||||
}
|
||||
} else if (!qualifier.equals(Item.ANY)) {
|
||||
} else if (!Item.ANY.equals(qualifier)) {
|
||||
// Not a wildcard, so qualifier must match exactly
|
||||
if (!qualifier.equals(metadataField.getQualifier())) {
|
||||
if (!StringUtils.equals(qualifier, metadataField.getQualifier())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -533,15 +533,15 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
// Value is qualified, so no match
|
||||
return false;
|
||||
}
|
||||
} else if (!language.equals(Item.ANY)) {
|
||||
} else if (!Item.ANY.equals(language)) {
|
||||
// Not a wildcard, so language must match exactly
|
||||
if (!language.equals(metadataValue.getLanguage())) {
|
||||
if (!StringUtils.equals(language, metadataValue.getLanguage())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!schema.equals(Item.ANY)) {
|
||||
if (metadataSchema != null && !metadataSchema.getName().equals(schema)) {
|
||||
if (!Item.ANY.equals(schema)) {
|
||||
if (!StringUtils.equals(schema, metadataSchema.getName())) {
|
||||
// The namespace doesn't match
|
||||
return false;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
@@ -36,6 +37,11 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
||||
@Autowired
|
||||
private DSpaceObjectUtils dSpaceObjectUtils;
|
||||
|
||||
@Autowired
|
||||
private ConfigurationService configurationService;
|
||||
|
||||
private int csxExportLimit = -1;
|
||||
|
||||
@Override
|
||||
public DSpaceCSV handleExport(Context context, boolean exportAllItems, boolean exportAllMetadata, String identifier,
|
||||
DSpaceRunnableHandler handler) throws Exception {
|
||||
@@ -43,7 +49,7 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
||||
|
||||
if (exportAllItems) {
|
||||
handler.logInfo("Exporting whole repository WARNING: May take some time!");
|
||||
toExport = itemService.findAll(context);
|
||||
toExport = itemService.findAll(context, getCsvExportLimit(), 0);
|
||||
} else {
|
||||
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService()
|
||||
.resolveToObject(context, identifier);
|
||||
@@ -63,7 +69,7 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
||||
} else if (dso.getType() == Constants.COLLECTION) {
|
||||
handler.logInfo("Exporting collection '" + dso.getName() + "' (" + identifier + ")");
|
||||
Collection collection = (Collection) dso;
|
||||
toExport = itemService.findByCollection(context, collection);
|
||||
toExport = itemService.findByCollection(context, collection, getCsvExportLimit(), 0);
|
||||
} else if (dso.getType() == Constants.COMMUNITY) {
|
||||
handler.logInfo("Exporting community '" + dso.getName() + "' (" + identifier + ")");
|
||||
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;
|
||||
}
|
||||
|
||||
@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.setMode(Context.Mode.READ_ONLY);
|
||||
|
||||
// Process each item
|
||||
// Process each item until we reach the limit
|
||||
int itemExportLimit = getCsvExportLimit();
|
||||
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
||||
while (toExport.hasNext()) {
|
||||
|
||||
for (int itemsAdded = 0; toExport.hasNext() && itemsAdded < itemExportLimit; itemsAdded++) {
|
||||
Item item = toExport.next();
|
||||
csv.addItem(item);
|
||||
context.uncacheEntity(item);
|
||||
@@ -97,8 +106,9 @@ public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExpo
|
||||
}
|
||||
|
||||
@Override
|
||||
public DSpaceCSV export(Context context, Community community, boolean exportAll) throws Exception {
|
||||
return export(context, buildFromCommunity(context, community), exportAll);
|
||||
public DSpaceCSV export(Context context, Community community,
|
||||
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
|
||||
List<Collection> collections = community.getCollections();
|
||||
for (Collection collection : collections) {
|
||||
Iterator<Item> items = itemService.findByCollection(context, collection);
|
||||
while (items.hasNext()) {
|
||||
// Never obtain more items than the configured limit
|
||||
Iterator<Item> items = itemService.findByCollection(context, collection, getCsvExportLimit(), 0);
|
||||
while (result.size() < getCsvExportLimit() && items.hasNext()) {
|
||||
result.add(items.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Add all the sub-communities
|
||||
// Add all the sub-communities
|
||||
List<Community> communities = community.getSubcommunities();
|
||||
for (Community subCommunity : communities) {
|
||||
Iterator<Item> items = buildFromCommunity(context, subCommunity);
|
||||
while (items.hasNext()) {
|
||||
while (result.size() < getCsvExportLimit() && items.hasNext()) {
|
||||
result.add(items.next());
|
||||
}
|
||||
}
|
||||
|
||||
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<>();
|
||||
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()) {
|
||||
metadataFields.addAll(formToField.getValue().stream().map(value ->
|
||||
StringUtils.replace(value, "_", "."))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
DiscoverySearchFilterFacet matchingFacet = null;
|
||||
for (DiscoverySearchFilterFacet facetConfig : searchConfigurationService.getAllFacetsConfig()) {
|
||||
for (DiscoverySearchFilterFacet facetConfig : searchConfigurationService.getAllUniqueFacetsConfig()) {
|
||||
boolean coversAllFieldsFromVocab = true;
|
||||
for (String fieldFromVocab: metadataFields) {
|
||||
boolean coversFieldFromVocab = false;
|
||||
|
@@ -11,8 +11,6 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -21,7 +19,11 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
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.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.BitstreamFormat;
|
||||
@@ -1310,13 +1312,12 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester {
|
||||
if (params.getBooleanProperty("manifestOnly", false)) {
|
||||
// NOTE: since we are only dealing with a METS manifest,
|
||||
// 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
|
||||
URL fileURL = new URL(path);
|
||||
URLConnection connection = fileURL.openConnection();
|
||||
|
||||
// open stream to access file contents
|
||||
return connection.getInputStream();
|
||||
try (CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(path))) {
|
||||
// open stream to access file contents
|
||||
return httpResponse.getEntity().getContent();
|
||||
}
|
||||
} catch (IOException io) {
|
||||
log
|
||||
.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.
|
||||
* @param dSpaceObject the object whose metadata are sought.
|
||||
* @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.
|
||||
*/
|
||||
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),
|
||||
* null if explicitly no language,
|
||||
* 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.
|
||||
*/
|
||||
public List<MetadataValue> getMetadata(T dSpaceObject, String schema,
|
||||
|
@@ -44,7 +44,8 @@ public interface MetadataDSpaceCsvExportService {
|
||||
* @return A DSpaceCSV object containing the exported information
|
||||
* @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
|
||||
@@ -54,6 +55,9 @@ public interface MetadataDSpaceCsvExportService {
|
||||
* @return A DSpaceCSV object containing the exported information
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
* Typical use:
|
||||
@@ -168,6 +168,9 @@ public class Email {
|
||||
*/
|
||||
private String charset;
|
||||
|
||||
/** The message being assembled. */
|
||||
MimeMessage message;
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
/** Velocity template settings. */
|
||||
@@ -188,6 +191,9 @@ public class Email {
|
||||
/** Velocity template for a message body */
|
||||
private Template template;
|
||||
|
||||
/** The message text. */
|
||||
private String body;
|
||||
|
||||
/**
|
||||
* Create a new email message.
|
||||
*/
|
||||
@@ -254,9 +260,15 @@ public class Email {
|
||||
/**
|
||||
* 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) {
|
||||
if (null == arg) {
|
||||
arg = "";
|
||||
LOG.warn("Null argument {} to email template {} replaced with zero-length string",
|
||||
arguments.size(), contentName);
|
||||
}
|
||||
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
|
||||
* {@code mail.message.headers} then that name and its value will be added
|
||||
* 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
|
||||
* had been called with that value. Thus a template may define its subject,
|
||||
* but the caller may override it.
|
||||
*
|
||||
* @throws MessagingException if there was a problem sending the mail.
|
||||
* @throws IOException if IO error
|
||||
*
|
||||
* @throws MessagingException if there is no template, or passed through.
|
||||
* @throws IOException passed through.
|
||||
*/
|
||||
public void send() throws MessagingException, IOException {
|
||||
void build()
|
||||
throws MessagingException, IOException {
|
||||
if (null == template) {
|
||||
// No template -- no content -- PANIC!!!
|
||||
throw new MessagingException("Email has no body");
|
||||
@@ -351,7 +384,6 @@ public class Email {
|
||||
|
||||
// Get the mail configuration properties
|
||||
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 (charset == null) {
|
||||
@@ -362,7 +394,7 @@ public class Email {
|
||||
Session session = DSpaceServicesFactory.getInstance().getEmailService().getSession();
|
||||
|
||||
// Create message
|
||||
MimeMessage message = new MimeMessage(session);
|
||||
message = new MimeMessage(session);
|
||||
|
||||
// Set the recipients of the message
|
||||
for (String recipient : recipients) {
|
||||
@@ -385,7 +417,7 @@ public class Email {
|
||||
LOG.error("Template not merged: {}", ex.getMessage());
|
||||
throw new MessagingException("Template not merged", ex);
|
||||
}
|
||||
String fullMessage = writer.toString();
|
||||
body = writer.toString();
|
||||
|
||||
// Set some message header fields
|
||||
Instant date = Instant.now();
|
||||
@@ -412,20 +444,19 @@ public class Email {
|
||||
message.setSubject(subject);
|
||||
}
|
||||
|
||||
// Add attachments
|
||||
if (attachments.isEmpty() && moreAttachments.isEmpty()) {
|
||||
// If a character set has been specified, or a default exists
|
||||
// Attach the body.
|
||||
if (attachments.isEmpty() && moreAttachments.isEmpty()) { // Flat body.
|
||||
if (charset != null) {
|
||||
message.setText(fullMessage, charset);
|
||||
message.setText(body, charset);
|
||||
} else {
|
||||
message.setText(fullMessage);
|
||||
message.setText(body);
|
||||
}
|
||||
} else {
|
||||
} else { // Add attachments.
|
||||
Multipart multipart = new MimeMultipart();
|
||||
|
||||
// create the first part of the email
|
||||
BodyPart messageBodyPart = new MimeBodyPart();
|
||||
messageBodyPart.setText(fullMessage);
|
||||
messageBodyPart.setText(body);
|
||||
multipart.addBodyPart(messageBodyPart);
|
||||
|
||||
// Add file attachments
|
||||
@@ -457,30 +488,47 @@ public class Email {
|
||||
replyToAddr[0] = new InternetAddress(replyTo);
|
||||
message.setReplyTo(replyToAddr);
|
||||
}
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
StringBuilder text = new StringBuilder(
|
||||
"Message not sent due to mail.server.disabled:\n");
|
||||
/**
|
||||
* Flatten the email into a string.
|
||||
*
|
||||
* @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();
|
||||
while (headers.hasMoreElements()) {
|
||||
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);
|
||||
Enumeration<String> headers = message.getAllHeaderLines();
|
||||
while (headers.hasMoreElements()) {
|
||||
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(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)
|
||||
.toInstant(ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,11 +9,15 @@ package org.dspace.ctask.general;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
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.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
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)
|
||||
*/
|
||||
protected int getResponseStatus(String url, int redirects) {
|
||||
try {
|
||||
URL theURL = new URL(url);
|
||||
HttpURLConnection connection = (HttpURLConnection) theURL.openConnection();
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
int statusCode = connection.getResponseCode();
|
||||
RequestConfig config = RequestConfig.custom().setRedirectsEnabled(true).build();
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config)) {
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(url));
|
||||
int statusCode = httpResponse.getStatusLine().getStatusCode();
|
||||
int maxRedirect = configurationService.getIntProperty("curate.checklinks.max-redirect", 0);
|
||||
if ((statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM ||
|
||||
statusCode == HttpURLConnection.HTTP_SEE_OTHER)) {
|
||||
connection.disconnect();
|
||||
String newUrl = connection.getHeaderField("Location");
|
||||
String newUrl = httpResponse.getFirstHeader("Location").getValue();
|
||||
if (newUrl != null && (maxRedirect >= redirects || maxRedirect == -1)) {
|
||||
redirects++;
|
||||
return getResponseStatus(newUrl, redirects);
|
||||
}
|
||||
|
||||
}
|
||||
return statusCode;
|
||||
|
||||
} catch (IOException ioe) {
|
||||
// Must be a bad URL
|
||||
log.debug("Bad link: " + ioe.getMessage());
|
||||
|
@@ -30,13 +30,13 @@ import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
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 {
|
||||
|
||||
String callUrl = urlTemplate.replaceAll("\\{" + templateParam + "\\}", value);
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet req = new HttpGet(callUrl);
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
req.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
HttpResponse resp = client.execute(req);
|
||||
int status = Curator.CURATE_ERROR;
|
||||
int statusCode = resp.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_OK) {
|
||||
HttpEntity entity = resp.getEntity();
|
||||
if (entity != null) {
|
||||
// boiler-plate handling taken from Apache 4.1 javadoc
|
||||
InputStream instream = entity.getContent();
|
||||
try {
|
||||
// This next line triggers a false-positive XXE warning from LGTM, even though we disallow DTD
|
||||
// parsing during initialization of docBuilder in init()
|
||||
Document doc = docBuilder.parse(instream); // lgtm [java/xxe]
|
||||
status = processResponse(doc, item, resultSb);
|
||||
} catch (SAXException saxE) {
|
||||
log.error("caught exception: " + saxE);
|
||||
resultSb.append(" unable to read response document");
|
||||
} catch (RuntimeException ex) {
|
||||
// In case of an unexpected exception you may want to abort
|
||||
// the HTTP request in order to shut down the underlying
|
||||
// connection and release it back to the connection manager.
|
||||
req.abort();
|
||||
log.error("caught exception: " + ex);
|
||||
throw ex;
|
||||
} finally {
|
||||
// Closing the input stream will trigger connection release
|
||||
instream.close();
|
||||
}
|
||||
// When HttpClient instance is no longer needed,
|
||||
// shut down the connection manager to ensure
|
||||
// immediate deallocation of all system resources
|
||||
client.close();
|
||||
} else {
|
||||
log.error(" obtained no valid service response");
|
||||
resultSb.append("no service response");
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
HttpGet req = new HttpGet(callUrl);
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
req.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
try (CloseableHttpResponse resp = client.execute(req)) {
|
||||
int status = Curator.CURATE_ERROR;
|
||||
int statusCode = resp.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_OK) {
|
||||
HttpEntity entity = resp.getEntity();
|
||||
if (entity != null) {
|
||||
// boiler-plate handling taken from Apache 4.1 javadoc
|
||||
InputStream instream = entity.getContent();
|
||||
try {
|
||||
// This next line triggers a false-positive XXE warning from LGTM, even though
|
||||
// we disallow DTD parsing during initialization of docBuilder in init()
|
||||
Document doc = docBuilder.parse(instream); // lgtm [java/xxe]
|
||||
status = processResponse(doc, item, resultSb);
|
||||
} catch (SAXException saxE) {
|
||||
log.error("caught exception: " + saxE);
|
||||
resultSb.append(" unable to read response document");
|
||||
} catch (RuntimeException ex) {
|
||||
// In case of an unexpected exception you may want to abort
|
||||
// the HTTP request in order to shut down the underlying
|
||||
// connection and release it back to the connection manager.
|
||||
req.abort();
|
||||
log.error("caught exception: " + ex);
|
||||
throw ex;
|
||||
} finally {
|
||||
// Closing the input stream will trigger connection release
|
||||
instream.close();
|
||||
}
|
||||
} else {
|
||||
log.error(" obtained no valid service response");
|
||||
resultSb.append("no service response");
|
||||
}
|
||||
} else {
|
||||
log.error("service returned non-OK status: " + statusCode);
|
||||
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 {
|
||||
|
@@ -12,12 +12,12 @@ import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
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.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
@@ -60,22 +60,20 @@ public class MicrosoftTranslator extends AbstractTranslator {
|
||||
String url = baseUrl + "?appId=" + apiKey;
|
||||
url += "&to=" + to + "&from=" + from + "&text=" + text;
|
||||
|
||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
HttpGet hm = new HttpGet(url);
|
||||
HttpResponse httpResponse = client.execute(hm);
|
||||
log.debug("Response code from API call is " + httpResponse);
|
||||
|
||||
if (httpResponse.getStatusLine().getStatusCode() == 200) {
|
||||
String response = IOUtils.toString(httpResponse.getEntity().getContent(),
|
||||
StandardCharsets.ISO_8859_1);
|
||||
response = response
|
||||
.replaceAll("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", "");
|
||||
response = response.replaceAll("</string>", "");
|
||||
translatedText = response;
|
||||
try (CloseableHttpResponse httpResponse = client.execute(hm)) {
|
||||
log.debug("Response code from API call is " + httpResponse);
|
||||
if (httpResponse.getStatusLine().getStatusCode() == 200) {
|
||||
String response = IOUtils.toString(httpResponse.getEntity().getContent(),
|
||||
StandardCharsets.ISO_8859_1);
|
||||
response = response
|
||||
.replaceAll("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", "");
|
||||
response = response.replaceAll("</string>", "");
|
||||
translatedText = response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return translatedText;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -25,6 +25,8 @@ import java.util.UUID;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
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.content.DSpaceObject;
|
||||
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.service.HandleService;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
@@ -46,7 +49,9 @@ import org.dspace.utils.DSpace;
|
||||
public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
||||
|
||||
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;
|
||||
private CurationClientOptions curationClientOptions;
|
||||
|
||||
@@ -346,9 +351,29 @@ public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
||||
|
||||
if (this.commandLine.hasOption('i')) {
|
||||
this.id = this.commandLine.getOptionValue('i').toLowerCase();
|
||||
DSpaceObject dso;
|
||||
if (!this.id.equalsIgnoreCase("all")) {
|
||||
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||
DSpaceObject dso;
|
||||
// First, try to parse the id as a UUID. If that fails, treat it as a handle.
|
||||
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 {
|
||||
dso = handleService.resolveToObject(this.context, id);
|
||||
} 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.QueryResponse;
|
||||
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.util.ClientUtils;
|
||||
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.factory.IndexFactory;
|
||||
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
|
||||
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
@@ -339,6 +341,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
try {
|
||||
final List<IndexFactory> indexableObjectServices = indexObjectServiceFactory.
|
||||
getIndexFactories();
|
||||
int indexObject = 0;
|
||||
for (IndexFactory indexableObjectService : indexableObjectServices) {
|
||||
if (type == null || StringUtils.equals(indexableObjectService.getType(), type)) {
|
||||
final Iterator<IndexableObject> indexableObjects = indexableObjectService.findAll(context);
|
||||
@@ -346,6 +349,10 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
final IndexableObject indexableObject = indexableObjects.next();
|
||||
indexContent(context, indexableObject, force);
|
||||
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
|
||||
resolveFacetFields(context, query, result, skipLoadingResponse, solrQueryResponse);
|
||||
//Add total entries count for metadata browsing
|
||||
resolveEntriesCount(result, solrQueryResponse);
|
||||
//Resolve our json facet field values used for metadata browsing
|
||||
resolveJsonFacetFields(context, result, solrQueryResponse);
|
||||
}
|
||||
// If any stale entries are found in the current page of results,
|
||||
// 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
|
||||
* <code>json.facet</code> parameter with the following value:
|
||||
* Process the 'json.facet' response, which is currently only used for metadata browsing
|
||||
*
|
||||
* <pre><code>
|
||||
* {
|
||||
* "entries_count": {
|
||||
* "type": "terms",
|
||||
* "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
|
||||
* @param context context object
|
||||
* @param result the result object to add the facet results to
|
||||
* @param solrQueryResponse the solr query response
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
private void resolveEntriesCount(DiscoverResult result, QueryResponse solrQueryResponse) {
|
||||
private void resolveJsonFacetFields(Context context, DiscoverResult result, QueryResponse solrQueryResponse)
|
||||
throws SQLException {
|
||||
|
||||
NestableJsonFacet response = solrQueryResponse.getJsonFacetingResponse();
|
||||
if (response != null) {
|
||||
BucketBasedJsonFacet facet = response.getBucketBasedFacets("entries_count");
|
||||
if (facet != null) {
|
||||
result.setTotalEntries(facet.getNumBucketsCount());
|
||||
if (response != null && response.getBucketBasedFacetNames() != null) {
|
||||
for (String facetName : response.getBucketBasedFacetNames()) {
|
||||
BucketBasedJsonFacet facet = response.getBucketBasedFacets(facetName);
|
||||
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 {
|
||||
SolrQuery solrQuery = new SolrQuery();
|
||||
//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
|
||||
solrQuery.setFields(SearchUtils.RESOURCE_TYPE_FIELD, SearchUtils.RESOURCE_ID_FIELD);
|
||||
//Add the more like this parameters !
|
||||
|
@@ -10,8 +10,10 @@ package org.dspace.discovery.configuration;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
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() {
|
||||
List<DiscoverySearchFilterFacet> configs = new ArrayList<>();
|
||||
public List<DiscoverySearchFilterFacet> getAllUniqueFacetsConfig() {
|
||||
Set<DiscoverySearchFilterFacet> configs = new LinkedHashSet<>();
|
||||
for (String key : map.keySet()) {
|
||||
DiscoveryConfiguration config = map.get(key);
|
||||
configs.addAll(config.getSidebarFacets());
|
||||
}
|
||||
return configs;
|
||||
return new ArrayList<>(configs);
|
||||
}
|
||||
|
||||
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,
|
||||
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
|
||||
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
|
||||
.getProperty("discovery.solr.facets.split.char");
|
||||
|
@@ -17,15 +17,15 @@ import java.util.regex.Pattern;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
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.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.eperson.service.CaptchaService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -82,18 +82,17 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpResponse httpResponse;
|
||||
GoogleCaptchaResponse googleResponse;
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
httpResponse = httpClient.execute(httpPost);
|
||||
googleResponse = objectMapper.readValue(httpResponse.getEntity().getContent(), GoogleCaptchaResponse.class);
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
|
||||
GoogleCaptchaResponse googleResponse = objectMapper.readValue(httpResponse.getEntity().getContent(),
|
||||
GoogleCaptchaResponse.class);
|
||||
validateGoogleResponse(googleResponse, action);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException("Error during verify google recaptcha site", e);
|
||||
}
|
||||
validateGoogleResponse(googleResponse, action);
|
||||
}
|
||||
|
||||
private boolean responseSanityCheck(String response) {
|
||||
|
@@ -131,7 +131,8 @@ public class SubscribeServiceImpl implements SubscribeService {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -10,12 +10,45 @@ package org.dspace.eperson.factory;
|
||||
import org.dspace.eperson.service.CaptchaService;
|
||||
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 CaptchaService getCaptchaService();
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
* @return singleton instance of this class
|
||||
*/
|
||||
public static CaptchaServiceFactory getInstance() {
|
||||
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.Qualifier;
|
||||
|
||||
/**
|
||||
* Factory to get services for Captcha protection of DSpace forms / endpoints
|
||||
*
|
||||
* @author Kim Shepherd
|
||||
*/
|
||||
public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
||||
|
||||
@Autowired
|
||||
@@ -25,9 +30,16 @@ public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
||||
@Autowired
|
||||
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
|
||||
public CaptchaService getCaptchaService() {
|
||||
String provider = configurationService.getProperty("captcha.provider");
|
||||
String provider = configurationService.getProperty("captcha.provider", "google");
|
||||
|
||||
if ("altcha".equalsIgnoreCase(provider)) {
|
||||
return altchaCaptchaService;
|
||||
@@ -35,4 +47,26 @@ public class CaptchaServiceFactoryImpl extends CaptchaServiceFactory {
|
||||
|
||||
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.NoHttpResponseException;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
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.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.app.util.Util;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -120,33 +120,34 @@ public class OpenaireRestConnector {
|
||||
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
|
||||
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
||||
|
||||
JSONObject responseObject = null;
|
||||
try (InputStream is = getResponse.getEntity().getContent();
|
||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
||||
String inputStr;
|
||||
// verify if we have basic json
|
||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")
|
||||
&& inputStr.contains("expires_in")) {
|
||||
try {
|
||||
responseObject = new JSONObject(inputStr);
|
||||
} catch (Exception e) {
|
||||
// Not as valid as I'd hoped, move along
|
||||
responseObject = null;
|
||||
JSONObject responseObject = null;
|
||||
try (InputStream is = getResponse.getEntity().getContent();
|
||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
||||
String inputStr;
|
||||
// verify if we have basic json
|
||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")
|
||||
&& inputStr.contains("expires_in")) {
|
||||
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") || !responseObject.has("expires_in")) {
|
||||
throw new IOException("Unable to grab the access token using provided service url, client id and secret");
|
||||
}
|
||||
|
||||
return new OpenaireRestToken(responseObject.get("access_token").toString(),
|
||||
Long.valueOf(responseObject.get("expires_in").toString()));
|
||||
if (responseObject == null || !responseObject.has("access_token") || !responseObject.has("expires_in")) {
|
||||
throw new IOException("Unable to grab the access token using provided service url, " +
|
||||
"client id and secret");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
getResponse = httpClient.execute(httpGet);
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
getResponse = httpClient.execute(httpGet);
|
||||
|
||||
StatusLine status = getResponse.getStatusLine();
|
||||
StatusLine status = getResponse.getStatusLine();
|
||||
|
||||
// registering errors
|
||||
switch (status.getStatusCode()) {
|
||||
case HttpStatus.SC_NOT_FOUND:
|
||||
// 404 - Not found
|
||||
case HttpStatus.SC_FORBIDDEN:
|
||||
// 403 - Invalid Access Token
|
||||
case 429:
|
||||
// 429 - Rate limit abuse for unauthenticated user
|
||||
Header[] limitUsed = getResponse.getHeaders("x-ratelimit-used");
|
||||
Header[] limitMax = getResponse.getHeaders("x-ratelimit-limit");
|
||||
// registering errors
|
||||
switch (status.getStatusCode()) {
|
||||
case HttpStatus.SC_NOT_FOUND:
|
||||
// 404 - Not found
|
||||
case HttpStatus.SC_FORBIDDEN:
|
||||
// 403 - Invalid Access Token
|
||||
case 429:
|
||||
// 429 - Rate limit abuse for unauthenticated user
|
||||
Header[] limitUsed = getResponse.getHeaders("x-ratelimit-used");
|
||||
Header[] limitMax = getResponse.getHeaders("x-ratelimit-limit");
|
||||
|
||||
if (limitUsed.length > 0) {
|
||||
String limitMsg = limitUsed[0].getValue();
|
||||
if (limitMax.length > 0) {
|
||||
limitMsg = limitMsg.concat(" of " + limitMax[0].getValue());
|
||||
if (limitUsed.length > 0) {
|
||||
String limitMsg = limitUsed[0].getValue();
|
||||
if (limitMax.length > 0) {
|
||||
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(
|
||||
new NoHttpResponseException(status.getReasonPhrase() + " with usage limit " + limitMsg),
|
||||
url + '/' + file);
|
||||
} else {
|
||||
// 429 - Rate limit abuse
|
||||
getGotError(new NoHttpResponseException(status.getReasonPhrase()), url + '/' + file);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// 200 or other
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// 200 or other
|
||||
break;
|
||||
}
|
||||
|
||||
// do not close this httpClient
|
||||
result = getResponse.getEntity().getContent();
|
||||
// do not close this httpClient
|
||||
result = getResponse.getEntity().getContent();
|
||||
}
|
||||
} catch (MalformedURLException e1) {
|
||||
getGotError(e1, url + '/' + file);
|
||||
} catch (Exception e) {
|
||||
|
@@ -7,17 +7,18 @@
|
||||
*/
|
||||
package org.dspace.external;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
|
||||
/**
|
||||
* @author Antoine Snyers (antoine at atmire.com)
|
||||
@@ -39,7 +40,7 @@ public class OrcidRestConnector {
|
||||
}
|
||||
|
||||
public InputStream get(String path, String accessToken) {
|
||||
HttpResponse getResponse = null;
|
||||
CloseableHttpResponse getResponse = null;
|
||||
InputStream result = null;
|
||||
path = trimSlashes(path);
|
||||
|
||||
@@ -49,11 +50,13 @@ public class OrcidRestConnector {
|
||||
httpGet.addHeader("Content-Type", "application/vnd.orcid+xml");
|
||||
httpGet.addHeader("Authorization","Bearer " + accessToken);
|
||||
}
|
||||
try {
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
getResponse = httpClient.execute(httpGet);
|
||||
//do not close this httpClient
|
||||
result = getResponse.getEntity().getContent();
|
||||
try (InputStream responseStream = 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) {
|
||||
getGotError(e, fullPath);
|
||||
}
|
||||
|
@@ -7,24 +7,17 @@
|
||||
*/
|
||||
package org.dspace.external.provider.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.Logger;
|
||||
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.provider.AbstractExternalDataProvider;
|
||||
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.record.Email;
|
||||
import org.orcid.jaxb.model.v3.release.record.Person;
|
||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -60,6 +54,11 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
|
||||
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})";
|
||||
private static final int MAX_INDEX = 10000;
|
||||
|
||||
@@ -78,47 +77,37 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
* @throws java.io.IOException passed through from HTTPclient.
|
||||
*/
|
||||
public void init() 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");
|
||||
// Initialize access token at spring instantiation. If it fails, the access token will be null rather
|
||||
// than causing a fatal Spring startup error
|
||||
initializeAccessToken();
|
||||
}
|
||||
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
||||
|
||||
JSONObject responseObject = null;
|
||||
try (InputStream is = getResponse.getEntity().getContent();
|
||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
|
||||
String inputStr;
|
||||
while ((inputStr = streamReader.readLine()) != null && responseObject == null) {
|
||||
if (inputStr.startsWith("{") && inputStr.endsWith("}") && inputStr.contains("access_token")) {
|
||||
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");
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void initializeAccessToken() {
|
||||
// If we have reaches max retries or the access token is already set, return immediately
|
||||
if (maxClientRetries <= 0 || StringUtils.isNotBlank(accessToken)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
accessToken = OrcidFactoryUtils.retrieveAccessToken(clientId, clientSecret, OAUTHUrl).orElse(null);
|
||||
} catch (IOException e) {
|
||||
log.error("Error retrieving ORCID access token, {} retries left", --maxClientRetries);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ExternalDataObject> getExternalDataObject(String id) {
|
||||
initializeAccessToken();
|
||||
Person person = getBio(id);
|
||||
ExternalDataObject externalDataObject = convertToExternalDataObject(person);
|
||||
return Optional.of(externalDataObject);
|
||||
}
|
||||
|
||||
protected ExternalDataObject convertToExternalDataObject(Person person) {
|
||||
initializeAccessToken();
|
||||
ExternalDataObject externalDataObject = new ExternalDataObject(sourceIdentifier);
|
||||
if (person.getName() != null) {
|
||||
String lastName = "";
|
||||
@@ -126,13 +115,20 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
if (person.getName().getFamilyName() != null) {
|
||||
lastName = person.getName().getFamilyName().getContent();
|
||||
externalDataObject.addMetadata(new MetadataValueDTO("person", "familyName", null, null,
|
||||
lastName));
|
||||
lastName));
|
||||
}
|
||||
if (person.getName().getGivenNames() != null) {
|
||||
firstName = person.getName().getGivenNames().getContent();
|
||||
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
|
||||
@@ -140,7 +136,7 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
new MetadataValueDTO("person", "identifier", "orcid", null, person.getName().getPath()));
|
||||
externalDataObject
|
||||
.addMetadata(new MetadataValueDTO("dc", "identifier", "uri", null,
|
||||
orcidUrl + "/" + person.getName().getPath()));
|
||||
orcidUrl + "/" + person.getName().getPath()));
|
||||
if (!StringUtils.isBlank(lastName) && !StringUtils.isBlank(firstName)) {
|
||||
externalDataObject.setDisplayValue(lastName + ", " + firstName);
|
||||
externalDataObject.setValue(lastName + ", " + firstName);
|
||||
@@ -151,8 +147,8 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
externalDataObject.setDisplayValue(firstName);
|
||||
externalDataObject.setValue(firstName);
|
||||
}
|
||||
} else if (person.getPath() != null ) {
|
||||
externalDataObject.setId(StringUtils.substringBetween(person.getPath(),"/","/person"));
|
||||
} else if (person.getPath() != null) {
|
||||
externalDataObject.setId(StringUtils.substringBetween(person.getPath(), "/", "/person"));
|
||||
}
|
||||
return externalDataObject;
|
||||
}
|
||||
@@ -167,14 +163,13 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
if (!isValid(id)) {
|
||||
return null;
|
||||
}
|
||||
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
||||
Person person = converter.convertSinglePerson(bioDocument);
|
||||
try {
|
||||
bioDocument.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
if (orcidRestConnector == null) {
|
||||
log.error("ORCID REST connector is null, returning null ORCID Person Bio");
|
||||
return null;
|
||||
}
|
||||
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
|
||||
public List<ExternalDataObject> searchExternalDataObjects(String query, int start, int limit) {
|
||||
initializeAccessToken();
|
||||
if (limit > 100) {
|
||||
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
||||
}
|
||||
if (start > MAX_INDEX) {
|
||||
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)
|
||||
+ "&start=" + start
|
||||
@@ -205,7 +206,7 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
for (Result result : results) {
|
||||
OrcidIdentifier orcidIdentifier = result.getOrcidIdentifier();
|
||||
if (orcidIdentifier != null) {
|
||||
log.debug("Found OrcidId=" + orcidIdentifier.toString());
|
||||
log.debug("Found OrcidId=" + orcidIdentifier.getPath());
|
||||
String orcid = orcidIdentifier.getPath();
|
||||
Person bio = getBio(orcid);
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -231,6 +224,11 @@ public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider {
|
||||
|
||||
@Override
|
||||
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)
|
||||
+ "&start=" + 0
|
||||
+ "&rows=" + 0;
|
||||
|
@@ -97,7 +97,7 @@ public class SHERPAv2JournalDataProvider extends AbstractExternalDataProvider {
|
||||
if (CollectionUtils.isNotEmpty(sherpaJournal.getIssns())) {
|
||||
String issn = sherpaJournal.getIssns().get(0);
|
||||
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);
|
||||
externalDataObject.setId(issn);
|
||||
externalDataObject.addMetadata(new MetadataValueDTO(
|
||||
"dc", "identifier", "issn", null, issn));
|
||||
|
||||
"creativeworkseries", "issn", null, null, issn));
|
||||
}
|
||||
|
||||
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" +
|
||||
"with id: " + item.getID() + " from source: " + externalDataObject.getSource() + " with identifier: " +
|
||||
externalDataObject.getId()));
|
||||
" with id: " + item.getID() +
|
||||
" from source: " + externalDataObject.getSource() +
|
||||
" with identifier: " + externalDataObject.getId()));
|
||||
try {
|
||||
List<SuggestionProvider> providers = suggestionService.getSuggestionProviders();
|
||||
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.entity.StringEntity;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.google.GoogleAnalyticsEvent;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class GoogleAnalyticsClientImpl implements GoogleAnalyticsClient {
|
||||
public GoogleAnalyticsClientImpl(String keyPrefix, GoogleAnalyticsClientRequestBuilder requestBuilder) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
this.requestBuilder = requestBuilder;
|
||||
this.httpclient = HttpClients.createDefault();
|
||||
this.httpclient = DSpaceHttpClientFactory.getInstance().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -15,11 +15,14 @@ import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
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.Context;
|
||||
import org.dspace.core.LogHelper;
|
||||
@@ -62,9 +65,6 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
||||
@Autowired(required = true)
|
||||
private HandleService handleService;
|
||||
|
||||
@Autowired(required = true)
|
||||
private ItemService itemService;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -489,27 +499,29 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
||||
* Remove all handles from an item's metadata and add the supplied handle instead.
|
||||
*
|
||||
* @param context The relevant DSpace Context.
|
||||
* @param item which item to modify
|
||||
* @param dso which dso to modify
|
||||
* @param handle which handle to add
|
||||
* @throws SQLException if database 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 {
|
||||
// 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
|
||||
// identifiers which are not from type handle and add the new handle.
|
||||
String handleref = handleService.getCanonicalForm(handle);
|
||||
List<MetadataValue> identifiers = itemService
|
||||
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||
itemService.clearMetadata(context, item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||
DSpaceObjectService<DSpaceObject> dSpaceObjectService =
|
||||
ContentServiceFactory.getInstance().getDSpaceObjectService(dso);
|
||||
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) {
|
||||
if (this.supports(identifier.getValue())) {
|
||||
// ignore handles
|
||||
continue;
|
||||
}
|
||||
itemService.addMetadata(context,
|
||||
item,
|
||||
dSpaceObjectService.addMetadata(context,
|
||||
dso,
|
||||
identifier.getMetadataField(),
|
||||
identifier.getLanguage(),
|
||||
identifier.getValue(),
|
||||
@@ -517,9 +529,9 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
||||
identifier.getConfidence());
|
||||
}
|
||||
if (!StringUtils.isEmpty(handleref)) {
|
||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||
dSpaceObjectService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||
"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.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
@@ -719,7 +719,7 @@ public class DataCiteConnector
|
||||
httpContext.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
HttpEntity entity = null;
|
||||
try ( CloseableHttpClient httpclient = HttpClientBuilder.create().build(); ) {
|
||||
try (CloseableHttpClient httpclient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
HttpResponse response = httpclient.execute(req, httpContext);
|
||||
|
||||
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.impl.client.BasicCredentialsProvider;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.identifier.DOI;
|
||||
import org.dspace.identifier.IdentifierException;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class EZIDRequest {
|
||||
this.authority = authority;
|
||||
}
|
||||
|
||||
client = HttpClientBuilder.create().build();
|
||||
client = DSpaceHttpClientFactory.getInstance().build();
|
||||
httpContext = HttpClientContext.create();
|
||||
if (null != username) {
|
||||
URI uri = new URI(scheme, host, path, null);
|
||||
@@ -124,7 +124,7 @@ public class EZIDRequest {
|
||||
this.authority = authority;
|
||||
}
|
||||
|
||||
client = HttpClientBuilder.create().build();
|
||||
client = DSpaceHttpClientFactory.getInstance().build();
|
||||
httpContext = HttpClientContext.create();
|
||||
if (null != username) {
|
||||
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
|
@@ -12,12 +12,14 @@ import static org.dspace.iiif.canvasdimension.Util.checkDimensions;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
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.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.iiif.util.IIIFSharedUtils;
|
||||
|
||||
@@ -35,14 +37,10 @@ public class IIIFApiQueryServiceImpl implements IIIFApiQueryService {
|
||||
public int[] getImageDimensions(Bitstream bitstream) {
|
||||
int[] arr = new int[2];
|
||||
String path = IIIFSharedUtils.getInfoJsonPath(bitstream);
|
||||
URL url;
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
url = new URL(path);
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
in = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()));
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(path));
|
||||
in = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
|
||||
String inputLine;
|
||||
StringBuilder response = new StringBuilder();
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
|
@@ -17,7 +17,6 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.importer.external.datamodel.ImportRecord;
|
||||
import org.dspace.importer.external.datamodel.Query;
|
||||
@@ -144,7 +143,7 @@ public class MultipleParallelImportMetadataSourceServiceImpl implements QuerySou
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -21,7 +21,6 @@ import java.util.concurrent.Callable;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
@@ -99,7 +98,7 @@ public class ADSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -15,7 +15,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.client.ClientBuilder;
|
||||
import jakarta.ws.rs.client.Invocation;
|
||||
@@ -162,7 +161,7 @@ public class ArXivImportMetadataSourceServiceImpl extends AbstractImportMetadata
|
||||
@Override
|
||||
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
|
||||
// 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.concurrent.Callable;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.HttpException;
|
||||
@@ -113,7 +112,7 @@ public class CiniiImportMetadataSourceServiceImpl extends AbstractImportMetadata
|
||||
|
||||
@Override
|
||||
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() {
|
||||
|
@@ -20,7 +20,6 @@ import java.util.concurrent.Callable;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
@@ -112,7 +111,7 @@ public class CrossRefImportMetadataSourceServiceImpl extends AbstractImportMetad
|
||||
|
||||
@Override
|
||||
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) {
|
||||
|
@@ -17,7 +17,6 @@ import java.util.Map;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -204,7 +203,7 @@ public class DataCiteImportMetadataSourceServiceImpl
|
||||
|
||||
@Override
|
||||
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) {
|
||||
|
@@ -17,19 +17,16 @@ import java.util.Optional;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
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.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -53,16 +50,11 @@ public class LiveImportClientImpl implements LiveImportClient {
|
||||
@Override
|
||||
public String executeHttpGetRequest(int timeout, String URL, Map<String, Map<String, String>> params) {
|
||||
HttpGet method = null;
|
||||
RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(timeout).build();
|
||||
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
||||
.orElseGet(HttpClients::createDefault)) {
|
||||
|
||||
Builder requestConfigBuilder = RequestConfig.custom();
|
||||
requestConfigBuilder.setConnectionRequestTimeout(timeout);
|
||||
RequestConfig defaultRequestConfig = requestConfigBuilder.build();
|
||||
|
||||
.orElse(DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config))) {
|
||||
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
||||
method = new HttpGet(uri);
|
||||
method.setConfig(defaultRequestConfig);
|
||||
|
||||
Map<String, String> headerParams = params.get(HEADER_PARAMETERS);
|
||||
if (MapUtils.isNotEmpty(headerParams)) {
|
||||
@@ -71,7 +63,6 @@ public class LiveImportClientImpl implements LiveImportClient {
|
||||
}
|
||||
}
|
||||
|
||||
configureProxy(method, defaultRequestConfig);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Performing GET request to \"" + uri + "\"...");
|
||||
}
|
||||
@@ -95,21 +86,17 @@ public class LiveImportClientImpl implements LiveImportClient {
|
||||
@Override
|
||||
public String executeHttpPostRequest(String URL, Map<String, Map<String, String>> params, String entry) {
|
||||
HttpPost method = null;
|
||||
RequestConfig config = RequestConfig.custom().build();
|
||||
try (CloseableHttpClient httpClient = Optional.ofNullable(this.httpClient)
|
||||
.orElseGet(HttpClients::createDefault)) {
|
||||
|
||||
Builder requestConfigBuilder = RequestConfig.custom();
|
||||
RequestConfig defaultRequestConfig = requestConfigBuilder.build();
|
||||
.orElse(DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(config))) {
|
||||
|
||||
String uri = buildUrl(URL, params.get(URI_PARAMETERS));
|
||||
method = new HttpPost(uri);
|
||||
method.setConfig(defaultRequestConfig);
|
||||
if (StringUtils.isNotBlank(entry)) {
|
||||
method.setEntity(new StringEntity(entry));
|
||||
}
|
||||
setHeaderParams(method, params);
|
||||
|
||||
configureProxy(method, defaultRequestConfig);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Performing POST request to \"" + uri + "\"..." );
|
||||
}
|
||||
@@ -129,17 +116,6 @@ public class LiveImportClientImpl implements LiveImportClient {
|
||||
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
|
||||
*
|
||||
|
@@ -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.concurrent.Callable;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.client.ClientBuilder;
|
||||
import jakarta.ws.rs.client.Invocation;
|
||||
@@ -135,12 +134,12 @@ public class OpenAireImportMetadataSourceServiceImpl extends AbstractImportMetad
|
||||
|
||||
@Override
|
||||
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
|
||||
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.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -131,7 +130,7 @@ public class OpenAlexImportMetadataSourceServiceImpl extends AbstractImportMetad
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
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 {
|
||||
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));
|
||||
Element root = document.getRootElement();
|
||||
|
||||
|
@@ -18,7 +18,6 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
@@ -153,7 +152,7 @@ public class PubmedEuropeMetadataSourceServiceImpl extends AbstractImportMetadat
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -19,7 +19,6 @@ import java.util.concurrent.Callable;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
@@ -91,12 +90,12 @@ public class RorImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
|
@@ -21,7 +21,6 @@ import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
@@ -99,17 +98,17 @@ public class ScieloImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
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.Pattern;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -152,7 +151,7 @@ public class ScopusImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
||||
@Override
|
||||
public Collection<ImportRecord> findMatchingRecords(Item item)
|
||||
throws MetadataSourceException {
|
||||
throw new MethodNotFoundException("This method is not implemented for Scopus");
|
||||
throw new UnsupportedOperationException("This method is not implemented for Scopus");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -19,7 +19,6 @@ import java.util.concurrent.Callable;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -104,7 +103,7 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -22,7 +22,6 @@ import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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 Pattern ISI_PATTERN = Pattern.compile("^\\d{15}$");
|
||||
|
||||
private int timeout = 1000;
|
||||
private final int timeout = 1000;
|
||||
|
||||
private String url;
|
||||
private String urlSearch;
|
||||
@@ -109,17 +108,17 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
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 String query;
|
||||
private final String query;
|
||||
|
||||
private SearchNBByQueryCallable(String queryString) {
|
||||
this.query = queryString;
|
||||
@@ -156,7 +155,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
Element tot = xpath.evaluateFirst(root);
|
||||
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 String doi;
|
||||
private final String doi;
|
||||
|
||||
private FindByIdCallable(String doi) {
|
||||
this.doi = URLEncoder.encode(doi, StandardCharsets.UTF_8);
|
||||
@@ -186,6 +186,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
for (Element record : elements) {
|
||||
results.add(transformSourceRecords(record));
|
||||
}
|
||||
} else {
|
||||
log.warn("API key is missing: cannot execute live import request.");
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -203,7 +205,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
*/
|
||||
private class SearchByQueryCallable implements Callable<List<ImportRecord>> {
|
||||
|
||||
private Query query;
|
||||
private final Query query;
|
||||
|
||||
private SearchByQueryCallable(String queryString, Integer maxResult, Integer start) {
|
||||
query = new Query();
|
||||
@@ -233,6 +235,8 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
for (Element el : omElements) {
|
||||
results.add(transformSourceRecords(el));
|
||||
}
|
||||
} else {
|
||||
log.warn("API key is missing: cannot execute live import request.");
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -271,9 +275,7 @@ public class WOSImportMetadataSourceServiceImpl extends AbstractImportMetadataSo
|
||||
} else if (isIsi(query)) {
|
||||
return "UT=(" + query + ")";
|
||||
}
|
||||
StringBuilder queryBuilder = new StringBuilder("TS=(");
|
||||
queryBuilder.append(query).append(")");
|
||||
return queryBuilder.toString();
|
||||
return "TS=(" + query + ")";
|
||||
}
|
||||
|
||||
private boolean isIsi(String query) {
|
||||
|
@@ -10,9 +10,6 @@ package org.dspace.license;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
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.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.jdom2.Attribute;
|
||||
import org.jdom2.Document;
|
||||
@@ -70,12 +67,7 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
|
||||
client = builder
|
||||
.disableAutomaticRetries()
|
||||
.setMaxConnTotal(5)
|
||||
.build();
|
||||
client = DSpaceHttpClientFactory.getInstance().buildWithoutAutomaticRetries(5);
|
||||
|
||||
// disallow DTD parsing to ensure no XXE attacks can occur.
|
||||
// See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
@@ -333,23 +325,13 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
|
||||
@Override
|
||||
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
|
||||
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
||||
|
||||
String issueUrl = ccLicenseUrl + "/details?license-uri=" + licenseURI;
|
||||
|
||||
URL request_url;
|
||||
try {
|
||||
request_url = new URL(issueUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
URLConnection connection = request_url.openConnection();
|
||||
connection.setDoOutput(true);
|
||||
try {
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(new HttpPost(issueUrl));
|
||||
// parsing document from input stream
|
||||
InputStream stream = connection.getInputStream();
|
||||
InputStream stream = httpResponse.getEntity().getContent();
|
||||
Document doc = parser.build(stream);
|
||||
return doc;
|
||||
|
||||
} catch (Exception 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.HttpStatus;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
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.RequestBuilder;
|
||||
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.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.orcid.OrcidToken;
|
||||
import org.dspace.orcid.exception.OrcidClientException;
|
||||
import org.dspace.orcid.model.OrcidEntityType;
|
||||
@@ -254,10 +255,8 @@ public class OrcidClientImpl implements OrcidClient {
|
||||
}
|
||||
|
||||
private void executeSuccessful(HttpUriRequest httpUriRequest) {
|
||||
try {
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpResponse response = client.execute(httpUriRequest);
|
||||
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(
|
||||
getStatusCode(response),
|
||||
@@ -272,21 +271,17 @@ public class OrcidClientImpl implements OrcidClient {
|
||||
}
|
||||
|
||||
private <T> T executeAndParseJson(HttpUriRequest httpUriRequest, Class<T> clazz) {
|
||||
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
return executeAndReturns(() -> {
|
||||
|
||||
HttpResponse response = client.execute(httpUriRequest);
|
||||
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
|
||||
return objectMapper.readValue(response.getEntity().getContent(), clazz);
|
||||
|
||||
});
|
||||
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
return executeAndReturns(() -> {
|
||||
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
return objectMapper.readValue(response.getEntity().getContent(), clazz);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,44 +296,37 @@ public class OrcidClientImpl implements OrcidClient {
|
||||
* @throws OrcidClientException if the incoming response is not successful
|
||||
*/
|
||||
private <T> T executeAndUnmarshall(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull, Class<T> clazz) {
|
||||
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
return executeAndReturns(() -> {
|
||||
|
||||
HttpResponse response = client.execute(httpUriRequest);
|
||||
|
||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
|
||||
return unmarshall(response.getEntity(), clazz);
|
||||
|
||||
});
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
return executeAndReturns(() -> {
|
||||
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||
return null;
|
||||
}
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
return unmarshall(response.getEntity(), clazz);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private OrcidResponse execute(HttpUriRequest httpUriRequest, boolean handleNotFoundAsNull) {
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
|
||||
return executeAndReturns(() -> {
|
||||
|
||||
HttpResponse response = client.execute(httpUriRequest);
|
||||
|
||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||
return new OrcidResponse(getStatusCode(response), null, getContent(response));
|
||||
}
|
||||
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
|
||||
return new OrcidResponse(getStatusCode(response), getPutCode(response), getContent(response));
|
||||
|
||||
});
|
||||
try (CloseableHttpClient client = DSpaceHttpClientFactory.getInstance().build()) {
|
||||
return executeAndReturns(() -> {
|
||||
CloseableHttpResponse response = client.execute(httpUriRequest);
|
||||
if (handleNotFoundAsNull && isNotFound(response)) {
|
||||
return new OrcidResponse(getStatusCode(response), null, getContent(response));
|
||||
}
|
||||
if (isNotSuccessfull(response)) {
|
||||
throw new OrcidClientException(getStatusCode(response), formatErrorMessage(response));
|
||||
}
|
||||
return new OrcidResponse(getStatusCode(response), getPutCode(response), getContent(response));
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T executeAndReturns(ThrowingSupplier<T, Exception> supplier) {
|
||||
|
@@ -7,10 +7,21 @@
|
||||
*/
|
||||
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.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
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
|
||||
@@ -65,4 +76,48 @@ public final class OrcidFactoryUtils {
|
||||
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.StringEntity;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.QAEvent;
|
||||
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.
|
||||
*/
|
||||
private void makeAcknowledgement(String eventId, String source, String status) {
|
||||
String[] ackwnoledgeCallbacks = configurationService
|
||||
String[] acknowledgeCallbacks = configurationService
|
||||
.getArrayProperty("qaevents." + source + ".acknowledge-url");
|
||||
if (ackwnoledgeCallbacks != null) {
|
||||
for (String ackwnoledgeCallback : ackwnoledgeCallbacks) {
|
||||
if (StringUtils.isNotBlank(ackwnoledgeCallback)) {
|
||||
if (acknowledgeCallbacks != null) {
|
||||
for (String acknowledgeCallback : acknowledgeCallbacks) {
|
||||
if (StringUtils.isNotBlank(acknowledgeCallback)) {
|
||||
ObjectNode node = jsonMapper.createObjectNode();
|
||||
node.put("eventId", eventId);
|
||||
node.put("status", status);
|
||||
StringEntity requestEntity = new StringEntity(node.toString(), ContentType.APPLICATION_JSON);
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
HttpPost postMethod = new HttpPost(ackwnoledgeCallback);
|
||||
postMethod.setEntity(requestEntity);
|
||||
try {
|
||||
httpclient.execute(postMethod);
|
||||
try (CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||
HttpPost postMethod = new HttpPost(acknowledgeCallback);
|
||||
postMethod.setEntity(requestEntity);
|
||||
httpClient.execute(postMethod);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
@@ -117,9 +117,9 @@ public class Harvest {
|
||||
}
|
||||
|
||||
if (!withdrawn) {
|
||||
discoverQuery.addFilterQueries("archived: true OR withdrawn: false");
|
||||
discoverQuery.addFilterQueries("archived:true OR withdrawn:false");
|
||||
} 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
|
||||
|
@@ -19,11 +19,11 @@ import org.apache.http.HttpResponse;
|
||||
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
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.message.BasicHeaderElementIterator;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
|
||||
/**
|
||||
@@ -112,7 +112,7 @@ public class HttpConnectionPoolService {
|
||||
* @return the client.
|
||||
*/
|
||||
public CloseableHttpClient getClient() {
|
||||
CloseableHttpClient httpClient = HttpClientBuilder.create()
|
||||
CloseableHttpClient httpClient = DSpaceHttpClientFactory.getInstance().builder(true).create()
|
||||
.setKeepAliveStrategy(keepAliveStrategy)
|
||||
.setConnectionManager(connManager)
|
||||
.build();
|
||||
|
@@ -54,7 +54,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
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.Logger;
|
||||
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.ShardParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
@@ -1208,7 +1208,7 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea
|
||||
+ "."
|
||||
+ i
|
||||
+ ".csv");
|
||||
try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) {
|
||||
try (CloseableHttpClient hc = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||
HttpResponse response = hc.execute(get);
|
||||
csvInputstream = response.getEntity().getContent();
|
||||
//Write the csv output to a file !
|
||||
@@ -1350,7 +1350,7 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea
|
||||
|
||||
HttpGet get = new HttpGet(solrRequestUrl);
|
||||
List<String[]> rows;
|
||||
try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) {
|
||||
try (CloseableHttpClient hc = DSpaceHttpClientFactory.getInstance().buildWithoutProxy()) {
|
||||
HttpResponse response = hc.execute(get);
|
||||
InputStream csvOutput = response.getEntity().getContent();
|
||||
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
|
||||
// updated
|
||||
Item newItem = (Item) event.getObject(ctx);
|
||||
String updateQuery = "id: " + newItem.getID() + " AND type:"
|
||||
String updateQuery = "id:" + newItem.getID() + " AND type:"
|
||||
+ newItem.getType();
|
||||
|
||||
List<String> fieldNames = new ArrayList<String>();
|
||||
@@ -116,7 +116,7 @@ public class StatisticsLoggingConsumer implements Consumer {
|
||||
&& event.getObject(ctx) instanceof Item) {
|
||||
// Unmapping items
|
||||
Item newItem = (Item) event.getObject(ctx);
|
||||
String updateQuery = "id: " + newItem.getID() + " AND type:"
|
||||
String updateQuery = "id:" + newItem.getID() + " AND type:"
|
||||
+ newItem.getType();
|
||||
|
||||
List<String> fieldNames = new ArrayList<String>();
|
||||
|
@@ -68,10 +68,10 @@ public class StatisticsBSAdapter {
|
||||
switch (visitType) {
|
||||
case ITEM_VISITS:
|
||||
return solrLoggerService
|
||||
.queryTotal("type: " + Constants.ITEM + " AND id: " + item.getID(), resolveFilterQueries(), 0)
|
||||
.queryTotal("type:" + Constants.ITEM + " AND id:" + item.getID(), resolveFilterQueries(), 0)
|
||||
.getCount();
|
||||
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();
|
||||
case TOTAL_VISITS:
|
||||
return getNumberOfVisits(ITEM_VISITS, item) + getNumberOfVisits(BITSTREAM_VISITS, item);
|
||||
|
@@ -209,7 +209,7 @@ public class StatisticsDataSearches extends StatisticsData {
|
||||
protected String getQuery() {
|
||||
String query;
|
||||
if (currentDso != null) {
|
||||
query = "scopeType: " + currentDso.getType() + " AND ";
|
||||
query = "scopeType:" + currentDso.getType() + " AND ";
|
||||
if (currentDso instanceof DSpaceObjectLegacySupport) {
|
||||
query += " (scopeId:" + currentDso.getID() + " OR scopeId:" + ((DSpaceObjectLegacySupport) currentDso)
|
||||
.getLegacyId() + ")";
|
||||
|
@@ -237,7 +237,7 @@ public class StatisticsDataVisits extends StatisticsData {
|
||||
false, null, facetMinCount);
|
||||
for (int j = 0; j < maxObjectCounts.length; j++) {
|
||||
ObjectCount firstCount = maxObjectCounts[j];
|
||||
String newQuery = dataSetQuery.getFacetField() + ": " + ClientUtils
|
||||
String newQuery = dataSetQuery.getFacetField() + ":" + ClientUtils
|
||||
.escapeQueryChars(firstCount.getValue()) + " AND " + query;
|
||||
ObjectCount[] maxDateFacetCounts = solrLoggerService
|
||||
.queryFacetDate(newQuery, filterQuery, dataSetQuery.getMax(), dateFacet.getDateType(),
|
||||
@@ -813,7 +813,7 @@ public class StatisticsDataVisits extends StatisticsData {
|
||||
String query = "";
|
||||
//Check (& add if needed) the dsoType
|
||||
if (dsoType != -1) {
|
||||
query += "type: " + dsoType;
|
||||
query += "type:" + dsoType;
|
||||
}
|
||||
|
||||
//Check (& add if needed) the dsoId
|
||||
|
@@ -146,7 +146,7 @@ public class StatisticsDataWorkflow extends StatisticsData {
|
||||
*/
|
||||
protected String getQuery() {
|
||||
String query = "statistics_type:" + SolrLoggerServiceImpl.StatisticsType.WORKFLOW.text();
|
||||
query += " AND NOT(previousWorkflowStep: SUBMIT)";
|
||||
query += " AND NOT(previousWorkflowStep:SUBMIT)";
|
||||
if (currentDso != null) {
|
||||
if (currentDso.getType() == Constants.COMMUNITY) {
|
||||
query += " AND owningComm:";
|
||||
|
@@ -15,13 +15,13 @@ import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
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.methods.CloseableHttpResponse;
|
||||
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.Logger;
|
||||
import org.dspace.app.client.DSpaceHttpClientFactory;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.statistics.export.OpenURLTracker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -69,16 +69,16 @@ public class OpenUrlServiceImpl implements OpenUrlService {
|
||||
* @throws IOException
|
||||
*/
|
||||
protected int getResponseCodeFromUrl(final String urlStr) throws IOException {
|
||||
HttpGet httpGet = new HttpGet(urlStr);
|
||||
HttpClient httpClient = getHttpClient(getHttpClientRequestConfig());
|
||||
HttpResponse httpResponse = httpClient.execute(httpGet);
|
||||
return httpResponse.getStatusLine().getStatusCode();
|
||||
try (CloseableHttpClient httpClient = getHttpClient(getHttpClientRequestConfig())) {
|
||||
HttpGet httpGet = new HttpGet(urlStr);
|
||||
try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
|
||||
return httpResponse.getStatusLine().getStatusCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpClient getHttpClient(RequestConfig requestConfig) {
|
||||
return HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.build();
|
||||
protected CloseableHttpClient getHttpClient(RequestConfig requestConfig) {
|
||||
return DSpaceHttpClientFactory.getInstance().buildWithRequestConfig(requestConfig);
|
||||
}
|
||||
|
||||
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
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
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
|
||||
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-entity-type="CustomEntityType" submission-name="entitytypetest"/>
|
||||
<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"/>
|
||||
</submission-map>
|
||||
|
||||
@@ -195,6 +196,11 @@
|
||||
<processing-class>org.dspace.app.rest.submit.step.NotifyStep</processing-class>
|
||||
<type>coarnotify</type>
|
||||
</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">
|
||||
<heading>submit.progressbar.describe.stepone</heading>
|
||||
@@ -311,6 +317,12 @@
|
||||
<step id="publicationStep"></step>
|
||||
</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>
|
||||
|
||||
</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
|
||||
management.health.solrOai.enabled = false
|
||||
management.health.seo.enabled = false
|
||||
|
||||
# Enable researcher profiles and orcid synchronization for tests
|
||||
researcher-profile.entity-type = Person
|
||||
@@ -192,4 +193,13 @@ ldn.notify.inbox.block-untrusted-ip = true
|
||||
# ERROR LOGGING #
|
||||
###########################################
|
||||
# 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">
|
||||
<map>
|
||||
<entry key="upload" value-ref="uploadConfigurationDefault" />
|
||||
<entry key="upload-no-required-metadata" value-ref="uploadConfigurationPublicationTestPatch" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -116,4 +117,16 @@
|
||||
</property>
|
||||
</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>
|
||||
|
@@ -16,7 +16,7 @@
|
||||
<bean id="dspace.DSpaceAuthorityIndexer" class="org.dspace.authority.indexer.DSpaceAuthorityIndexer"/>
|
||||
|
||||
<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">
|
||||
<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