mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 23:13:10 +00:00
Merge branch 'master' into DS-4239-migrate-workflow-xml-to-spring
This commit is contained in:
@@ -4,3 +4,8 @@
|
|||||||
*/target/
|
*/target/
|
||||||
dspace/modules/*/target/
|
dspace/modules/*/target/
|
||||||
Dockerfile.*
|
Dockerfile.*
|
||||||
|
dspace/src/main/docker/dspace-postgres-pgcrypto
|
||||||
|
dspace/src/main/docker/dspace-postgres-pgcrypto-curl
|
||||||
|
dspace/src/main/docker/solr
|
||||||
|
dspace/src/main/docker/README.md
|
||||||
|
dspace/src/main/docker-compose/
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
language: java
|
language: java
|
||||||
sudo: false
|
sudo: false
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# Give Maven 1GB of memory to work with
|
# Give Maven 1GB of memory to work with
|
||||||
|
54
Dockerfile.cli.jdk8
Normal file
54
Dockerfile.cli.jdk8
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# This image will be published as dspace/dspace-cli
|
||||||
|
# See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details
|
||||||
|
#
|
||||||
|
# This version is JDK8 compatible
|
||||||
|
# - openjdk:8-jdk
|
||||||
|
# - ANT 1.10.7
|
||||||
|
# - maven:3-jdk-8
|
||||||
|
# - note:
|
||||||
|
# - default tag for branch: dspace/dspace-cli: dspace/dspace-cli:dspace-7_x
|
||||||
|
|
||||||
|
# Step 1 - Run Maven Build
|
||||||
|
FROM dspace/dspace-dependencies:dspace-7_x as build
|
||||||
|
ARG TARGET_DIR=dspace-installer
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# The dspace-install directory will be written to /install
|
||||||
|
RUN mkdir /install \
|
||||||
|
&& chown -Rv dspace: /install \
|
||||||
|
&& chown -Rv dspace: /app
|
||||||
|
|
||||||
|
USER dspace
|
||||||
|
|
||||||
|
# Copy the DSpace source code into the workdir (excluding .dockerignore contents)
|
||||||
|
ADD --chown=dspace . /app/
|
||||||
|
COPY dspace/src/main/docker/local.cfg /app/local.cfg
|
||||||
|
|
||||||
|
# Build DSpace. Copy the dspace-install directory to /install. Clean up the build to keep the docker image small
|
||||||
|
RUN mvn package -P'!dspace-rest' && \
|
||||||
|
mv /app/dspace/target/${TARGET_DIR}/* /install && \
|
||||||
|
mvn clean
|
||||||
|
|
||||||
|
# Step 2 - Run Ant Deploy
|
||||||
|
FROM openjdk:8-jdk as ant_build
|
||||||
|
ARG TARGET_DIR=dspace-installer
|
||||||
|
COPY --from=build /install /dspace-src
|
||||||
|
WORKDIR /dspace-src
|
||||||
|
|
||||||
|
# Create the initial install deployment using ANT
|
||||||
|
ENV ANT_VERSION 1.10.7
|
||||||
|
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||||
|
ENV PATH $ANT_HOME/bin:$PATH
|
||||||
|
|
||||||
|
RUN mkdir $ANT_HOME && \
|
||||||
|
wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME
|
||||||
|
|
||||||
|
RUN ant init_installation update_configs update_code
|
||||||
|
|
||||||
|
# Step 3 - Run jdk
|
||||||
|
# Create a new tomcat image that does not retain the the build directory contents
|
||||||
|
FROM openjdk:8-jdk
|
||||||
|
ENV DSPACE_INSTALL=/dspace
|
||||||
|
COPY --from=ant_build /dspace $DSPACE_INSTALL
|
||||||
|
|
||||||
|
ENV JAVA_OPTS=-Xmx1000m
|
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# This version is JDK8 compatible
|
# This version is JDK8 compatible
|
||||||
# - tomcat:8-jre8
|
# - tomcat:8-jre8
|
||||||
# - ANT 1.10.5
|
# - ANT 1.10.7
|
||||||
# - maven:3-jdk-8
|
# - maven:3-jdk-8
|
||||||
# - note:
|
# - note:
|
||||||
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8
|
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8
|
||||||
@@ -36,14 +36,14 @@ COPY --from=build /install /dspace-src
|
|||||||
WORKDIR /dspace-src
|
WORKDIR /dspace-src
|
||||||
|
|
||||||
# Create the initial install deployment using ANT
|
# Create the initial install deployment using ANT
|
||||||
ENV ANT_VERSION 1.10.5
|
ENV ANT_VERSION 1.10.7
|
||||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||||
ENV PATH $ANT_HOME/bin:$PATH
|
ENV PATH $ANT_HOME/bin:$PATH
|
||||||
|
|
||||||
RUN mkdir $ANT_HOME && \
|
RUN mkdir $ANT_HOME && \
|
||||||
wget -qO- "https://www.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME
|
wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME
|
||||||
|
|
||||||
RUN ant init_installation update_configs update_code update_webapps update_solr_indexes
|
RUN ant init_installation update_configs update_code update_webapps
|
||||||
|
|
||||||
# Step 3 - Run tomcat
|
# Step 3 - Run tomcat
|
||||||
# Create a new tomcat image that does not retain the the build directory contents
|
# Create a new tomcat image that does not retain the the build directory contents
|
||||||
@@ -54,10 +54,13 @@ EXPOSE 8080 8009
|
|||||||
|
|
||||||
ENV JAVA_OPTS=-Xmx2000m
|
ENV JAVA_OPTS=-Xmx2000m
|
||||||
|
|
||||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
# and the v6.x (deprecated) REST API off the "/rest" path
|
||||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
# Please note that server webapp should only run on one path at a time.
|
||||||
|
#RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||||
|
# ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||||
|
# ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# This version is JDK8 compatible
|
# This version is JDK8 compatible
|
||||||
# - tomcat:8-jre8
|
# - tomcat:8-jre8
|
||||||
# - ANT 1.10.5
|
# - ANT 1.10.7
|
||||||
# - maven:3-jdk-8
|
# - maven:3-jdk-8
|
||||||
# - note:
|
# - note:
|
||||||
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8-test
|
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8-test
|
||||||
@@ -36,14 +36,14 @@ COPY --from=build /install /dspace-src
|
|||||||
WORKDIR /dspace-src
|
WORKDIR /dspace-src
|
||||||
|
|
||||||
# Create the initial install deployment using ANT
|
# Create the initial install deployment using ANT
|
||||||
ENV ANT_VERSION 1.10.5
|
ENV ANT_VERSION 1.10.7
|
||||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||||
ENV PATH $ANT_HOME/bin:$PATH
|
ENV PATH $ANT_HOME/bin:$PATH
|
||||||
|
|
||||||
RUN mkdir $ANT_HOME && \
|
RUN mkdir $ANT_HOME && \
|
||||||
wget -qO- "https://www.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME
|
wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME
|
||||||
|
|
||||||
RUN ant init_installation update_configs update_code update_webapps update_solr_indexes
|
RUN ant init_installation update_configs update_code update_webapps
|
||||||
|
|
||||||
# Step 3 - Run tomcat
|
# Step 3 - Run tomcat
|
||||||
# Create a new tomcat image that does not retain the the build directory contents
|
# Create a new tomcat image that does not retain the the build directory contents
|
||||||
@@ -54,16 +54,17 @@ EXPOSE 8080 8009
|
|||||||
|
|
||||||
ENV JAVA_OPTS=-Xmx2000m
|
ENV JAVA_OPTS=-Xmx2000m
|
||||||
|
|
||||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
# and the v6.x (deprecated) REST API off the "/rest" path
|
||||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
# Please note that server webapp should only run on one path at a time.
|
||||||
|
#RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||||
|
# ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||||
|
# ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||||
|
|
||||||
COPY dspace/src/main/docker/test/solr_web.xml $DSPACE_INSTALL/webapps/solr/WEB-INF/web.xml
|
# Overwrite the v6.x (deprecated) REST API's web.xml, so that we can run it on HTTP (defaults to requiring HTTPS)
|
||||||
COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||||
|
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||||
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/solr/WEB-INF/web.xml && \
|
|
||||||
sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
|
@@ -14,7 +14,7 @@ For more information, visit http://www.dspace.org/
|
|||||||
|
|
||||||
***
|
***
|
||||||
:warning: **Work on DSpace 7 has begun on our `master` branch.** This means that there is temporarily NO user interface on this `master` branch. DSpace 7 will feature a new, unified [Angular](https://angular.io/) user interface, along with an enhanced, rebuilt REST API. The latest status of this work can be found on the [DSpace 7 UI Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) page. Additionally, the codebases can be found in the following places:
|
:warning: **Work on DSpace 7 has begun on our `master` branch.** This means that there is temporarily NO user interface on this `master` branch. DSpace 7 will feature a new, unified [Angular](https://angular.io/) user interface, along with an enhanced, rebuilt REST API. The latest status of this work can be found on the [DSpace 7 UI Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) page. Additionally, the codebases can be found in the following places:
|
||||||
* DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-spring-rest) of this repository.
|
* DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-server-webapp) of this repository.
|
||||||
* The REST Contract is being documented at https://github.com/DSpace/Rest7Contract
|
* The REST Contract is being documented at https://github.com/DSpace/Rest7Contract
|
||||||
* DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular
|
* DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular
|
||||||
|
|
||||||
@@ -40,8 +40,8 @@ Please be aware that, as a Java web application, DSpace requires a database (Pos
|
|||||||
and a servlet container (usually Tomcat) in order to function.
|
and a servlet container (usually Tomcat) in order to function.
|
||||||
More information about these and all other prerequisites can be found in the Installation instructions above.
|
More information about these and all other prerequisites can be found in the Installation instructions above.
|
||||||
|
|
||||||
## Dockerfile Usage
|
## Running DSpace 7 in Docker
|
||||||
See the [DSpace Docker Tutorial](https://dspace-labs.github.io/DSpace-Docker-Images/).
|
See [Running DSpace 7 with Docker Compose](dspace/src/main/docker-compose/README.md)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ run automatically by [Travis CI](https://travis-ci.org/DSpace/DSpace/) for all P
|
|||||||
mvn clean install
|
mvn clean install
|
||||||
|
|
||||||
# Then, move into a module subdirectory, and run the test command
|
# Then, move into a module subdirectory, and run the test command
|
||||||
cd [dspace-src]/dspace-spring-rest
|
cd [dspace-src]/dspace-server-webapp
|
||||||
# Choose your test command from the lists above
|
# Choose your test command from the lists above
|
||||||
```
|
```
|
||||||
|
|
||||||
|
25
docker-compose-cli.yml
Normal file
25
docker-compose-cli.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
dspace-cli:
|
||||||
|
image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}"
|
||||||
|
container_name: dspace-cli
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.cli.jdk8
|
||||||
|
#environment:
|
||||||
|
volumes:
|
||||||
|
- ./dspace/src/main/docker-compose/local.cfg:/dspace/config/local.cfg
|
||||||
|
- assetstore:/dspace/assetstore
|
||||||
|
entrypoint: /dspace/bin/dspace
|
||||||
|
command: help
|
||||||
|
networks:
|
||||||
|
- dspacenet
|
||||||
|
tty: true
|
||||||
|
stdin_open: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
assetstore:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
62
docker-compose.yml
Normal file
62
docker-compose.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
version: '3.7'
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
services:
|
||||||
|
dspace:
|
||||||
|
container_name: dspace
|
||||||
|
image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-jdk8-test}"
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.jdk8-test
|
||||||
|
depends_on:
|
||||||
|
- dspacedb
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
ports:
|
||||||
|
- published: 8080
|
||||||
|
target: 8080
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- assetstore:/dspace/assetstore
|
||||||
|
- ./dspace/src/main/docker-compose/local.cfg:/dspace/config/local.cfg
|
||||||
|
# Ensure that the database is ready before starting tomcat
|
||||||
|
entrypoint:
|
||||||
|
- /bin/bash
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
/dspace/bin/dspace database migrate
|
||||||
|
catalina.sh run
|
||||||
|
dspacedb:
|
||||||
|
container_name: dspacedb
|
||||||
|
environment:
|
||||||
|
PGDATA: /pgdata
|
||||||
|
image: dspace/dspace-postgres-pgcrypto
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- pgdata:/pgdata
|
||||||
|
dspacesolr:
|
||||||
|
container_name: dspacesolr
|
||||||
|
image: dspace/dspace-solr
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
ports:
|
||||||
|
- published: 8983
|
||||||
|
target: 8983
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- solr_authority:/opt/solr/server/solr/authority/data
|
||||||
|
- solr_oai:/opt/solr/server/solr/oai/data
|
||||||
|
- solr_search:/opt/solr/server/solr/search/data
|
||||||
|
- solr_statistics:/opt/solr/server/solr/statistics/data
|
||||||
|
volumes:
|
||||||
|
assetstore:
|
||||||
|
pgdata:
|
||||||
|
solr_authority:
|
||||||
|
solr_oai:
|
||||||
|
solr_search:
|
||||||
|
solr_statistics:
|
@@ -1,5 +1,4 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-api</artifactId>
|
<artifactId>dspace-api</artifactId>
|
||||||
@@ -87,7 +86,6 @@
|
|||||||
<exclude>**/.gitignore</exclude>
|
<exclude>**/.gitignore</exclude>
|
||||||
<exclude>**/src/main/resources/rebel.xml</exclude>
|
<exclude>**/src/main/resources/rebel.xml</exclude>
|
||||||
<exclude>src/test/data/dspaceFolder/config/spiders/**</exclude>
|
<exclude>src/test/data/dspaceFolder/config/spiders/**</exclude>
|
||||||
<exclude>src/main/java/org/apache/solr/handler/extraction/ExtractingParams.java</exclude>
|
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -335,6 +333,16 @@
|
|||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>handle</artifactId>
|
<artifactId>handle</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||||
|
<artifactId>jetty-all</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>javax.servlet</artifactId>
|
||||||
|
<groupId>org.eclipse.jetty.orbit</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>jargon</artifactId>
|
<artifactId>jargon</artifactId>
|
||||||
@@ -450,14 +458,6 @@
|
|||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>fontbox</artifactId>
|
<artifactId>fontbox</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk15</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcmail-jdk15</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.poi</groupId>
|
<groupId>org.apache.poi</groupId>
|
||||||
<artifactId>poi</artifactId>
|
<artifactId>poi</artifactId>
|
||||||
@@ -600,6 +600,12 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.solr</groupId>
|
||||||
|
<artifactId>solr-cell</artifactId>
|
||||||
|
<version>${solr.client.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-configuration2</artifactId>
|
<artifactId>commons-configuration2</artifactId>
|
||||||
@@ -757,6 +763,34 @@
|
|||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>20180130</version>
|
<version>20180130</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Used for Solr core export/import -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.opencsv</groupId>
|
||||||
|
<artifactId>opencsv</artifactId>
|
||||||
|
<version>4.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Email templating -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xmlunit</groupId>
|
||||||
|
<artifactId>xmlunit-matchers</artifactId>
|
||||||
|
<version>2.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.javax.persistence</groupId>
|
||||||
|
<artifactId>hibernate-jpa-2.1-api</artifactId>
|
||||||
|
<version>1.0.0.Final</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.solr.handler.extraction;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The various Solr Parameters names to use when extracting content.
|
|
||||||
**/
|
|
||||||
public interface ExtractingParams {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map all generated attribute names to field names with lowercase and underscores.
|
|
||||||
*/
|
|
||||||
public static final String LOWERNAMES = "lowernames";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if true, ignore TikaException (give up to extract text but index meta data)
|
|
||||||
*/
|
|
||||||
public static final String IGNORE_TIKA_EXCEPTION = "ignoreTikaException";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The param prefix for mapping Tika metadata to Solr fields.
|
|
||||||
* <p>
|
|
||||||
* To map a field, add a name like:
|
|
||||||
* <pre>fmap.title=solr.title</pre>
|
|
||||||
*
|
|
||||||
* In this example, the tika "title" metadata value will be added to a Solr field named "solr.title"
|
|
||||||
*/
|
|
||||||
public static final String MAP_PREFIX = "fmap.";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The boost value for the name of the field. The boost can be specified by a name mapping.
|
|
||||||
* <p>
|
|
||||||
* For example
|
|
||||||
* <pre>
|
|
||||||
* map.title=solr.title
|
|
||||||
* boost.solr.title=2.5
|
|
||||||
* </pre>
|
|
||||||
* will boost the solr.title field for this document by 2.5
|
|
||||||
*/
|
|
||||||
public static final String BOOST_PREFIX = "boost.";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass in literal values to be added to the document, as in
|
|
||||||
* <pre>
|
|
||||||
* literal.myField=Foo
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public static final String LITERALS_PREFIX = "literal.";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restrict the extracted parts of a document to be indexed
|
|
||||||
* by passing in an XPath expression. All content that satisfies the XPath expr.
|
|
||||||
* will be passed to the {@link org.apache.solr.handler.extraction.SolrContentHandler}.
|
|
||||||
* <p>
|
|
||||||
* See Tika's docs for what the extracted document looks like.
|
|
||||||
*
|
|
||||||
* @see #CAPTURE_ELEMENTS
|
|
||||||
*/
|
|
||||||
public static final String XPATH_EXPRESSION = "xpath";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only extract and return the content, do not index it.
|
|
||||||
*/
|
|
||||||
public static final String EXTRACT_ONLY = "extractOnly";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Content output format if extractOnly is true. Default is "xml", alternative is "text".
|
|
||||||
*/
|
|
||||||
public static final String EXTRACT_FORMAT = "extractFormat";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capture attributes separately according to the name of the element, instead of just adding them to the string
|
|
||||||
* buffer
|
|
||||||
*/
|
|
||||||
public static final String CAPTURE_ATTRIBUTES = "captureAttr";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Literal field values will by default override other values such as metadata and content. Set this to false to
|
|
||||||
* revert to pre-4.0 behaviour
|
|
||||||
*/
|
|
||||||
public static final String LITERALS_OVERRIDE = "literalsOverride";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capture the specified fields (and everything included below it that isn't capture by some other capture field)
|
|
||||||
* separately from the default. This is different
|
|
||||||
* then the case of passing in an XPath expression.
|
|
||||||
* <p>
|
|
||||||
* The Capture field is based on the localName returned to the
|
|
||||||
* {@link org.apache.solr.handler.extraction.SolrContentHandler}
|
|
||||||
* by Tika, not to be confused by the mapped field. The field name can then
|
|
||||||
* be mapped into the index schema.
|
|
||||||
* <p>
|
|
||||||
* For instance, a Tika document may look like:
|
|
||||||
* <pre>
|
|
||||||
* <html>
|
|
||||||
* ...
|
|
||||||
* <body>
|
|
||||||
* <p>some text here. <div>more text</div></p>
|
|
||||||
* Some more text
|
|
||||||
* </body>
|
|
||||||
* </pre>
|
|
||||||
* By passing in the p tag, you could capture all P tags separately from the rest of the t
|
|
||||||
* Thus, in the example, the capture of the P tag would be: "some text here. more text"
|
|
||||||
*/
|
|
||||||
public static final String CAPTURE_ELEMENTS = "capture";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the stream. If not specified, Tika will use mime type detection.
|
|
||||||
*/
|
|
||||||
public static final String STREAM_TYPE = "stream.type";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional. The file name. If specified, Tika can take this into account while
|
|
||||||
* guessing the MIME type.
|
|
||||||
*/
|
|
||||||
public static final String RESOURCE_NAME = "resource.name";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional. The password for this resource. Will be used instead of the rule based password lookup mechanisms
|
|
||||||
*/
|
|
||||||
public static final String RESOURCE_PASSWORD = "resource.password";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional. If specified, the prefix will be prepended to all Metadata, such that it would be possible
|
|
||||||
* to setup a dynamic field to automatically capture it
|
|
||||||
*/
|
|
||||||
public static final String UNKNOWN_FIELD_PREFIX = "uprefix";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional. If specified and the name of a potential field cannot be determined, the default Field specified
|
|
||||||
* will be used instead.
|
|
||||||
*/
|
|
||||||
public static final String DEFAULT_FIELD = "defaultField";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional. If specified, loads the file as a source for password lookups for Tika encrypted documents.
|
|
||||||
* <p>
|
|
||||||
* File format is Java properties format with one key=value per line.
|
|
||||||
* The key is evaluated as a regex against the file name, and the value is the password
|
|
||||||
* The rules are evaluated top-bottom, i.e. the first match will be used
|
|
||||||
* If you want a fallback password to be always used, supply a .*=<defaultmypassword> at the end
|
|
||||||
*/
|
|
||||||
public static final String PASSWORD_MAP_FILE = "passwordsFile";
|
|
||||||
}
|
|
@@ -21,6 +21,7 @@ import org.apache.xpath.XPathAPI;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.NonUniqueMetadataException;
|
import org.dspace.content.NonUniqueMetadataException;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.MetadataFieldService;
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
@@ -248,7 +249,7 @@ public class MetadataImporter {
|
|||||||
|
|
||||||
// If the schema is not provided default to DC
|
// If the schema is not provided default to DC
|
||||||
if (schema == null) {
|
if (schema == null) {
|
||||||
schema = MetadataSchema.DC_SCHEMA;
|
schema = MetadataSchemaEnum.DC.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -7,12 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.administer;
|
package org.dspace.administer;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.FileInputStream;
|
||||||
import java.io.File;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileWriter;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
@@ -23,12 +27,16 @@ import org.apache.commons.cli.CommandLine;
|
|||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
import org.apache.commons.cli.DefaultParser;
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.xpath.XPathAPI;
|
import org.apache.xpath.XPathAPI;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
@@ -36,6 +44,7 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||||
import org.dspace.eperson.service.EPersonService;
|
import org.dspace.eperson.service.EPersonService;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jdom.output.Format;
|
||||||
import org.jdom.output.XMLOutputter;
|
import org.jdom.output.XMLOutputter;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
@@ -47,8 +56,7 @@ import org.xml.sax.SAXException;
|
|||||||
* an XML file.
|
* an XML file.
|
||||||
*
|
*
|
||||||
* The XML file structure needs to be:
|
* The XML file structure needs to be:
|
||||||
* <p>
|
* <pre>{@code
|
||||||
* {@code
|
|
||||||
* <import_structure>
|
* <import_structure>
|
||||||
* <community>
|
* <community>
|
||||||
* <name>....</name>
|
* <name>....</name>
|
||||||
@@ -58,7 +66,7 @@ import org.xml.sax.SAXException;
|
|||||||
* </collection>
|
* </collection>
|
||||||
* </community>
|
* </community>
|
||||||
* </import_structure>
|
* </import_structure>
|
||||||
* }
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
* It can be arbitrarily deep, and supports all the metadata elements
|
* It can be arbitrarily deep, and supports all the metadata elements
|
||||||
* that make up the community and collection metadata. See the system
|
* that make up the community and collection metadata. See the system
|
||||||
@@ -68,26 +76,31 @@ import org.xml.sax.SAXException;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class StructBuilder {
|
public class StructBuilder {
|
||||||
/**
|
/** Name of the root element for the document to be imported. */
|
||||||
* The output XML document which will contain updated information about the
|
static final String INPUT_ROOT = "import_structure";
|
||||||
* imported structure.
|
|
||||||
|
/*
|
||||||
|
* Name of the root element for the document produced by importing.
|
||||||
|
* Community and collection elements are annotated with their identifiers.
|
||||||
*/
|
*/
|
||||||
private static final org.jdom.Document xmlOutput
|
static final String RESULT_ROOT = "imported_structure";
|
||||||
= new org.jdom.Document(new Element("imported_structure"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hash table to hold metadata for the collection being worked on.
|
* A table to hold metadata for the collection being worked on.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, String> collectionMap = new HashMap<>();
|
private static final Map<String, String> collectionMap = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hash table to hold metadata for the community being worked on.
|
* A table to hold metadata for the community being worked on.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, String> communityMap = new HashMap<>();
|
private static final Map<String, String> communityMap = new HashMap<>();
|
||||||
|
|
||||||
protected static CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
protected static CommunityService communityService
|
||||||
protected static CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
= ContentServiceFactory.getInstance().getCommunityService();
|
||||||
protected static EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
protected static CollectionService collectionService
|
||||||
|
= ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
protected static EPersonService ePersonService
|
||||||
|
= EPersonServiceFactory.getInstance().getEPersonService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
@@ -96,31 +109,48 @@ public class StructBuilder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Main method to be run from the command line to import a structure into
|
* Main method to be run from the command line to import a structure into
|
||||||
* DSpace
|
* DSpacee or export existing structure to a file.The command is of the form:
|
||||||
*
|
*
|
||||||
* This is of the form:
|
* <p>{@code StructBuilder -f [XML source] -e [administrator email] -o [output file]}
|
||||||
*
|
*
|
||||||
* {@code StructBuilder -f [xml source] -e [administrator email] -o [output file]}
|
* <p>to import, or
|
||||||
*
|
*
|
||||||
* The output file will contain exactly the same as the source xml document, but
|
* <p>{@code StructBuilder -x -e [administrator email] -o [output file]}</p>
|
||||||
* with the handle for each imported item added as an attribute.
|
|
||||||
*
|
*
|
||||||
* @param argv the command line arguments given
|
* <p>to export. The output will contain exactly the same as the source XML
|
||||||
|
* document, but with the Handle for each imported item added as an attribute.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param argv command line arguments.
|
||||||
* @throws ParserConfigurationException passed through.
|
* @throws ParserConfigurationException passed through.
|
||||||
* @throws SQLException passed through.
|
* @throws SQLException passed through.
|
||||||
|
* @throws FileNotFoundException if input or output could not be opened.
|
||||||
|
* @throws TransformerException if the input document is invalid.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] argv)
|
public static void main(String[] argv)
|
||||||
throws ParserConfigurationException, SQLException {
|
throws ParserConfigurationException, SQLException,
|
||||||
CommandLineParser parser = new DefaultParser();
|
FileNotFoundException, IOException, TransformerException {
|
||||||
|
// Define command line options.
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
|
|
||||||
options.addOption("h", "help", false, "help");
|
options.addOption("h", "help", false, "Print this help message.");
|
||||||
options.addOption("?", "help");
|
options.addOption("?", "help");
|
||||||
options.addOption("f", "file", true, "input structure document");
|
options.addOption("x", "export", false, "Export the current structure as XML.");
|
||||||
options.addOption("e", "eperson", true, "eperson");
|
|
||||||
options.addOption("o", "output", true, "output structure document");
|
|
||||||
|
|
||||||
|
options.addOption(Option.builder("e").longOpt("eperson")
|
||||||
|
.desc("User who is manipulating the repository's structure.")
|
||||||
|
.hasArg().argName("eperson").required().build());
|
||||||
|
|
||||||
|
options.addOption(Option.builder("f").longOpt("file")
|
||||||
|
.desc("File of new structure information.")
|
||||||
|
.hasArg().argName("input").build());
|
||||||
|
|
||||||
|
options.addOption(Option.builder("o").longOpt("output")
|
||||||
|
.desc("File to receive the structure map ('-' for standard out).")
|
||||||
|
.hasArg().argName("output").required().build());
|
||||||
|
|
||||||
|
// Parse the command line.
|
||||||
|
CommandLineParser parser = new DefaultParser();
|
||||||
CommandLine line = null;
|
CommandLine line = null;
|
||||||
try {
|
try {
|
||||||
line = parser.parse(options, argv);
|
line = parser.parse(options, argv);
|
||||||
@@ -130,36 +160,33 @@ public class StructBuilder {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user asked for help, give it and exit.
|
||||||
if (line.hasOption('h') || line.hasOption('?')) {
|
if (line.hasOption('h') || line.hasOption('?')) {
|
||||||
usage(options);
|
giveHelp(options);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
String file = null;
|
// Otherwise, analyze the command.
|
||||||
String eperson = null;
|
// Must be import or export.
|
||||||
String output = null;
|
if (!(line.hasOption('f') || line.hasOption('x'))) {
|
||||||
|
giveHelp(options);
|
||||||
if (line.hasOption('f')) {
|
|
||||||
file = line.getOptionValue('f');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.hasOption('e')) {
|
|
||||||
eperson = line.getOptionValue('e');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.hasOption('o')) {
|
|
||||||
output = line.getOptionValue('o');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output == null || eperson == null || file == null) {
|
|
||||||
usage(options);
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open the output stream.
|
||||||
|
String output = line.getOptionValue('o');
|
||||||
|
OutputStream outputStream;
|
||||||
|
if ("-".equals(output)) {
|
||||||
|
outputStream = System.out;
|
||||||
|
} else {
|
||||||
|
outputStream = new FileOutputStream(output);
|
||||||
|
}
|
||||||
|
|
||||||
// create a context
|
// create a context
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
|
|
||||||
// set the context
|
// set the context.
|
||||||
|
String eperson = line.getOptionValue('e');
|
||||||
try {
|
try {
|
||||||
context.setCurrentUser(ePersonService.findByEmail(context, eperson));
|
context.setCurrentUser(ePersonService.findByEmail(context, eperson));
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
@@ -167,10 +194,47 @@ public class StructBuilder {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export? Import?
|
||||||
|
if (line.hasOption('x')) { // export
|
||||||
|
exportStructure(context, outputStream);
|
||||||
|
} else { // Must be import
|
||||||
|
String input = line.getOptionValue('f');
|
||||||
|
if (null == input) {
|
||||||
|
usage(options);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream inputStream;
|
||||||
|
if ("-".equals(input)) {
|
||||||
|
inputStream = System.in;
|
||||||
|
} else {
|
||||||
|
inputStream = new FileInputStream(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
importStructure(context, inputStream, outputStream);
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import new Community/Collection structure.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param input XML which describes the new communities and collections.
|
||||||
|
* @param output input, annotated with the new objects' identifiers.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws TransformerException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
static void importStructure(Context context, InputStream input, OutputStream output)
|
||||||
|
throws IOException, ParserConfigurationException, SQLException, TransformerException {
|
||||||
|
|
||||||
// load the XML
|
// load the XML
|
||||||
Document document = null;
|
Document document = null;
|
||||||
try {
|
try {
|
||||||
document = loadXML(file);
|
document = loadXML(input);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.err.format("The input document could not be read: %s%n", ex.getMessage());
|
System.err.format("The input document could not be read: %s%n", ex.getMessage());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
@@ -180,7 +244,7 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// run the preliminary validation, to be sure that the the XML document
|
// run the preliminary validation, to be sure that the the XML document
|
||||||
// is properly structured
|
// is properly structured.
|
||||||
try {
|
try {
|
||||||
validate(document);
|
validate(document);
|
||||||
} catch (TransformerException ex) {
|
} catch (TransformerException ex) {
|
||||||
@@ -188,6 +252,12 @@ public class StructBuilder {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for 'identifier' attributes -- possibly output by this class.
|
||||||
|
NodeList identifierNodes = XPathAPI.selectNodeList(document, "//*[@identifier]");
|
||||||
|
if (identifierNodes.getLength() > 0) {
|
||||||
|
System.err.println("The input document has 'identifier' attributes, which will be ignored.");
|
||||||
|
}
|
||||||
|
|
||||||
// load the mappings into the member variable hashmaps
|
// load the mappings into the member variable hashmaps
|
||||||
communityMap.put("name", "name");
|
communityMap.put("name", "name");
|
||||||
communityMap.put("description", "short_description");
|
communityMap.put("description", "short_description");
|
||||||
@@ -219,33 +289,154 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate the output
|
// generate the output
|
||||||
Element root = xmlOutput.getRootElement();
|
final Element root = new Element(RESULT_ROOT);
|
||||||
|
|
||||||
for (Element element : elements) {
|
for (Element element : elements) {
|
||||||
root.addContent(element);
|
root.addContent(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally write the string into the output file
|
// finally write the string into the output file.
|
||||||
try (BufferedWriter out = new BufferedWriter(new FileWriter(output));) {
|
final org.jdom.Document xmlOutput = new org.jdom.Document(root);
|
||||||
out.write(new XMLOutputter().outputString(xmlOutput));
|
try {
|
||||||
|
new XMLOutputter().output(xmlOutput, output);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Unable to write to output file " + output);
|
System.out.printf("Unable to write to output file %s: %s%n",
|
||||||
|
output, e.getMessage());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.complete();
|
context.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single community, and its children, to the Document.
|
||||||
|
*
|
||||||
|
* @param community
|
||||||
|
* @return a fragment representing this Community.
|
||||||
|
*/
|
||||||
|
private static Element exportACommunity(Community community) {
|
||||||
|
// Export this Community.
|
||||||
|
Element element = new Element("community");
|
||||||
|
element.setAttribute("identifier", community.getHandle());
|
||||||
|
element.addContent(new Element("name").setText(community.getName()));
|
||||||
|
element.addContent(new Element("description")
|
||||||
|
.setText(communityService.getMetadataFirstValue(community,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", "abstract", Item.ANY)));
|
||||||
|
element.addContent(new Element("intro")
|
||||||
|
.setText(communityService.getMetadataFirstValue(community,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", null, Item.ANY)));
|
||||||
|
element.addContent(new Element("copyright")
|
||||||
|
.setText(communityService.getMetadataFirstValue(community,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "rights", null, Item.ANY)));
|
||||||
|
element.addContent(new Element("sidebar")
|
||||||
|
.setText(communityService.getMetadataFirstValue(community,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", "tableofcontents", Item.ANY)));
|
||||||
|
|
||||||
|
// Export this Community's Community children.
|
||||||
|
for (Community subCommunity : community.getSubcommunities()) {
|
||||||
|
element.addContent(exportACommunity(subCommunity));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export this Community's Collection children.
|
||||||
|
for (Collection collection : community.getCollections()) {
|
||||||
|
element.addContent(exportACollection(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single Collection to the Document.
|
||||||
|
*
|
||||||
|
* @param collection
|
||||||
|
* @return a fragment representing this Collection.
|
||||||
|
*/
|
||||||
|
private static Element exportACollection(Collection collection) {
|
||||||
|
// Export this Collection.
|
||||||
|
Element element = new Element("collection");
|
||||||
|
element.setAttribute("identifier", collection.getHandle());
|
||||||
|
element.addContent(new Element("name").setText(collection.getName()));
|
||||||
|
element.addContent(new Element("description")
|
||||||
|
.setText(collectionService.getMetadataFirstValue(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", "abstract", Item.ANY)));
|
||||||
|
element.addContent(new Element("intro")
|
||||||
|
.setText(collectionService.getMetadataFirstValue(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", null, Item.ANY)));
|
||||||
|
element.addContent(new Element("copyright")
|
||||||
|
.setText(collectionService.getMetadataFirstValue(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "rights", null, Item.ANY)));
|
||||||
|
element.addContent(new Element("sidebar")
|
||||||
|
.setText(collectionService.getMetadataFirstValue(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "description", "tableofcontents", Item.ANY)));
|
||||||
|
element.addContent(new Element("license")
|
||||||
|
.setText(collectionService.getMetadataFirstValue(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "rights", "license", Item.ANY)));
|
||||||
|
// Provenance is special: multivalued
|
||||||
|
for (MetadataValue value : collectionService.getMetadata(collection,
|
||||||
|
MetadataSchemaEnum.DC.getName(), "provenance", null, Item.ANY)) {
|
||||||
|
element.addContent(new Element("provenance")
|
||||||
|
.setText(value.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write out the existing Community/Collection structure.
|
||||||
|
*/
|
||||||
|
static void exportStructure(Context context, OutputStream output) {
|
||||||
|
// Build a document from the Community/Collection hierarchy.
|
||||||
|
Element rootElement = new Element(INPUT_ROOT); // To be read by importStructure, perhaps
|
||||||
|
|
||||||
|
List<Community> communities = null;
|
||||||
|
try {
|
||||||
|
communities = communityService.findAllTop(context);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
System.out.printf("Unable to get the list of top-level communities: %s%n",
|
||||||
|
ex.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Community community : communities) {
|
||||||
|
rootElement.addContent(exportACommunity(community));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now write the structure out.
|
||||||
|
org.jdom.Document xmlOutput = new org.jdom.Document(rootElement);
|
||||||
|
try {
|
||||||
|
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
|
||||||
|
outputter.output(xmlOutput, output);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.printf("Unable to write to output file %s: %s%n",
|
||||||
|
output, e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output the usage information.
|
* Output the usage information.
|
||||||
*/
|
*/
|
||||||
private static void usage(Options options) {
|
private static void usage(Options options) {
|
||||||
HelpFormatter helper = new HelpFormatter();
|
HelpFormatter helper = new HelpFormatter();
|
||||||
helper.printHelp("java StructBuilder -f <source XML file> -o <output file> -e <eperson email>",
|
try (PrintWriter writer = new PrintWriter(System.out);) {
|
||||||
"Load community/collection structure from a file.",
|
helper.printUsage(writer, 80/* FIXME Magic */,
|
||||||
|
"structure-builder", options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help the user more.
|
||||||
|
*/
|
||||||
|
private static void giveHelp(Options options) {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("struct-builder",
|
||||||
|
"Import or export Community/Collection structure.",
|
||||||
options,
|
options,
|
||||||
"Communities will be created from the top level,"
|
"When importing (-f), communities will be created from the "
|
||||||
+ " and a map of communities to handles will be returned"
|
+ "top level, and a map of communities to handles will "
|
||||||
+ " in the output file.");
|
+ "be returned in the output file. When exporting (-x),"
|
||||||
|
+ "the current structure will be written to the map file.",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,7 +458,7 @@ public class StructBuilder {
|
|||||||
if (first.getLength() == 0) {
|
if (first.getLength() == 0) {
|
||||||
err.append("-There are no top level communities in the source document.");
|
err.append("-There are no top level communities in the source document.");
|
||||||
System.out.println(err.toString());
|
System.out.println(err.toString());
|
||||||
System.exit(0);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String errs = validateCommunities(first, 1);
|
String errs = validateCommunities(first, 1);
|
||||||
@@ -278,7 +469,7 @@ public class StructBuilder {
|
|||||||
|
|
||||||
if (trip) {
|
if (trip) {
|
||||||
System.out.println(err.toString());
|
System.out.println(err.toString());
|
||||||
System.exit(0);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,17 +558,17 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load in the XML from file.
|
* Load the XML document from input.
|
||||||
*
|
*
|
||||||
* @param filename the filename to load from
|
* @param input the filename to load from.
|
||||||
* @return the DOM representation of the XML file
|
* @return the DOM representation of the XML input.
|
||||||
*/
|
*/
|
||||||
private static org.w3c.dom.Document loadXML(String filename)
|
private static org.w3c.dom.Document loadXML(InputStream input)
|
||||||
throws IOException, ParserConfigurationException, SAXException {
|
throws IOException, ParserConfigurationException, SAXException {
|
||||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
|
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
|
||||||
.newDocumentBuilder();
|
.newDocumentBuilder();
|
||||||
|
|
||||||
org.w3c.dom.Document document = builder.parse(new File(filename));
|
org.w3c.dom.Document document = builder.parse(input);
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
@@ -388,7 +579,7 @@ public class StructBuilder {
|
|||||||
* @param node the node from which we want to extract the string value
|
* @param node the node from which we want to extract the string value
|
||||||
* @return the string value of the node
|
* @return the string value of the node
|
||||||
*/
|
*/
|
||||||
public static String getStringValue(Node node) {
|
private static String getStringValue(Node node) {
|
||||||
String value = node.getNodeValue();
|
String value = node.getNodeValue();
|
||||||
|
|
||||||
if (node.hasChildNodes()) {
|
if (node.hasChildNodes()) {
|
||||||
|
@@ -27,6 +27,7 @@ import java.util.UUID;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.authority.AuthorityValue;
|
import org.dspace.authority.AuthorityValue;
|
||||||
import org.dspace.authority.factory.AuthorityServiceFactory;
|
import org.dspace.authority.factory.AuthorityServiceFactory;
|
||||||
import org.dspace.authority.service.AuthorityValueService;
|
import org.dspace.authority.service.AuthorityValueService;
|
||||||
@@ -34,6 +35,7 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.authority.Choices;
|
import org.dspace.content.authority.Choices;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
@@ -168,6 +170,9 @@ public class DSpaceCSV implements Serializable {
|
|||||||
if ("collection".equals(element)) {
|
if ("collection".equals(element)) {
|
||||||
// Store the heading
|
// Store the heading
|
||||||
headings.add(element);
|
headings.add(element);
|
||||||
|
} else if ("rowName".equals(element)) {
|
||||||
|
// Store the heading
|
||||||
|
headings.add(element);
|
||||||
} else if ("action".equals(element)) { // Store the action
|
} else if ("action".equals(element)) { // Store the action
|
||||||
// Store the heading
|
// Store the heading
|
||||||
headings.add(element);
|
headings.add(element);
|
||||||
@@ -198,10 +203,12 @@ public class DSpaceCSV implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that the scheme exists
|
// Check that the scheme exists
|
||||||
|
if (!StringUtils.equals(metadataSchema, MetadataSchemaEnum.RELATION.getName())) {
|
||||||
MetadataSchema foundSchema = metadataSchemaService.find(c, metadataSchema);
|
MetadataSchema foundSchema = metadataSchemaService.find(c, metadataSchema);
|
||||||
if (foundSchema == null) {
|
if (foundSchema == null) {
|
||||||
throw new MetadataImportInvalidHeadingException(clean[0],
|
throw new MetadataImportInvalidHeadingException(clean[0],
|
||||||
MetadataImportInvalidHeadingException.SCHEMA,
|
MetadataImportInvalidHeadingException
|
||||||
|
.SCHEMA,
|
||||||
columnCounter);
|
columnCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,9 +217,11 @@ public class DSpaceCSV implements Serializable {
|
|||||||
.findByElement(c, foundSchema, metadataElement, metadataQualifier);
|
.findByElement(c, foundSchema, metadataElement, metadataQualifier);
|
||||||
if (foundField == null) {
|
if (foundField == null) {
|
||||||
throw new MetadataImportInvalidHeadingException(clean[0],
|
throw new MetadataImportInvalidHeadingException(clean[0],
|
||||||
MetadataImportInvalidHeadingException.ELEMENT,
|
MetadataImportInvalidHeadingException
|
||||||
|
.ELEMENT,
|
||||||
columnCounter);
|
columnCounter);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Store the heading
|
// Store the heading
|
||||||
headings.add(authorityPrefix + element);
|
headings.add(authorityPrefix + element);
|
||||||
|
@@ -14,10 +14,14 @@ import java.io.InputStreamReader;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
@@ -33,14 +37,25 @@ import org.dspace.authority.service.AuthorityValueService;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Entity;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataField;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
|
import org.dspace.content.Relationship;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.authority.Choices;
|
import org.dspace.content.authority.Choices;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.EntityService;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
import org.dspace.content.service.InstallItemService;
|
import org.dspace.content.service.InstallItemService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
|
import org.dspace.content.service.MetadataValueService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
@@ -89,6 +104,45 @@ public class MetadataImport {
|
|||||||
*/
|
*/
|
||||||
protected static final String AC_PREFIX = "authority.controlled.";
|
protected static final String AC_PREFIX = "authority.controlled.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of field:value to csv row number, used to resolve indirect entity target references.
|
||||||
|
*
|
||||||
|
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||||
|
*/
|
||||||
|
protected Map<String, Set<Integer>> csvRefMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of csv row number to UUID, used to resolve indirect entity target references.
|
||||||
|
*
|
||||||
|
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||||
|
*/
|
||||||
|
protected HashMap<Integer, UUID> csvRowMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of UUIDs to their entity types.
|
||||||
|
*
|
||||||
|
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||||
|
*/
|
||||||
|
protected static HashMap<UUID, String> entityTypeMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of UUIDs to their relations that are referenced within any import with their referers.
|
||||||
|
*
|
||||||
|
* @see #populateEntityRelationMap(String, String, String)
|
||||||
|
*/
|
||||||
|
protected static HashMap<String, HashMap<String, ArrayList<String>>> entityRelationMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of errors generated during relation validation process.
|
||||||
|
*/
|
||||||
|
protected ArrayList<String> relationValidationErrors = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counter of rows proccssed in a CSV.
|
||||||
|
*/
|
||||||
|
protected Integer rowCount = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger
|
* Logger
|
||||||
*/
|
*/
|
||||||
@@ -101,6 +155,10 @@ public class MetadataImport {
|
|||||||
protected final CollectionService collectionService;
|
protected final CollectionService collectionService;
|
||||||
protected final HandleService handleService;
|
protected final HandleService handleService;
|
||||||
protected final WorkspaceItemService workspaceItemService;
|
protected final WorkspaceItemService workspaceItemService;
|
||||||
|
protected final RelationshipTypeService relationshipTypeService;
|
||||||
|
protected final RelationshipService relationshipService;
|
||||||
|
protected final EntityTypeService entityTypeService;
|
||||||
|
protected final EntityService entityService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of the metadata importer. Requires a context and an array of CSV lines
|
* Create an instance of the metadata importer. Requires a context and an array of CSV lines
|
||||||
@@ -120,6 +178,10 @@ public class MetadataImport {
|
|||||||
handleService = HandleServiceFactory.getInstance().getHandleService();
|
handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||||
authorityValueService = AuthorityServiceFactory.getInstance().getAuthorityValueService();
|
authorityValueService = AuthorityServiceFactory.getInstance().getAuthorityValueService();
|
||||||
workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||||
|
relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||||
|
relationshipTypeService = ContentServiceFactory.getInstance().getRelationshipTypeService();
|
||||||
|
entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
|
||||||
|
entityService = ContentServiceFactory.getInstance().getEntityService();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,7 +208,11 @@ public class MetadataImport {
|
|||||||
c.setMode(Context.Mode.BATCH_EDIT);
|
c.setMode(Context.Mode.BATCH_EDIT);
|
||||||
|
|
||||||
// Process each change
|
// Process each change
|
||||||
|
rowCount = 1;
|
||||||
for (DSpaceCSVLine line : toImport) {
|
for (DSpaceCSVLine line : toImport) {
|
||||||
|
// Resolve target references to other items
|
||||||
|
populateRefAndRowMap(line, line.getID());
|
||||||
|
line = resolveEntityRefs(line);
|
||||||
// Get the DSpace item to compare with
|
// Get the DSpace item to compare with
|
||||||
UUID id = line.getID();
|
UUID id = line.getID();
|
||||||
|
|
||||||
@@ -159,7 +225,7 @@ public class MetadataImport {
|
|||||||
WorkflowItem wfItem = null;
|
WorkflowItem wfItem = null;
|
||||||
Item item = null;
|
Item item = null;
|
||||||
|
|
||||||
// Is this a new item?
|
// Is this an existing item?
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
// Get the item
|
// Get the item
|
||||||
item = itemService.find(c, id);
|
item = itemService.find(c, id);
|
||||||
@@ -196,9 +262,8 @@ public class MetadataImport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
compare(item, fromCSV, change, md, whatHasChanged, line);
|
compareAndUpdate(item, fromCSV, change, md, whatHasChanged, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +324,7 @@ public class MetadataImport {
|
|||||||
BulkEditChange whatHasChanged = new BulkEditChange();
|
BulkEditChange whatHasChanged = new BulkEditChange();
|
||||||
for (String md : line.keys()) {
|
for (String md : line.keys()) {
|
||||||
// Get the values we already have
|
// Get the values we already have
|
||||||
if (!"id".equals(md)) {
|
if (!"id".equals(md) && !"rowName".equals(md)) {
|
||||||
// Get the values from the CSV
|
// Get the values from the CSV
|
||||||
String[] fromCSV = line.get(md).toArray(new String[line.get(md).size()]);
|
String[] fromCSV = line.get(md).toArray(new String[line.get(md).size()]);
|
||||||
|
|
||||||
@@ -337,6 +402,7 @@ public class MetadataImport {
|
|||||||
|
|
||||||
// Add the metadata to the item
|
// Add the metadata to the item
|
||||||
for (BulkEditMetadataValue dcv : whatHasChanged.getAdds()) {
|
for (BulkEditMetadataValue dcv : whatHasChanged.getAdds()) {
|
||||||
|
if (!StringUtils.equals(dcv.getSchema(), MetadataSchemaEnum.RELATION.getName())) {
|
||||||
itemService.addMetadata(c, item, dcv.getSchema(),
|
itemService.addMetadata(c, item, dcv.getSchema(),
|
||||||
dcv.getElement(),
|
dcv.getElement(),
|
||||||
dcv.getQualifier(),
|
dcv.getQualifier(),
|
||||||
@@ -345,6 +411,14 @@ public class MetadataImport {
|
|||||||
dcv.getAuthority(),
|
dcv.getAuthority(),
|
||||||
dcv.getConfidence());
|
dcv.getConfidence());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//Add relations after all metadata has been processed
|
||||||
|
for (BulkEditMetadataValue dcv : whatHasChanged.getAdds()) {
|
||||||
|
if (StringUtils.equals(dcv.getSchema(), MetadataSchemaEnum.RELATION.getName())) {
|
||||||
|
addRelationship(c, item, dcv.getElement(), dcv.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Should the workflow be used?
|
// Should the workflow be used?
|
||||||
if (useWorkflow) {
|
if (useWorkflow) {
|
||||||
@@ -368,8 +442,6 @@ public class MetadataImport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit changes to the object
|
|
||||||
// c.commit();
|
|
||||||
whatHasChanged.setItem(item);
|
whatHasChanged.setItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +455,9 @@ public class MetadataImport {
|
|||||||
c.uncacheEntity(wfItem);
|
c.uncacheEntity(wfItem);
|
||||||
c.uncacheEntity(item);
|
c.uncacheEntity(item);
|
||||||
}
|
}
|
||||||
|
populateRefAndRowMap(line, item == null ? null : item.getID());
|
||||||
|
// keep track of current rows processed
|
||||||
|
rowCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.setMode(originalMode);
|
c.setMode(originalMode);
|
||||||
@@ -393,11 +468,14 @@ public class MetadataImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the changes
|
// Return the changes
|
||||||
|
if (!change ) {
|
||||||
|
validateExpressedRelations();
|
||||||
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare an item metadata with a line from CSV, and optionally update the item
|
* Compare an item metadata with a line from CSV, and optionally update the item.
|
||||||
*
|
*
|
||||||
* @param item The current item metadata
|
* @param item The current item metadata
|
||||||
* @param fromCSV The metadata from the CSV file
|
* @param fromCSV The metadata from the CSV file
|
||||||
@@ -407,10 +485,11 @@ public class MetadataImport {
|
|||||||
* @param line line in CSV file
|
* @param line line in CSV file
|
||||||
* @throws SQLException if there is a problem accessing a Collection from the database, from its handle
|
* @throws SQLException if there is a problem accessing a Collection from the database, from its handle
|
||||||
* @throws AuthorizeException if there is an authorization problem with permissions
|
* @throws AuthorizeException if there is an authorization problem with permissions
|
||||||
|
* @throws MetadataImportException custom exception for error handling within metadataimport
|
||||||
*/
|
*/
|
||||||
protected void compare(Item item, String[] fromCSV, boolean change,
|
protected void compareAndUpdate(Item item, String[] fromCSV, boolean change,
|
||||||
String md, BulkEditChange changes, DSpaceCSVLine line)
|
String md, BulkEditChange changes, DSpaceCSVLine line)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException, MetadataImportException {
|
||||||
// Log what metadata element we're looking at
|
// Log what metadata element we're looking at
|
||||||
String all = "";
|
String all = "";
|
||||||
for (String part : fromCSV) {
|
for (String part : fromCSV) {
|
||||||
@@ -420,8 +499,8 @@ public class MetadataImport {
|
|||||||
log.debug(LogManager.getHeader(c, "metadata_import",
|
log.debug(LogManager.getHeader(c, "metadata_import",
|
||||||
"item_id=" + item.getID() + ",fromCSV=" + all));
|
"item_id=" + item.getID() + ",fromCSV=" + all));
|
||||||
|
|
||||||
// Don't compare collections or actions
|
// Don't compare collections or actions or rowNames
|
||||||
if (("collection".equals(md)) || ("action".equals(md))) {
|
if (("collection".equals(md)) || ("action".equals(md)) || ("rowName".equals(md))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,12 +662,130 @@ public class MetadataImport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set those values
|
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName())) {
|
||||||
|
List<RelationshipType> relationshipTypeList = relationshipTypeService
|
||||||
|
.findByLeftwardOrRightwardTypeName(c, element);
|
||||||
|
for (RelationshipType relationshipType : relationshipTypeList) {
|
||||||
|
for (Relationship relationship : relationshipService
|
||||||
|
.findByItemAndRelationshipType(c, item, relationshipType)) {
|
||||||
|
relationshipService.delete(c, relationship);
|
||||||
|
relationshipService.update(c, relationship);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addRelationships(c, item, element, values);
|
||||||
|
} else {
|
||||||
itemService.clearMetadata(c, item, schema, element, qualifier, language);
|
itemService.clearMetadata(c, item, schema, element, qualifier, language);
|
||||||
itemService.addMetadata(c, item, schema, element, qualifier, language, values, authorities, confidences);
|
itemService.addMetadata(c, item, schema, element, qualifier,
|
||||||
|
language, values, authorities, confidences);
|
||||||
itemService.update(c, item);
|
itemService.update(c, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Adds multiple relationships with a matching typeName to an item.
|
||||||
|
*
|
||||||
|
* @param c The relevant DSpace context
|
||||||
|
* @param item The item to which this metadatavalue belongs to
|
||||||
|
* @param typeName The element for the metadatavalue
|
||||||
|
* @param values to iterate over
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
private void addRelationships(Context c, Item item, String typeName, List<String> values)
|
||||||
|
throws SQLException, AuthorizeException,
|
||||||
|
MetadataImportException {
|
||||||
|
for (String value : values) {
|
||||||
|
addRelationship(c, item, typeName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an existing entity from a target reference.
|
||||||
|
*
|
||||||
|
* @param context the context to use.
|
||||||
|
* @param targetReference the target reference which may be a UUID, metadata reference, or rowName reference.
|
||||||
|
* @return the entity, which is guaranteed to exist.
|
||||||
|
* @throws MetadataImportException if the target reference is badly formed or refers to a non-existing item.
|
||||||
|
*/
|
||||||
|
private Entity getEntity(Context context, String targetReference) throws MetadataImportException {
|
||||||
|
Entity entity = null;
|
||||||
|
UUID uuid = resolveEntityRef(context, targetReference);
|
||||||
|
// At this point, we have a uuid, so we can get an entity
|
||||||
|
try {
|
||||||
|
entity = entityService.findByItemId(context, uuid);
|
||||||
|
if (entity.getItem() == null) {
|
||||||
|
throw new IllegalArgumentException("No item found in repository with uuid: " + uuid);
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
throw new MetadataImportException("Unable to find entity using reference: " + targetReference, sqle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Creates a relationship for the given item
|
||||||
|
*
|
||||||
|
* @param c The relevant DSpace context
|
||||||
|
* @param item The item that the relationships will be made for
|
||||||
|
* @param typeName The relationship typeName
|
||||||
|
* @param value The value for the relationship
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
private void addRelationship(Context c, Item item, String typeName, String value)
|
||||||
|
throws SQLException, AuthorizeException, MetadataImportException {
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean left = false;
|
||||||
|
|
||||||
|
// Get entity from target reference
|
||||||
|
Entity relationEntity = getEntity(c, value);
|
||||||
|
// Get relationship type of entity and item
|
||||||
|
String relationEntityRelationshipType = itemService.getMetadata(relationEntity.getItem(),
|
||||||
|
"relationship", "type",
|
||||||
|
null, Item.ANY).get(0).getValue();
|
||||||
|
String itemRelationshipType = itemService.getMetadata(item, "relationship", "type",
|
||||||
|
null, Item.ANY).get(0).getValue();
|
||||||
|
|
||||||
|
// Get the correct RelationshipType based on typeName
|
||||||
|
List<RelationshipType> relType = relationshipTypeService.findByLeftwardOrRightwardTypeName(c, typeName);
|
||||||
|
RelationshipType foundRelationshipType = matchRelationshipType(relType,
|
||||||
|
relationEntityRelationshipType, itemRelationshipType, typeName);
|
||||||
|
|
||||||
|
if (foundRelationshipType == null) {
|
||||||
|
throw new MetadataImportException("Error on CSV row " + rowCount + ":" + "\n" +
|
||||||
|
"No Relationship type found for:\n" +
|
||||||
|
"Target type: " + relationEntityRelationshipType + "\n" +
|
||||||
|
"Origin referer type: " + itemRelationshipType + "\n" +
|
||||||
|
"with typeName: " + typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundRelationshipType.getLeftwardType().equalsIgnoreCase(typeName)) {
|
||||||
|
left = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder items for relation placing
|
||||||
|
Item leftItem = null;
|
||||||
|
Item rightItem = null;
|
||||||
|
if (left) {
|
||||||
|
leftItem = item;
|
||||||
|
rightItem = relationEntity.getItem();
|
||||||
|
} else {
|
||||||
|
leftItem = relationEntity.getItem();
|
||||||
|
rightItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the relationship
|
||||||
|
int leftPlace = relationshipService.findNextLeftPlaceByLeftItem(c, leftItem);
|
||||||
|
int rightPlace = relationshipService.findNextRightPlaceByRightItem(c, rightItem);
|
||||||
|
Relationship persistedRelationship = relationshipService.create(c, leftItem, rightItem,
|
||||||
|
foundRelationshipType, leftPlace, rightPlace);
|
||||||
|
relationshipService.update(c, persistedRelationship);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare changes between an items owning collection and mapped collections
|
* Compare changes between an items owning collection and mapped collections
|
||||||
@@ -1078,6 +1275,8 @@ public class MetadataImport {
|
|||||||
"notify - when adding new items using a workflow, send notification emails");
|
"notify - when adding new items using a workflow, send notification emails");
|
||||||
options.addOption("t", "template", false,
|
options.addOption("t", "template", false,
|
||||||
"template - when adding new items, use the collection template (if it exists)");
|
"template - when adding new items, use the collection template (if it exists)");
|
||||||
|
options.addOption("v", "validate-only", false,
|
||||||
|
"validate - just validate the csv, don't run the import");
|
||||||
options.addOption("h", "help", false, "help");
|
options.addOption("h", "help", false, "help");
|
||||||
|
|
||||||
// Parse the command line arguments
|
// Parse the command line arguments
|
||||||
@@ -1175,7 +1374,9 @@ public class MetadataImport {
|
|||||||
MetadataImport importer = new MetadataImport(c, csv);
|
MetadataImport importer = new MetadataImport(c, csv);
|
||||||
List<BulkEditChange> changes;
|
List<BulkEditChange> changes;
|
||||||
|
|
||||||
if (!line.hasOption('s')) {
|
boolean validateOnly = line.hasOption('v');
|
||||||
|
|
||||||
|
if (!line.hasOption('s') || validateOnly) {
|
||||||
// See what has changed
|
// See what has changed
|
||||||
try {
|
try {
|
||||||
changes = importer.runImport(false, useWorkflow, workflowNotify, useTemplate);
|
changes = importer.runImport(false, useWorkflow, workflowNotify, useTemplate);
|
||||||
@@ -1189,7 +1390,7 @@ public class MetadataImport {
|
|||||||
int changeCounter = displayChanges(changes, false);
|
int changeCounter = displayChanges(changes, false);
|
||||||
|
|
||||||
// If there were changes, ask if we should execute them
|
// If there were changes, ask if we should execute them
|
||||||
if (changeCounter > 0) {
|
if (!validateOnly && changeCounter > 0) {
|
||||||
try {
|
try {
|
||||||
// Ask the user if they want to make the changes
|
// Ask the user if they want to make the changes
|
||||||
System.out.println("\n" + changeCounter + " item(s) will be changed\n");
|
System.out.println("\n" + changeCounter + " item(s) will be changed\n");
|
||||||
@@ -1214,7 +1415,7 @@ public class MetadataImport {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// If required, make the change
|
// If required, make the change
|
||||||
if (change) {
|
if (change && !validateOnly) {
|
||||||
try {
|
try {
|
||||||
// Make the changes
|
// Make the changes
|
||||||
changes = importer.runImport(true, useWorkflow, workflowNotify, useTemplate);
|
changes = importer.runImport(true, useWorkflow, workflowNotify, useTemplate);
|
||||||
@@ -1226,9 +1427,6 @@ public class MetadataImport {
|
|||||||
|
|
||||||
// Display the changes
|
// Display the changes
|
||||||
displayChanges(changes, true);
|
displayChanges(changes, true);
|
||||||
|
|
||||||
// Commit the change to the DB
|
|
||||||
// c.commit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finsh off and tidy up
|
// Finsh off and tidy up
|
||||||
@@ -1241,4 +1439,418 @@ public class MetadataImport {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a copy of the given csv line with all entity target references resolved to UUID strings.
|
||||||
|
* Keys being iterated over represent metadatafields or special columns to be processed.
|
||||||
|
*
|
||||||
|
* @param line the csv line to process.
|
||||||
|
* @return a copy, with all references resolved.
|
||||||
|
* @throws MetadataImportException if there is an error resolving any entity target reference.
|
||||||
|
*/
|
||||||
|
public DSpaceCSVLine resolveEntityRefs(DSpaceCSVLine line) throws MetadataImportException {
|
||||||
|
DSpaceCSVLine newLine = new DSpaceCSVLine(line.getID());
|
||||||
|
UUID originId = evaluateOriginId(line.getID());
|
||||||
|
for (String key : line.keys()) {
|
||||||
|
// If a key represents a relation field attempt to resolve the target reference from the csvRefMap
|
||||||
|
if (key.split("\\.")[0].equalsIgnoreCase("relation")) {
|
||||||
|
if (line.get(key).size() > 0) {
|
||||||
|
for (String val : line.get(key)) {
|
||||||
|
// Attempt to resolve the relation target reference
|
||||||
|
// These can be a UUID, metadata target reference or rowName target reference
|
||||||
|
String uuid = resolveEntityRef(c, val).toString();
|
||||||
|
newLine.add(key, uuid);
|
||||||
|
//Entity refs have been resolved / placeholdered
|
||||||
|
//Populate the EntityRelationMap
|
||||||
|
populateEntityRelationMap(uuid, key, originId.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (line.get(key).size() > 1) {
|
||||||
|
for (String value : line.get(key)) {
|
||||||
|
newLine.add(key, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (line.get(key).size() > 0) {
|
||||||
|
newLine.add(key, line.get(key).get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the entityRelationMap with all target references and it's asscoiated typeNames
|
||||||
|
* to their respective origins
|
||||||
|
*
|
||||||
|
* @param refUUID the target reference UUID for the relation
|
||||||
|
* @param relationField the field of the typeNames to relate from
|
||||||
|
*/
|
||||||
|
private void populateEntityRelationMap(String refUUID, String relationField, String originId) {
|
||||||
|
HashMap<String, ArrayList<String>> typeNames = null;
|
||||||
|
if (entityRelationMap.get(refUUID) == null) {
|
||||||
|
typeNames = new HashMap<>();
|
||||||
|
ArrayList<String> originIds = new ArrayList<>();
|
||||||
|
originIds.add(originId);
|
||||||
|
typeNames.put(relationField, originIds);
|
||||||
|
entityRelationMap.put(refUUID, typeNames);
|
||||||
|
} else {
|
||||||
|
typeNames = entityRelationMap.get(refUUID);
|
||||||
|
if (typeNames.get(relationField) == null) {
|
||||||
|
ArrayList<String> originIds = new ArrayList<>();
|
||||||
|
originIds.add(originId);
|
||||||
|
typeNames.put(relationField, originIds);
|
||||||
|
} else {
|
||||||
|
ArrayList<String> originIds = typeNames.get(relationField);
|
||||||
|
originIds.add(originId);
|
||||||
|
typeNames.put(relationField, originIds);
|
||||||
|
}
|
||||||
|
entityRelationMap.put(refUUID, typeNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the csvRefMap, csvRowMap, and entityTypeMap for the given csv line.
|
||||||
|
*
|
||||||
|
* The csvRefMap is an index that keeps track of which rows have a specific value for
|
||||||
|
* a specific metadata field or the special "rowName" column. This is used to help resolve indirect
|
||||||
|
* entity target references in the same CSV.
|
||||||
|
*
|
||||||
|
* The csvRowMap is a row number to UUID map, and contains an entry for every row that has
|
||||||
|
* been processed so far which has a known (minted) UUID for its item. This is used to help complete
|
||||||
|
* the resolution after the row number has been determined.
|
||||||
|
*
|
||||||
|
* @param line the csv line.
|
||||||
|
* @param uuid the uuid of the item, which may be null if it has not been minted yet.
|
||||||
|
*/
|
||||||
|
private void populateRefAndRowMap(DSpaceCSVLine line, @Nullable UUID uuid) {
|
||||||
|
if (uuid != null) {
|
||||||
|
csvRowMap.put(rowCount, uuid);
|
||||||
|
} else {
|
||||||
|
csvRowMap.put(rowCount, new UUID(0, rowCount));
|
||||||
|
}
|
||||||
|
for (String key : line.keys()) {
|
||||||
|
if (key.contains(".") && !key.split("\\.")[0].equalsIgnoreCase("relation") ||
|
||||||
|
key.equalsIgnoreCase("rowName")) {
|
||||||
|
for (String value : line.get(key)) {
|
||||||
|
String valueKey = key + ":" + value;
|
||||||
|
Set<Integer> rowNums = csvRefMap.get(valueKey);
|
||||||
|
if (rowNums == null) {
|
||||||
|
rowNums = new HashSet<>();
|
||||||
|
csvRefMap.put(valueKey, rowNums);
|
||||||
|
}
|
||||||
|
rowNums.add(rowCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Populate entityTypeMap
|
||||||
|
if (key.equalsIgnoreCase("relationship.type") && line.get(key).size() > 0) {
|
||||||
|
if (uuid == null) {
|
||||||
|
entityTypeMap.put(new UUID(0, rowCount), line.get(key).get(0));
|
||||||
|
} else {
|
||||||
|
entityTypeMap.put(uuid, line.get(key).get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the UUID of the item indicated by the given target reference,
|
||||||
|
* which may be a direct UUID string, a row reference
|
||||||
|
* of the form rowName:VALUE, or a metadata value reference of the form schema.element[.qualifier]:VALUE.
|
||||||
|
*
|
||||||
|
* The reference may refer to a previously-processed item in the CSV or an item in the database.
|
||||||
|
*
|
||||||
|
* @param context the context to use.
|
||||||
|
* @param reference the target reference which may be a UUID, metadata reference, or rowName reference.
|
||||||
|
* @return the uuid.
|
||||||
|
* @throws MetadataImportException if the target reference is malformed or ambiguous (refers to multiple items).
|
||||||
|
*/
|
||||||
|
private UUID resolveEntityRef(Context context, String reference) throws MetadataImportException {
|
||||||
|
// value reference
|
||||||
|
UUID uuid = null;
|
||||||
|
if (!reference.contains(":")) {
|
||||||
|
// assume it's a UUID
|
||||||
|
try {
|
||||||
|
return UUID.fromString(reference);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Not a UUID or indirect entity reference: '" + reference + "'");
|
||||||
|
}
|
||||||
|
} else if (!reference.startsWith("rowName:") ) { // Not a rowName ref; so it's a metadata value reference
|
||||||
|
MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
||||||
|
MetadataFieldService metadataFieldService =
|
||||||
|
ContentServiceFactory.getInstance().getMetadataFieldService();
|
||||||
|
int i = reference.indexOf(":");
|
||||||
|
String mfValue = reference.substring(i + 1);
|
||||||
|
String mf[] = reference.substring(0, i).split("\\.");
|
||||||
|
if (mf.length < 2) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Bad metadata field in reference: '" + reference
|
||||||
|
+ "' (expected syntax is schema.element[.qualifier])");
|
||||||
|
}
|
||||||
|
String schema = mf[0];
|
||||||
|
String element = mf[1];
|
||||||
|
String qualifier = mf.length == 2 ? null : mf[2];
|
||||||
|
try {
|
||||||
|
MetadataField mfo = metadataFieldService.findByElement(context, schema, element, qualifier);
|
||||||
|
Iterator<MetadataValue> mdv = metadataValueService.findByFieldAndValue(context, mfo, mfValue);
|
||||||
|
if (mdv.hasNext()) {
|
||||||
|
MetadataValue mdvVal = mdv.next();
|
||||||
|
uuid = mdvVal.getDSpaceObject().getID();
|
||||||
|
if (mdv.hasNext()) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Ambiguous reference; multiple matches in db: " + reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Error looking up item by metadata reference: " + reference, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Lookup UUIDs that may have already been processed into the csvRefMap
|
||||||
|
// See populateRefAndRowMap() for how the csvRefMap is populated
|
||||||
|
// See getMatchingCSVUUIDs() for how the reference param is sourced from the csvRefMap
|
||||||
|
Set<UUID> csvUUIDs = getMatchingCSVUUIDs(reference);
|
||||||
|
if (csvUUIDs.size() > 1) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Ambiguous reference; multiple matches in csv: " + reference);
|
||||||
|
} else if (csvUUIDs.size() == 1) {
|
||||||
|
UUID csvUUID = csvUUIDs.iterator().next();
|
||||||
|
if (csvUUID.equals(uuid)) {
|
||||||
|
return uuid; // one match from csv and db (same item)
|
||||||
|
} else if (uuid != null) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"Ambiguous reference; multiple matches in db and csv: " + reference);
|
||||||
|
} else {
|
||||||
|
return csvUUID; // one match from csv
|
||||||
|
}
|
||||||
|
} else { // size == 0; the reference does not exist throw an error
|
||||||
|
if (uuid == null) {
|
||||||
|
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||||
|
"No matches found for reference: " + reference
|
||||||
|
+ "\nKeep in mind you can only reference entries that are listed before " +
|
||||||
|
"this one within the CSV.");
|
||||||
|
} else {
|
||||||
|
return uuid; // one match from db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of matching lines as UUIDs that have already been processed given a metadata value.
|
||||||
|
*
|
||||||
|
* @param mdValueRef the metadataValue reference to search for.
|
||||||
|
* @return the set of matching lines as UUIDs.
|
||||||
|
*/
|
||||||
|
private Set<UUID> getMatchingCSVUUIDs(String mdValueRef) {
|
||||||
|
Set<UUID> set = new HashSet<>();
|
||||||
|
if (csvRefMap.containsKey(mdValueRef)) {
|
||||||
|
for (Integer rowNum : csvRefMap.get(mdValueRef)) {
|
||||||
|
set.add(getUUIDForRow(rowNum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the UUID of the item of a given row in the CSV, if it has been minted.
|
||||||
|
* If the UUID has not yet been minted, gets a UUID representation of the row
|
||||||
|
* (a UUID whose numeric value equals the row number).
|
||||||
|
*
|
||||||
|
* @param rowNum the row number.
|
||||||
|
* @return the UUID of the item
|
||||||
|
*/
|
||||||
|
private UUID getUUIDForRow(int rowNum) {
|
||||||
|
if (csvRowMap.containsKey(rowNum)) {
|
||||||
|
return csvRowMap.get(rowNum);
|
||||||
|
} else {
|
||||||
|
return new UUID(0, rowNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a UUID of the origin in process or a placeholder for the origin to be evaluated later
|
||||||
|
*
|
||||||
|
* @param originId UUID of the origin
|
||||||
|
* @return the UUID of the item or UUID placeholder
|
||||||
|
*/
|
||||||
|
private UUID evaluateOriginId(@Nullable UUID originId) {
|
||||||
|
if (originId != null) {
|
||||||
|
return originId;
|
||||||
|
} else {
|
||||||
|
return new UUID(0, rowCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate every relation modification expressed in the CSV.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void validateExpressedRelations() throws MetadataImportException {
|
||||||
|
for (String targetUUID : entityRelationMap.keySet()) {
|
||||||
|
String targetType = null;
|
||||||
|
try {
|
||||||
|
// Get the type of reference. Attempt lookup in processed map first before looking in archive.
|
||||||
|
if (entityTypeMap.get(UUID.fromString(targetUUID)) != null) {
|
||||||
|
targetType = entityTypeService.
|
||||||
|
findByEntityType(c, entityTypeMap.get(UUID.fromString(targetUUID))).getLabel();
|
||||||
|
} else {
|
||||||
|
// Target item may be archived; check there.
|
||||||
|
// Add to errors if Realtionship.type cannot be derived
|
||||||
|
Item targetItem = null;
|
||||||
|
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
|
||||||
|
targetItem = itemService.find(c, UUID.fromString(targetUUID));
|
||||||
|
List<MetadataValue> relTypes = itemService.
|
||||||
|
getMetadata(targetItem, "relationship", "type", null, Item.ANY);
|
||||||
|
String relTypeValue = null;
|
||||||
|
if (relTypes.size() > 0) {
|
||||||
|
relTypeValue = relTypes.get(0).getValue();
|
||||||
|
targetType = entityTypeService.findByEntityType(c, relTypeValue).getLabel();
|
||||||
|
} else {
|
||||||
|
relationValidationErrors.add("Cannot resolve Entity type for target UUID: " +
|
||||||
|
targetUUID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
relationValidationErrors.add("Cannot resolve Entity type for target UUID: " +
|
||||||
|
targetUUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (targetType == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Get typeNames for each origin referer of this target.
|
||||||
|
for (String typeName : entityRelationMap.get(targetUUID).keySet()) {
|
||||||
|
// Resolve Entity Type for each origin referer.
|
||||||
|
for (String originRefererUUID : entityRelationMap.get(targetUUID).get(typeName)) {
|
||||||
|
// Evaluate row number for origin referer.
|
||||||
|
String originRow = "N/A";
|
||||||
|
if (csvRowMap.containsValue(UUID.fromString(originRefererUUID))) {
|
||||||
|
for (int key : csvRowMap.keySet()) {
|
||||||
|
if (csvRowMap.get(key).toString().equalsIgnoreCase(originRefererUUID)) {
|
||||||
|
originRow = key + "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String originType = "";
|
||||||
|
// Validate target type and origin type pairing with typeName or add to errors.
|
||||||
|
// Attempt lookup in processed map first before looking in archive.
|
||||||
|
if (entityTypeMap.get(UUID.fromString(originRefererUUID)) != null) {
|
||||||
|
originType = entityTypeMap.get(UUID.fromString(originRefererUUID));
|
||||||
|
validateTypesByTypeByTypeName(targetType, originType, typeName, originRow);
|
||||||
|
} else {
|
||||||
|
// Origin item may be archived; check there.
|
||||||
|
// Add to errors if Realtionship.type cannot be derived.
|
||||||
|
Item originItem = null;
|
||||||
|
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
|
||||||
|
originItem = itemService.find(c, UUID.fromString(originRefererUUID));
|
||||||
|
List<MetadataValue> relTypes = itemService.
|
||||||
|
getMetadata(originItem, "relationship", "type", null, Item.ANY);
|
||||||
|
String relTypeValue = null;
|
||||||
|
if (relTypes.size() > 0) {
|
||||||
|
relTypeValue = relTypes.get(0).getValue();
|
||||||
|
originType = entityTypeService.findByEntityType(c, relTypeValue).getLabel();
|
||||||
|
validateTypesByTypeByTypeName(targetType, originType, typeName, originRow);
|
||||||
|
} else {
|
||||||
|
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||||
|
"Cannot resolve Entity type for reference: "
|
||||||
|
+ originRefererUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||||
|
"Cannot resolve Entity type for reference: "
|
||||||
|
+ originRefererUUID + " in row: " + originRow );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
throw new MetadataImportException("Error interacting with database!", sqle);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // If relationValidationErrors is empty all described relationships are valid.
|
||||||
|
if (!relationValidationErrors.isEmpty()) {
|
||||||
|
StringBuilder errors = new StringBuilder();
|
||||||
|
for (String error : relationValidationErrors) {
|
||||||
|
errors.append(error + "\n");
|
||||||
|
}
|
||||||
|
throw new MetadataImportException("Error validating relationships: \n" + errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a list of potenital Relationship Types given a typeName and attempts to match the given
|
||||||
|
* targetType and originType to a Relationship Type in the list.
|
||||||
|
*
|
||||||
|
* @param targetType entity type of target.
|
||||||
|
* @param originType entity type of origin referer.
|
||||||
|
* @param typeName left or right typeName of the respective Relationship.
|
||||||
|
* @return the UUID of the item.
|
||||||
|
*/
|
||||||
|
private void validateTypesByTypeByTypeName(String targetType, String originType, String typeName, String originRow)
|
||||||
|
throws MetadataImportException {
|
||||||
|
try {
|
||||||
|
RelationshipType foundRelationshipType = null;
|
||||||
|
List<RelationshipType> relationshipTypeList = relationshipTypeService.
|
||||||
|
findByLeftwardOrRightwardTypeName(c, typeName.split("\\.")[1]);
|
||||||
|
// Validate described relationship form the CSV.
|
||||||
|
foundRelationshipType = matchRelationshipType(relationshipTypeList, targetType, originType, typeName);
|
||||||
|
if (foundRelationshipType == null) {
|
||||||
|
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||||
|
"No Relationship type found for:\n" +
|
||||||
|
"Target type: " + targetType + "\n" +
|
||||||
|
"Origin referer type: " + originType + "\n" +
|
||||||
|
"with typeName: " + typeName + " for type: " + originType);
|
||||||
|
}
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
throw new MetadataImportException("Error interacting with database!", sqle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches two Entity types to a Relationship Type from a set of Relationship Types.
|
||||||
|
*
|
||||||
|
* @param relTypes set of Relationship Types.
|
||||||
|
* @param targetType entity type of target.
|
||||||
|
* @param originType entity type of origin referer.
|
||||||
|
* @return null or matched Relationship Type.
|
||||||
|
*/
|
||||||
|
private RelationshipType matchRelationshipType(List<RelationshipType> relTypes,
|
||||||
|
String targetType, String originType, String originTypeName) {
|
||||||
|
RelationshipType foundRelationshipType = null;
|
||||||
|
if (originTypeName.split("\\.").length > 1) {
|
||||||
|
originTypeName = originTypeName.split("\\.")[1];
|
||||||
|
}
|
||||||
|
for (RelationshipType relationshipType : relTypes) {
|
||||||
|
// Is origin type leftward or righward
|
||||||
|
boolean isLeft = false;
|
||||||
|
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(originType)) {
|
||||||
|
isLeft = true;
|
||||||
|
}
|
||||||
|
if (isLeft) {
|
||||||
|
// Validate typeName reference
|
||||||
|
if (!relationshipType.getLeftwardType().equalsIgnoreCase(originTypeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(originType) &&
|
||||||
|
relationshipType.getRightType().getLabel().equalsIgnoreCase(targetType)) {
|
||||||
|
foundRelationshipType = relationshipType;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!relationshipType.getRightwardType().equalsIgnoreCase(originTypeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(targetType) &&
|
||||||
|
relationshipType.getRightType().getLabel().equalsIgnoreCase(originType)) {
|
||||||
|
foundRelationshipType = relationshipType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundRelationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -272,9 +272,8 @@ public class Harvest {
|
|||||||
targetCollection = (Collection) dso;
|
targetCollection = (Collection) dso;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not a handle, try and treat it as an integer collection database ID
|
// not a handle, try and treat it as an collection database UUID
|
||||||
System.out.println("Looking up by id: " + collectionID + ", parsed as '" + Integer
|
System.out.println("Looking up by UUID: " + collectionID + ", " + "in context: " + context);
|
||||||
.parseInt(collectionID) + "', " + "in context: " + context);
|
|
||||||
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,7 +459,7 @@ public class Harvest {
|
|||||||
List<String> errors;
|
List<String> errors;
|
||||||
|
|
||||||
System.out.print("Testing basic PMH access: ");
|
System.out.print("Testing basic PMH access: ");
|
||||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||||
(null != metadataFormat) ? metadataFormat : "dc", false);
|
(null != metadataFormat) ? metadataFormat : "dc", false);
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
System.out.println("OK");
|
System.out.println("OK");
|
||||||
@@ -471,7 +470,7 @@ public class Harvest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.out.print("Testing ORE support: ");
|
System.out.print("Testing ORE support: ");
|
||||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||||
(null != metadataFormat) ? metadataFormat : "dc", true);
|
(null != metadataFormat) ? metadataFormat : "dc", true);
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
System.out.println("OK");
|
System.out.println("OK");
|
||||||
|
@@ -42,7 +42,7 @@ import org.dspace.content.Community;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
@@ -214,7 +214,7 @@ public class ItemExportServiceImpl implements ItemExportService {
|
|||||||
protected void writeMetadata(Context c, String schema, Item i,
|
protected void writeMetadata(Context c, String schema, Item i,
|
||||||
File destDir, boolean migrate) throws Exception {
|
File destDir, boolean migrate) throws Exception {
|
||||||
String filename;
|
String filename;
|
||||||
if (schema.equals(MetadataSchema.DC_SCHEMA)) {
|
if (schema.equals(MetadataSchemaEnum.DC.getName())) {
|
||||||
filename = "dublin_core.xml";
|
filename = "dublin_core.xml";
|
||||||
} else {
|
} else {
|
||||||
filename = "metadata_" + schema + ".xml";
|
filename = "metadata_" + schema + ".xml";
|
||||||
|
@@ -74,6 +74,7 @@ import org.dspace.content.DSpaceObject;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.service.BitstreamFormatService;
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
@@ -677,7 +678,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem(
|
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem(
|
||||||
"schema");
|
"schema");
|
||||||
if (schemaAttr == null) {
|
if (schemaAttr == null) {
|
||||||
schema = MetadataSchema.DC_SCHEMA;
|
schema = MetadataSchemaEnum.DC.getName();
|
||||||
} else {
|
} else {
|
||||||
schema = schemaAttr.getNodeValue();
|
schema = schemaAttr.getNodeValue();
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -189,7 +190,7 @@ public class MetadataUtilities {
|
|||||||
NodeList metadata = XPathAPI.selectNodeList(document, "/dublin_core");
|
NodeList metadata = XPathAPI.selectNodeList(document, "/dublin_core");
|
||||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem("schema");
|
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem("schema");
|
||||||
if (schemaAttr == null) {
|
if (schemaAttr == null) {
|
||||||
schema = MetadataSchema.DC_SCHEMA;
|
schema = MetadataSchemaEnum.DC.getName();
|
||||||
} else {
|
} else {
|
||||||
schema = schemaAttr.getNodeValue();
|
schema = schemaAttr.getNodeValue();
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,12 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||||
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||||
import org.dspace.services.RequestService;
|
import org.dspace.services.RequestService;
|
||||||
@@ -27,6 +33,9 @@ import org.jdom.input.SAXBuilder;
|
|||||||
* @author Mark Diggory
|
* @author Mark Diggory
|
||||||
*/
|
*/
|
||||||
public class ScriptLauncher {
|
public class ScriptLauncher {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(ScriptLauncher.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service manager kernel
|
* The service manager kernel
|
||||||
*/
|
*/
|
||||||
@@ -76,8 +85,9 @@ public class ScriptLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look up command in the configuration, and execute.
|
// Look up command in the configuration, and execute.
|
||||||
int status;
|
|
||||||
status = runOneCommand(commandConfigs, args);
|
CommandLineDSpaceRunnableHandler commandLineDSpaceRunnableHandler = new CommandLineDSpaceRunnableHandler();
|
||||||
|
int status = handleScript(args, commandConfigs, commandLineDSpaceRunnableHandler, kernelImpl);
|
||||||
|
|
||||||
// Destroy the service kernel if it is still alive
|
// Destroy the service kernel if it is still alive
|
||||||
if (kernelImpl != null) {
|
if (kernelImpl != null) {
|
||||||
@@ -86,6 +96,50 @@ public class ScriptLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.exit(status);
|
System.exit(status);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will take the arguments from a commandline input and it'll find the script that the first argument
|
||||||
|
* refers to and it'll execute this script.
|
||||||
|
* It can return a 1 or a 0 depending on whether the script failed or passed respectively
|
||||||
|
* @param args The arguments for the script and the script as first one in the array
|
||||||
|
* @param commandConfigs The Document
|
||||||
|
* @param dSpaceRunnableHandler The DSpaceRunnableHandler for this execution
|
||||||
|
* @param kernelImpl The relevant DSpaceKernelImpl
|
||||||
|
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||||
|
*/
|
||||||
|
public static int handleScript(String[] args, Document commandConfigs,
|
||||||
|
DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||||
|
DSpaceKernelImpl kernelImpl) {
|
||||||
|
int status;
|
||||||
|
DSpaceRunnable script = ScriptServiceFactory.getInstance().getScriptService().getScriptForName(args[0]);
|
||||||
|
if (script != null) {
|
||||||
|
status = executeScript(args, dSpaceRunnableHandler, script);
|
||||||
|
} else {
|
||||||
|
status = runOneCommand(commandConfigs, args, kernelImpl);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will simply execute the script
|
||||||
|
* @param args The arguments of the script with the script name as first place in the array
|
||||||
|
* @param dSpaceRunnableHandler The relevant DSpaceRunnableHandler
|
||||||
|
* @param script The script to be executed
|
||||||
|
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||||
|
*/
|
||||||
|
private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||||
|
DSpaceRunnable script) {
|
||||||
|
try {
|
||||||
|
script.initialize(args, dSpaceRunnableHandler);
|
||||||
|
script.run();
|
||||||
|
return 0;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
script.printHelp();
|
||||||
|
e.printStackTrace();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int runOneCommand(Document commandConfigs, String[] args) {
|
protected static int runOneCommand(Document commandConfigs, String[] args) {
|
||||||
@@ -98,7 +152,7 @@ public class ScriptLauncher {
|
|||||||
* @param commandConfigs Document
|
* @param commandConfigs Document
|
||||||
* @param args the command line arguments given
|
* @param args the command line arguments given
|
||||||
*/
|
*/
|
||||||
public static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) {
|
protected static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) {
|
||||||
String request = args[0];
|
String request = args[0];
|
||||||
Element root = commandConfigs.getRootElement();
|
Element root = commandConfigs.getRootElement();
|
||||||
List<Element> commands = root.getChildren("command");
|
List<Element> commands = root.getChildren("command");
|
||||||
|
@@ -11,7 +11,9 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
|
||||||
@@ -26,6 +28,8 @@ import org.dspace.content.Item;
|
|||||||
* @author Jason Sherman jsherman@usao.edu
|
* @author Jason Sherman jsherman@usao.edu
|
||||||
*/
|
*/
|
||||||
public class PDFBoxThumbnail extends MediaFilter implements SelfRegisterInputFormats {
|
public class PDFBoxThumbnail extends MediaFilter implements SelfRegisterInputFormats {
|
||||||
|
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(PDFBoxThumbnail.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFilteredName(String oldFilename) {
|
public String getFilteredName(String oldFilename) {
|
||||||
return oldFilename + ".jpg";
|
return oldFilename + ".jpg";
|
||||||
@@ -65,12 +69,19 @@ public class PDFBoxThumbnail extends MediaFilter implements SelfRegisterInputFor
|
|||||||
@Override
|
@Override
|
||||||
public InputStream getDestinationStream(Item currentItem, InputStream source, boolean verbose)
|
public InputStream getDestinationStream(Item currentItem, InputStream source, boolean verbose)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
PDDocument doc = PDDocument.load(source);
|
BufferedImage buf;
|
||||||
PDFRenderer renderer = new PDFRenderer(doc);
|
|
||||||
BufferedImage buf = renderer.renderImage(0);
|
|
||||||
// ImageIO.write(buf, "PNG", new File("custom-render.png"));
|
|
||||||
doc.close();
|
|
||||||
|
|
||||||
|
// Render the page image.
|
||||||
|
try ( PDDocument doc = PDDocument.load(source); ) {
|
||||||
|
PDFRenderer renderer = new PDFRenderer(doc);
|
||||||
|
buf = renderer.renderImage(0);
|
||||||
|
} catch (InvalidPasswordException ex) {
|
||||||
|
log.error("PDF is encrypted. Cannot create thumbnail (item: {})",
|
||||||
|
() -> currentItem.getHandle());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate thumbnail derivative and return as IO stream.
|
||||||
JPEGFilter jpegFilter = new JPEGFilter();
|
JPEGFilter jpegFilter = new JPEGFilter();
|
||||||
return jpegFilter.getThumb(currentItem, buf, verbose);
|
return jpegFilter.getThumb(currentItem, buf, verbose);
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ import java.io.Writer;
|
|||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
|
||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
@@ -95,6 +96,10 @@ public class PDFFilter extends MediaFilter {
|
|||||||
try {
|
try {
|
||||||
pdfDoc = PDDocument.load(source);
|
pdfDoc = PDDocument.load(source);
|
||||||
pts.writeText(pdfDoc, writer);
|
pts.writeText(pdfDoc, writer);
|
||||||
|
} catch (InvalidPasswordException ex) {
|
||||||
|
log.error("PDF is encrypted. Cannot extract text (item: {})",
|
||||||
|
() -> currentItem.getHandle());
|
||||||
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (pdfDoc != null) {
|
if (pdfDoc != null) {
|
||||||
|
@@ -78,7 +78,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
|||||||
private Date request_date = null;
|
private Date request_date = null;
|
||||||
|
|
||||||
@Column(name = "accept_request")
|
@Column(name = "accept_request")
|
||||||
private Boolean accept_request = null;
|
private boolean accept_request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected constructor, create object using:
|
* Protected constructor, create object using:
|
||||||
@@ -88,6 +88,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
|||||||
protected RequestItem() {
|
protected RequestItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Integer getID() {
|
public Integer getID() {
|
||||||
return requestitem_id;
|
return requestitem_id;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,9 @@ import java.util.List;
|
|||||||
* @author Andrea Bollini
|
* @author Andrea Bollini
|
||||||
*/
|
*/
|
||||||
public class SHERPAPublisher {
|
public class SHERPAPublisher {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private String alias;
|
private String alias;
|
||||||
@@ -49,7 +52,7 @@ public class SHERPAPublisher {
|
|||||||
|
|
||||||
private String dateupdated;
|
private String dateupdated;
|
||||||
|
|
||||||
public SHERPAPublisher(String name, String alias, String homeurl,
|
public SHERPAPublisher(String id, String name, String alias, String homeurl,
|
||||||
String prearchiving, List<String> prerestriction,
|
String prearchiving, List<String> prerestriction,
|
||||||
String postarchiving, List<String> postrestriction,
|
String postarchiving, List<String> postrestriction,
|
||||||
String pubarchiving, List<String> pubrestriction,
|
String pubarchiving, List<String> pubrestriction,
|
||||||
@@ -57,6 +60,8 @@ public class SHERPAPublisher {
|
|||||||
String paidaccessname, String paidaccessnotes,
|
String paidaccessname, String paidaccessnotes,
|
||||||
List<String[]> copyright, String romeocolour, String datedded,
|
List<String[]> copyright, String romeocolour, String datedded,
|
||||||
String dateupdated) {
|
String dateupdated) {
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
@@ -160,4 +165,11 @@ public class SHERPAPublisher {
|
|||||||
return dateupdated;
|
return dateupdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the id
|
||||||
|
* @return the id value of this SHERPAPublisher
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.util.XMLUtils;
|
import org.dspace.app.util.XMLUtils;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
@@ -24,7 +25,9 @@ import org.w3c.dom.Element;
|
|||||||
* @author Andrea Bollini
|
* @author Andrea Bollini
|
||||||
*/
|
*/
|
||||||
public class SHERPAResponse {
|
public class SHERPAResponse {
|
||||||
private boolean error;
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAResponse.class);
|
||||||
|
|
||||||
|
private int numHits;
|
||||||
|
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
@@ -57,12 +60,13 @@ public class SHERPAResponse {
|
|||||||
Element publishersElement = XMLUtils.getSingleElement(xmlRoot,
|
Element publishersElement = XMLUtils.getSingleElement(xmlRoot,
|
||||||
"publishers");
|
"publishers");
|
||||||
|
|
||||||
message = XMLUtils.getElementValue(headersElement, "message");
|
String numhitsString = XMLUtils.getElementValue(headersElement, "numhits");
|
||||||
|
if (StringUtils.isNotBlank(numhitsString)) {
|
||||||
if (StringUtils.isNotBlank(message)) {
|
numHits = Integer.parseInt(numhitsString);
|
||||||
error = true;
|
} else {
|
||||||
return;
|
numHits = 0;
|
||||||
}
|
}
|
||||||
|
message = XMLUtils.getElementValue(headersElement, "message");
|
||||||
|
|
||||||
license = XMLUtils.getElementValue(headersElement, "license");
|
license = XMLUtils.getElementValue(headersElement, "license");
|
||||||
licenseURL = XMLUtils.getElementValue(headersElement, "licenseurl");
|
licenseURL = XMLUtils.getElementValue(headersElement, "licenseurl");
|
||||||
@@ -112,9 +116,8 @@ public class SHERPAResponse {
|
|||||||
|
|
||||||
Element copyrightlinksElement = XMLUtils.getSingleElement(
|
Element copyrightlinksElement = XMLUtils.getSingleElement(
|
||||||
publisherElement, "copyrightlinks");
|
publisherElement, "copyrightlinks");
|
||||||
|
|
||||||
publishers
|
publishers
|
||||||
.add(new SHERPAPublisher(XMLUtils.getElementValue(
|
.add(new SHERPAPublisher(publisherElement.getAttribute("id"), XMLUtils.getElementValue(
|
||||||
publisherElement, "name"),
|
publisherElement, "name"),
|
||||||
XMLUtils.getElementValue(publisherElement,
|
XMLUtils.getElementValue(publisherElement,
|
||||||
"alias"), XMLUtils.getElementValue(
|
"alias"), XMLUtils.getElementValue(
|
||||||
@@ -162,17 +165,12 @@ public class SHERPAResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
error = true;
|
log.error("Error parsing SHERPA API Response", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SHERPAResponse(String message) {
|
public SHERPAResponse(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.error = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isError() {
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
@@ -198,4 +196,8 @@ public class SHERPAResponse {
|
|||||||
public List<SHERPAPublisher> getPublishers() {
|
public List<SHERPAPublisher> getPublishers() {
|
||||||
return publishers;
|
return publishers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNumHits() {
|
||||||
|
return numHits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -763,9 +763,10 @@ public class ReportGenerator {
|
|||||||
// build the referece
|
// build the referece
|
||||||
// FIXME: here we have blurred the line between content and presentation
|
// FIXME: here we have blurred the line between content and presentation
|
||||||
// and it should probably be un-blurred
|
// and it should probably be un-blurred
|
||||||
List<MetadataValue> title = itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
List<MetadataValue> title = itemService.getMetadata(item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null, Item.ANY);
|
||||||
List<MetadataValue> author = itemService
|
List<MetadataValue> author = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "contributor", "author", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "contributor", "author", Item.ANY);
|
||||||
|
|
||||||
StringBuffer authors = new StringBuffer();
|
StringBuffer authors = new StringBuffer();
|
||||||
if (author.size() > 0) {
|
if (author.size() > 0) {
|
||||||
|
@@ -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.app.util;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||||
|
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||||
|
import org.dspace.services.CachingService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all EhCache CacheManager and Cache instances.
|
||||||
|
*
|
||||||
|
* <p>This is a debugging tool, not used in the daily operation of DSpace.
|
||||||
|
* Just run it from the installed instance using
|
||||||
|
* {@code bin/dspace dsrun org.dspace.app.util.CacheSnooper}
|
||||||
|
* to check that the cache configuration is what you expect it to be,
|
||||||
|
* given your configuration.
|
||||||
|
*
|
||||||
|
* <p>This was created to prove a specific cache configuration patch,
|
||||||
|
* but I leave it here in the hope that it may be useful to others.
|
||||||
|
*
|
||||||
|
* @author Mark H. Wood <mwood@iupui.edu>
|
||||||
|
*/
|
||||||
|
public class CacheSnooper {
|
||||||
|
private CacheSnooper() { }
|
||||||
|
|
||||||
|
public static void main(String[] argv) {
|
||||||
|
// Ensure that the DSpace kernel is started.
|
||||||
|
DSpaceKernelImpl kernel = DSpaceKernelInit.getKernel(null);
|
||||||
|
|
||||||
|
// Ensure that the services cache manager is started.
|
||||||
|
CachingService serviceCaches = kernel.getServiceManager()
|
||||||
|
.getServiceByName(null, CachingService.class);
|
||||||
|
|
||||||
|
// Ensure that the database layer is started.
|
||||||
|
Context ctx = new Context();
|
||||||
|
|
||||||
|
// List those caches!
|
||||||
|
for (CacheManager manager : CacheManager.ALL_CACHE_MANAGERS) {
|
||||||
|
System.out.format("CacheManager: %s%n", manager);
|
||||||
|
for (String cacheName : manager.getCacheNames()) {
|
||||||
|
Cache cache = manager.getCache(cacheName);
|
||||||
|
System.out.format(" Cache: '%s'; maxHeap: %d; maxDisk: %d%n",
|
||||||
|
cacheName,
|
||||||
|
cache.getCacheConfiguration().getMaxEntriesLocalHeap(),
|
||||||
|
cache.getCacheConfiguration().getMaxEntriesLocalDisk());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -14,7 +14,7 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.regex.PatternSyntaxException;
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.core.Utils;
|
import org.dspace.core.Utils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -89,6 +89,11 @@ public class DCInput {
|
|||||||
*/
|
*/
|
||||||
private boolean repeatable = false;
|
private boolean repeatable = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* should name-variants be used?
|
||||||
|
*/
|
||||||
|
private boolean nameVariants = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'hint' text to display
|
* 'hint' text to display
|
||||||
*/
|
*/
|
||||||
@@ -134,6 +139,12 @@ public class DCInput {
|
|||||||
*/
|
*/
|
||||||
private List<String> typeBind = null;
|
private List<String> typeBind = null;
|
||||||
|
|
||||||
|
private boolean isRelationshipField = false;
|
||||||
|
private boolean isMetadataField = false;
|
||||||
|
private String relationshipType = null;
|
||||||
|
private String searchConfiguration = null;
|
||||||
|
private String filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scope of the input sets, this restricts hidden metadata fields from
|
* The scope of the input sets, this restricts hidden metadata fields from
|
||||||
* view during workflow processing.
|
* view during workflow processing.
|
||||||
@@ -160,7 +171,7 @@ public class DCInput {
|
|||||||
// Default the schema to dublin core
|
// Default the schema to dublin core
|
||||||
dcSchema = fieldMap.get("dc-schema");
|
dcSchema = fieldMap.get("dc-schema");
|
||||||
if (dcSchema == null) {
|
if (dcSchema == null) {
|
||||||
dcSchema = MetadataSchema.DC_SCHEMA;
|
dcSchema = MetadataSchemaEnum.DC.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the input have a language tag
|
//check if the input have a language tag
|
||||||
@@ -177,6 +188,9 @@ public class DCInput {
|
|||||||
String repStr = fieldMap.get("repeatable");
|
String repStr = fieldMap.get("repeatable");
|
||||||
repeatable = "true".equalsIgnoreCase(repStr)
|
repeatable = "true".equalsIgnoreCase(repStr)
|
||||||
|| "yes".equalsIgnoreCase(repStr);
|
|| "yes".equalsIgnoreCase(repStr);
|
||||||
|
String nameVariantsString = fieldMap.get("name-variants");
|
||||||
|
nameVariants = (StringUtils.isNotBlank(nameVariantsString)) ?
|
||||||
|
nameVariantsString.equalsIgnoreCase("true") : false;
|
||||||
label = fieldMap.get("label");
|
label = fieldMap.get("label");
|
||||||
inputType = fieldMap.get("input-type");
|
inputType = fieldMap.get("input-type");
|
||||||
// these types are list-controlled
|
// these types are list-controlled
|
||||||
@@ -206,6 +220,11 @@ public class DCInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
style = fieldMap.get("style");
|
style = fieldMap.get("style");
|
||||||
|
isRelationshipField = fieldMap.containsKey("relationship-type");
|
||||||
|
isMetadataField = fieldMap.containsKey("dc-schema");
|
||||||
|
relationshipType = fieldMap.get("relationship-type");
|
||||||
|
searchConfiguration = fieldMap.get("search-configuration");
|
||||||
|
filter = fieldMap.get("filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,6 +277,15 @@ public class DCInput {
|
|||||||
return isRepeatable();
|
return isRepeatable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the nameVariants flag for this row
|
||||||
|
*
|
||||||
|
* @return the nameVariants flag
|
||||||
|
*/
|
||||||
|
public boolean areNameVariantsAllowed() {
|
||||||
|
return nameVariants;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the input type for this row
|
* Get the input type for this row
|
||||||
*
|
*
|
||||||
@@ -481,6 +509,18 @@ public class DCInput {
|
|||||||
return Utils.standardize(this.getSchema(), this.getElement(), this.getQualifier(), ".");
|
return Utils.standardize(this.getSchema(), this.getElement(), this.getQualifier(), ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRelationshipType() {
|
||||||
|
return relationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchConfiguration() {
|
||||||
|
return searchConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isQualdropValue() {
|
public boolean isQualdropValue() {
|
||||||
if ("qualdrop_value".equals(getInputType())) {
|
if ("qualdrop_value".equals(getInputType())) {
|
||||||
return true;
|
return true;
|
||||||
@@ -505,4 +545,22 @@ public class DCInput {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the current field contains an entity relationship
|
||||||
|
* This also implies a relationship type is defined for this field
|
||||||
|
* The field can contain both an entity relationship and a metadata field simultaneously
|
||||||
|
*/
|
||||||
|
public boolean isRelationshipField() {
|
||||||
|
return isRelationshipField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the current field contains a metadata field
|
||||||
|
* This also implies a field type is defined for this field
|
||||||
|
* The field can contain both an entity relationship and a metadata field simultaneously
|
||||||
|
*/
|
||||||
|
public boolean isMetadataField() {
|
||||||
|
return isMetadataField;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ import javax.xml.parsers.FactoryConfigurationError;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.core.Utils;
|
import org.dspace.core.Utils;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
@@ -366,11 +366,15 @@ public class DCInputsReader {
|
|||||||
metadataField += "." + qualifier;
|
metadataField += "." + qualifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we omit the duplicate validation, allowing multiple
|
// we omit the duplicate validation, allowing multiple
|
||||||
// fields definition for
|
// fields definition for
|
||||||
// the same metadata and different visibility/type-bind
|
// the same metadata and different visibility/type-bind
|
||||||
|
} else if (StringUtils.equalsIgnoreCase(npg.getNodeName(), "relation-field")) {
|
||||||
|
Map<String, String> relationField = new HashMap<>();
|
||||||
|
processField(formName, npg, relationField);
|
||||||
|
fields.add(relationField);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// sanity check number of fields
|
// sanity check number of fields
|
||||||
if (fields.size() < 1) {
|
if (fields.size() < 1) {
|
||||||
@@ -396,19 +400,7 @@ public class DCInputsReader {
|
|||||||
String value = getValue(nd);
|
String value = getValue(nd);
|
||||||
field.put(tagName, value);
|
field.put(tagName, value);
|
||||||
if (tagName.equals("input-type")) {
|
if (tagName.equals("input-type")) {
|
||||||
if (value.equals("dropdown")
|
handleInputTypeTagName(formName, field, nd, value);
|
||||||
|| value.equals("qualdrop_value")
|
|
||||||
|| value.equals("list")) {
|
|
||||||
String pairTypeName = getAttribute(nd, PAIR_TYPE_NAME);
|
|
||||||
if (pairTypeName == null) {
|
|
||||||
throw new SAXException("Form " + formName + ", field " +
|
|
||||||
field.get("dc-element") +
|
|
||||||
"." + field.get("dc-qualifier") +
|
|
||||||
" has no name attribute");
|
|
||||||
} else {
|
|
||||||
field.put(PAIR_TYPE_NAME, pairTypeName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (tagName.equals("vocabulary")) {
|
} else if (tagName.equals("vocabulary")) {
|
||||||
String closedVocabularyString = getAttribute(nd, "closed");
|
String closedVocabularyString = getAttribute(nd, "closed");
|
||||||
field.put("closedVocabulary", closedVocabularyString);
|
field.put("closedVocabulary", closedVocabularyString);
|
||||||
@@ -424,17 +416,30 @@ public class DCInputsReader {
|
|||||||
field.put(PAIR_TYPE_NAME, pairTypeName);
|
field.put(PAIR_TYPE_NAME, pairTypeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (StringUtils.equalsIgnoreCase(tagName, "linked-metadata-field")) {
|
||||||
|
for (int j = 0; j < nd.getChildNodes().getLength(); j ++) {
|
||||||
|
Node nestedNode = nd.getChildNodes().item(j);
|
||||||
|
String nestedTagName = nestedNode.getNodeName();
|
||||||
|
String nestedValue = getValue(nestedNode);
|
||||||
|
field.put(nestedTagName, nestedValue);
|
||||||
|
if (nestedTagName.equals("input-type")) {
|
||||||
|
handleInputTypeTagName(formName, field, nestedNode, nestedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String missing = null;
|
String missing = null;
|
||||||
if (field.get("dc-element") == null) {
|
String nodeName = n.getNodeName();
|
||||||
|
if (field.get("dc-element") == null &&
|
||||||
|
(nodeName.equals("field") || field.containsKey("linked-metadata-field"))) {
|
||||||
missing = "dc-element";
|
missing = "dc-element";
|
||||||
}
|
}
|
||||||
if (field.get("label") == null) {
|
if (field.get("label") == null) {
|
||||||
missing = "label";
|
missing = "label";
|
||||||
}
|
}
|
||||||
if (field.get("input-type") == null) {
|
if (field.get("input-type") == null &&
|
||||||
|
(nodeName.equals("field") || field.containsKey("linked-metadata-field"))) {
|
||||||
missing = "input-type";
|
missing = "input-type";
|
||||||
}
|
}
|
||||||
if (missing != null) {
|
if (missing != null) {
|
||||||
@@ -442,7 +447,7 @@ public class DCInputsReader {
|
|||||||
throw new SAXException(msg);
|
throw new SAXException(msg);
|
||||||
}
|
}
|
||||||
String type = field.get("input-type");
|
String type = field.get("input-type");
|
||||||
if (type.equals("twobox") || type.equals("qualdrop_value")) {
|
if (StringUtils.isNotBlank(type) && (type.equals("twobox") || type.equals("qualdrop_value"))) {
|
||||||
String rpt = field.get("repeatable");
|
String rpt = field.get("repeatable");
|
||||||
if ((rpt == null) ||
|
if ((rpt == null) ||
|
||||||
((!rpt.equalsIgnoreCase("yes")) &&
|
((!rpt.equalsIgnoreCase("yes")) &&
|
||||||
@@ -453,6 +458,23 @@ public class DCInputsReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleInputTypeTagName(String formName, Map<String, String> field, Node nd, String value)
|
||||||
|
throws SAXException {
|
||||||
|
if (value.equals("dropdown")
|
||||||
|
|| value.equals("qualdrop_value")
|
||||||
|
|| value.equals("list")) {
|
||||||
|
String pairTypeName = getAttribute(nd, PAIR_TYPE_NAME);
|
||||||
|
if (pairTypeName == null) {
|
||||||
|
throw new SAXException("Form " + formName + ", field " +
|
||||||
|
field.get("dc-element") +
|
||||||
|
"." + field.get("dc-qualifier") +
|
||||||
|
" has no name attribute");
|
||||||
|
} else {
|
||||||
|
field.put(PAIR_TYPE_NAME, pairTypeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that this is the only field with the name dc-element.dc-qualifier
|
* Check that this is the only field with the name dc-element.dc-qualifier
|
||||||
* If there is a duplicate, return an error message, else return null;
|
* If there is a duplicate, return an error message, else return null;
|
||||||
@@ -464,7 +486,7 @@ public class DCInputsReader {
|
|||||||
String elem = field.get("dc-element");
|
String elem = field.get("dc-element");
|
||||||
String qual = field.get("dc-qualifier");
|
String qual = field.get("dc-qualifier");
|
||||||
if ((schema == null) || (schema.equals(""))) {
|
if ((schema == null) || (schema.equals(""))) {
|
||||||
schema = MetadataSchema.DC_SCHEMA;
|
schema = MetadataSchemaEnum.DC.getName();
|
||||||
}
|
}
|
||||||
String schemaTest;
|
String schemaTest;
|
||||||
|
|
||||||
@@ -474,7 +496,7 @@ public class DCInputsReader {
|
|||||||
Map<String, String> fld = pg.get(j);
|
Map<String, String> fld = pg.get(j);
|
||||||
if ((fld.get("dc-schema") == null) ||
|
if ((fld.get("dc-schema") == null) ||
|
||||||
((fld.get("dc-schema")).equals(""))) {
|
((fld.get("dc-schema")).equals(""))) {
|
||||||
schemaTest = MetadataSchema.DC_SCHEMA;
|
schemaTest = MetadataSchemaEnum.DC.getName();
|
||||||
} else {
|
} else {
|
||||||
schemaTest = fld.get("dc-schema");
|
schemaTest = fld.get("dc-schema");
|
||||||
}
|
}
|
||||||
@@ -584,9 +606,9 @@ public class DCInputsReader {
|
|||||||
Map<String, String> fld = fields.get(i);
|
Map<String, String> fld = fields.get(i);
|
||||||
// verify reference in certain input types
|
// verify reference in certain input types
|
||||||
String type = fld.get("input-type");
|
String type = fld.get("input-type");
|
||||||
if (type.equals("dropdown")
|
if (StringUtils.isNotBlank(type) && (type.equals("dropdown")
|
||||||
|| type.equals("qualdrop_value")
|
|| type.equals("qualdrop_value")
|
||||||
|| type.equals("list")) {
|
|| type.equals("list"))) {
|
||||||
String pairsName = fld.get(PAIR_TYPE_NAME);
|
String pairsName = fld.get(PAIR_TYPE_NAME);
|
||||||
List<String> v = valuePairs.get(pairsName);
|
List<String> v = valuePairs.get(pairsName);
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
|
@@ -0,0 +1,227 @@
|
|||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.cli.PosixParser;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.EntityType;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script is used to initialize the database with a set of relationshiptypes that are written
|
||||||
|
* in an xml file that is given to this script.
|
||||||
|
* This XML file needs to have a proper XML structure and needs to define the variables of the RelationshipType object
|
||||||
|
*/
|
||||||
|
public class InitializeEntities {
|
||||||
|
|
||||||
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
|
private RelationshipTypeService relationshipTypeService;
|
||||||
|
private RelationshipService relationshipService;
|
||||||
|
private EntityTypeService entityTypeService;
|
||||||
|
|
||||||
|
|
||||||
|
private InitializeEntities() {
|
||||||
|
relationshipTypeService = ContentServiceFactory.getInstance().getRelationshipTypeService();
|
||||||
|
relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||||
|
entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main method for this script
|
||||||
|
*
|
||||||
|
* @param argv The commandline arguments given with this command
|
||||||
|
* @throws SQLException If something goes wrong with the database
|
||||||
|
* @throws AuthorizeException If something goes wrong with permissions
|
||||||
|
* @throws ParseException If something goes wrong with the parsing
|
||||||
|
*/
|
||||||
|
public static void main(String[] argv) throws SQLException, AuthorizeException, ParseException {
|
||||||
|
InitializeEntities initializeEntities = new InitializeEntities();
|
||||||
|
CommandLineParser parser = new PosixParser();
|
||||||
|
Options options = createCommandLineOptions();
|
||||||
|
CommandLine line = parser.parse(options,argv);
|
||||||
|
String fileLocation = getFileLocationFromCommandLine(line);
|
||||||
|
checkHelpEntered(options, line);
|
||||||
|
initializeEntities.run(fileLocation);
|
||||||
|
}
|
||||||
|
private static void checkHelpEntered(Options options, CommandLine line) {
|
||||||
|
if (line.hasOption("h")) {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("Intialize Entities", options);
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static String getFileLocationFromCommandLine(CommandLine line) {
|
||||||
|
String query = line.getOptionValue("f");
|
||||||
|
if (StringUtils.isEmpty(query)) {
|
||||||
|
System.out.println("No file location was entered");
|
||||||
|
log.info("No file location was entered");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Options createCommandLineOptions() {
|
||||||
|
Options options = new Options();
|
||||||
|
options.addOption("f", "file", true, "the location for the file containing the xml data");
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void run(String fileLocation) throws SQLException, AuthorizeException {
|
||||||
|
Context context = new Context();
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
this.parseXMLToRelations(context, fileLocation);
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseXMLToRelations(Context context, String fileLocation) throws AuthorizeException {
|
||||||
|
try {
|
||||||
|
File fXmlFile = new File(fileLocation);
|
||||||
|
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder dBuilder = null;
|
||||||
|
dBuilder = dbFactory.newDocumentBuilder();
|
||||||
|
Document doc = dBuilder.parse(fXmlFile);
|
||||||
|
|
||||||
|
doc.getDocumentElement().normalize();
|
||||||
|
|
||||||
|
NodeList nList = doc.getElementsByTagName("type");
|
||||||
|
List<RelationshipType> relationshipTypes = new LinkedList<>();
|
||||||
|
for (int i = 0; i < nList.getLength(); i++) {
|
||||||
|
Node nNode = nList.item(i);
|
||||||
|
|
||||||
|
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
|
||||||
|
Element eElement = (Element) nNode;
|
||||||
|
|
||||||
|
String leftType = eElement.getElementsByTagName("leftType").item(0).getTextContent();
|
||||||
|
String rightType = eElement.getElementsByTagName("rightType").item(0).getTextContent();
|
||||||
|
String leftwardType = eElement.getElementsByTagName("leftwardType").item(0).getTextContent();
|
||||||
|
String rightwardType = eElement.getElementsByTagName("rightwardType").item(0).getTextContent();
|
||||||
|
|
||||||
|
|
||||||
|
NodeList leftCardinalityList = eElement.getElementsByTagName("leftCardinality");
|
||||||
|
NodeList rightCardinalityList = eElement.getElementsByTagName("rightCardinality");
|
||||||
|
|
||||||
|
String leftCardinalityMin = "";
|
||||||
|
String leftCardinalityMax = "";
|
||||||
|
|
||||||
|
String rightCardinalityMin = "";
|
||||||
|
String rightCardinalityMax = "";
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
}
|
||||||
|
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
||||||
|
leftCardinalityMin, leftCardinalityMax,
|
||||||
|
rightCardinalityMin, rightCardinalityMax);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ParserConfigurationException | SAXException | IOException | SQLException e) {
|
||||||
|
log.error("An error occurred while parsing the XML file to relations", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getString(String leftCardinalityMin,Element node, String minOrMax) {
|
||||||
|
if (node.getElementsByTagName(minOrMax).getLength() > 0) {
|
||||||
|
leftCardinalityMin = node.getElementsByTagName(minOrMax).item(0).getTextContent();
|
||||||
|
}
|
||||||
|
return leftCardinalityMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
||||||
|
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||||
|
String rightCardinalityMin, String rightCardinalityMax)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
EntityType leftEntityType = entityTypeService.findByEntityType(context,leftType);
|
||||||
|
if (leftEntityType == null) {
|
||||||
|
leftEntityType = entityTypeService.create(context, leftType);
|
||||||
|
}
|
||||||
|
EntityType rightEntityType = entityTypeService.findByEntityType(context, rightType);
|
||||||
|
if (rightEntityType == null) {
|
||||||
|
rightEntityType = entityTypeService.create(context, rightType);
|
||||||
|
}
|
||||||
|
Integer leftCardinalityMinInteger;
|
||||||
|
Integer leftCardinalityMaxInteger;
|
||||||
|
Integer rightCardinalityMinInteger;
|
||||||
|
Integer rightCardinalityMaxInteger;
|
||||||
|
if (StringUtils.isNotBlank(leftCardinalityMin)) {
|
||||||
|
leftCardinalityMinInteger = Integer.parseInt(leftCardinalityMin);
|
||||||
|
} else {
|
||||||
|
leftCardinalityMinInteger = null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(leftCardinalityMax)) {
|
||||||
|
leftCardinalityMaxInteger = Integer.parseInt(leftCardinalityMax);
|
||||||
|
} else {
|
||||||
|
leftCardinalityMaxInteger = null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(rightCardinalityMin)) {
|
||||||
|
rightCardinalityMinInteger = Integer.parseInt(rightCardinalityMin);
|
||||||
|
} else {
|
||||||
|
rightCardinalityMinInteger = null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(rightCardinalityMax)) {
|
||||||
|
rightCardinalityMaxInteger = Integer.parseInt(rightCardinalityMax);
|
||||||
|
} else {
|
||||||
|
rightCardinalityMaxInteger = null;
|
||||||
|
}
|
||||||
|
RelationshipType relationshipType = relationshipTypeService
|
||||||
|
.findbyTypesAndTypeName(context, leftEntityType, rightEntityType, leftwardType, rightwardType);
|
||||||
|
if (relationshipType == null) {
|
||||||
|
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftwardType, rightwardType,
|
||||||
|
leftCardinalityMinInteger, leftCardinalityMaxInteger,
|
||||||
|
rightCardinalityMinInteger, rightCardinalityMaxInteger);
|
||||||
|
} else {
|
||||||
|
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
||||||
|
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
||||||
|
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
||||||
|
relationshipType.setRightMaxCardinality(rightCardinalityMaxInteger);
|
||||||
|
relationshipTypeService.update(context, relationshipType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -13,6 +13,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.solr.client.solrj.SolrClient;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.SolrServerException;
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||||
@@ -39,9 +40,9 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
|||||||
/**
|
/**
|
||||||
* Non-Static CommonsHttpSolrServer for processing indexing events.
|
* Non-Static CommonsHttpSolrServer for processing indexing events.
|
||||||
*/
|
*/
|
||||||
protected HttpSolrClient solr = null;
|
protected SolrClient solr = null;
|
||||||
|
|
||||||
protected HttpSolrClient getSolr()
|
protected SolrClient getSolr()
|
||||||
throws MalformedURLException, SolrServerException, IOException {
|
throws MalformedURLException, SolrServerException, IOException {
|
||||||
if (solr == null) {
|
if (solr == null) {
|
||||||
|
|
||||||
@@ -49,12 +50,14 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
|||||||
|
|
||||||
log.debug("Solr authority URL: " + solrService);
|
log.debug("Solr authority URL: " + solrService);
|
||||||
|
|
||||||
solr = new HttpSolrClient.Builder(solrService).build();
|
HttpSolrClient solrServer = new HttpSolrClient.Builder(solrService).build();
|
||||||
solr.setBaseURL(solrService);
|
solrServer.setBaseURL(solrService);
|
||||||
|
|
||||||
SolrQuery solrQuery = new SolrQuery().setQuery("*:*");
|
SolrQuery solrQuery = new SolrQuery().setQuery("*:*");
|
||||||
|
|
||||||
solr.query(solrQuery);
|
solrServer.query(solrQuery);
|
||||||
|
|
||||||
|
solr = solrServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return solr;
|
return solr;
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
package org.dspace.authority;
|
package org.dspace.authority;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -23,6 +24,7 @@ import org.dspace.content.Item;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.util.SolrUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
import org.joda.time.format.ISODateTimeFormat;
|
||||||
@@ -34,8 +36,6 @@ import org.joda.time.format.ISODateTimeFormat;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class AuthorityValue {
|
public class AuthorityValue {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the record in solr
|
* The id of the record in solr
|
||||||
*/
|
*/
|
||||||
@@ -150,12 +150,13 @@ public class AuthorityValue {
|
|||||||
public SolrInputDocument getSolrInputDocument() {
|
public SolrInputDocument getSolrInputDocument() {
|
||||||
|
|
||||||
SolrInputDocument doc = new SolrInputDocument();
|
SolrInputDocument doc = new SolrInputDocument();
|
||||||
|
DateFormat solrDateFormatter = SolrUtils.getDateFormatter();
|
||||||
doc.addField("id", getId());
|
doc.addField("id", getId());
|
||||||
doc.addField("field", getField());
|
doc.addField("field", getField());
|
||||||
doc.addField("value", getValue());
|
doc.addField("value", getValue());
|
||||||
doc.addField("deleted", isDeleted());
|
doc.addField("deleted", isDeleted());
|
||||||
doc.addField("creation_date", getCreationDate());
|
doc.addField("creation_date", solrDateFormatter.format(getCreationDate()));
|
||||||
doc.addField("last_modified_date", getLastModified());
|
doc.addField("last_modified_date", solrDateFormatter.format(getLastModified()));
|
||||||
doc.addField("authority_type", getAuthorityType());
|
doc.addField("authority_type", getAuthorityType());
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
@@ -196,12 +197,12 @@ public class AuthorityValue {
|
|||||||
* @return map
|
* @return map
|
||||||
*/
|
*/
|
||||||
public Map<String, String> choiceSelectMap() {
|
public Map<String, String> choiceSelectMap() {
|
||||||
return new HashMap<String, String>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<DateTimeFormatter> getDateFormatters() {
|
public List<DateTimeFormatter> getDateFormatters() {
|
||||||
List<DateTimeFormatter> list = new ArrayList<DateTimeFormatter>();
|
List<DateTimeFormatter> list = new ArrayList<>();
|
||||||
list.add(ISODateTimeFormat.dateTime());
|
list.add(ISODateTimeFormat.dateTime());
|
||||||
list.add(ISODateTimeFormat.dateTimeNoMillis());
|
list.add(ISODateTimeFormat.dateTimeNoMillis());
|
||||||
return list;
|
return list;
|
||||||
|
@@ -35,6 +35,7 @@ public abstract class AuthorityServiceFactory {
|
|||||||
|
|
||||||
public abstract AuthorityService getAuthorityService();
|
public abstract AuthorityService getAuthorityService();
|
||||||
|
|
||||||
|
|
||||||
public abstract List<AuthorityIndexerInterface> getAuthorityIndexers();
|
public abstract List<AuthorityIndexerInterface> getAuthorityIndexers();
|
||||||
|
|
||||||
public static AuthorityServiceFactory getInstance() {
|
public static AuthorityServiceFactory getInstance() {
|
||||||
|
@@ -1,191 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.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.List;
|
|
||||||
|
|
||||||
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.authority.AuthorityValue;
|
|
||||||
import org.dspace.authority.SolrAuthorityInterface;
|
|
||||||
import org.dspace.authority.orcid.xml.XMLtoBio;
|
|
||||||
import org.dspace.authority.rest.RESTConnector;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.orcid.jaxb.model.record_v2.Person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Jonas Van Goolen (jonas at atmire dot com)
|
|
||||||
* This class contains all methods for retrieving "Person" objects calling the ORCID (version 2) endpoints.
|
|
||||||
* Additionally, this can also create AuthorityValues based on these returned Person objects
|
|
||||||
*/
|
|
||||||
public class Orcidv2 implements SolrAuthorityInterface {
|
|
||||||
|
|
||||||
private static Logger log = LogManager.getLogger(Orcidv2.class);
|
|
||||||
|
|
||||||
public RESTConnector restConnector;
|
|
||||||
private String OAUTHUrl;
|
|
||||||
private String clientId;
|
|
||||||
|
|
||||||
private String clientSecret;
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the accessToken that is required for all subsequent calls to ORCID.
|
|
||||||
*
|
|
||||||
* @throws java.io.IOException passed through from HTTPclient.
|
|
||||||
*/
|
|
||||||
public void init() throws IOException {
|
|
||||||
if (StringUtils.isNotBlank(accessToken) && StringUtils.isNotBlank(clientSecret)) {
|
|
||||||
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");
|
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
|
||||||
HttpResponse getResponse = httpClient.execute(httpPost);
|
|
||||||
|
|
||||||
InputStream is = getResponse.getEntity().getContent();
|
|
||||||
BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
|
||||||
|
|
||||||
JSONObject responseObject = null;
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes an instance of the Orcidv2 class based on the provided parameters.
|
|
||||||
* This constructor is called through the spring bean initialization
|
|
||||||
*/
|
|
||||||
private Orcidv2(String url, String OAUTHUrl, String clientId, String clientSecret) {
|
|
||||||
this.restConnector = new RESTConnector(url);
|
|
||||||
this.OAUTHUrl = OAUTHUrl;
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.clientSecret = clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes an instance of the Orcidv2 class based on the provided parameters.
|
|
||||||
* This constructor is called through the spring bean initialization
|
|
||||||
*/
|
|
||||||
private Orcidv2(String url) {
|
|
||||||
this.restConnector = new RESTConnector(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes an instance of the AuthorityValue with the given information.
|
|
||||||
* @param text search string
|
|
||||||
* @return List<AuthorityValue>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AuthorityValue> queryAuthorities(String text, int max) {
|
|
||||||
List<Person> bios = queryBio(text, max);
|
|
||||||
List<AuthorityValue> result = new ArrayList<>();
|
|
||||||
for (Person person : bios) {
|
|
||||||
AuthorityValue orcidAuthorityValue = Orcidv2AuthorityValue.create(person);
|
|
||||||
if (orcidAuthorityValue != null) {
|
|
||||||
result.add(orcidAuthorityValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an AuthorityValue from a Person retrieved using the given orcid identifier.
|
|
||||||
* @param id orcid identifier
|
|
||||||
* @return AuthorityValue
|
|
||||||
*/
|
|
||||||
public AuthorityValue queryAuthorityID(String id) {
|
|
||||||
Person person = getBio(id);
|
|
||||||
AuthorityValue valueFromPerson = Orcidv2AuthorityValue.create(person);
|
|
||||||
return valueFromPerson;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a Person object based on a given orcid identifier
|
|
||||||
* @param id orcid identifier
|
|
||||||
* @return Person
|
|
||||||
*/
|
|
||||||
public Person getBio(String id) {
|
|
||||||
log.debug("getBio called with ID=" + id);
|
|
||||||
if (!isValid(id)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
InputStream bioDocument = restConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
|
||||||
XMLtoBio converter = new XMLtoBio();
|
|
||||||
Person person = converter.convertSinglePerson(bioDocument);
|
|
||||||
return person;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a list of Person objects.
|
|
||||||
* @param text search string
|
|
||||||
* @param start offset to use
|
|
||||||
* @param rows how many rows to return
|
|
||||||
* @return List<Person>
|
|
||||||
*/
|
|
||||||
public List<Person> queryBio(String text, int start, int rows) {
|
|
||||||
if (rows > 100) {
|
|
||||||
throw new IllegalArgumentException("The maximum number of results to retrieve cannot exceed 100.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String searchPath = "search?q=" + URLEncoder.encode(text) + "&start=" + start + "&rows=" + rows;
|
|
||||||
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
|
||||||
InputStream bioDocument = restConnector.get(searchPath, accessToken);
|
|
||||||
XMLtoBio converter = new XMLtoBio();
|
|
||||||
List<Person> bios = converter.convert(bioDocument);
|
|
||||||
return bios;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a list of Person objects.
|
|
||||||
* @param text search string
|
|
||||||
* @param max how many rows to return
|
|
||||||
* @return List<Person>
|
|
||||||
*/
|
|
||||||
public List<Person> queryBio(String text, int max) {
|
|
||||||
return queryBio(text, 0, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check to see if the provided text has the correct ORCID syntax.
|
|
||||||
* Since only searching on ORCID id is allowed, this way, we filter out any queries that would return a
|
|
||||||
* blank result anyway
|
|
||||||
*/
|
|
||||||
private boolean isValid(String text) {
|
|
||||||
return StringUtils.isNotBlank(text) && text.matches(Orcidv2AuthorityValue.ORCID_ID_SYNTAX);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,342 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.authority.orcid;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
|
||||||
import org.dspace.authority.AuthorityValue;
|
|
||||||
import org.dspace.authority.AuthorityValueServiceImpl;
|
|
||||||
import org.dspace.authority.PersonAuthorityValue;
|
|
||||||
import org.dspace.utils.DSpace;
|
|
||||||
import org.orcid.jaxb.model.common_v2.ExternalId;
|
|
||||||
import org.orcid.jaxb.model.record_v2.ExternalIdentifiers;
|
|
||||||
import org.orcid.jaxb.model.record_v2.KeywordType;
|
|
||||||
import org.orcid.jaxb.model.record_v2.NameType;
|
|
||||||
import org.orcid.jaxb.model.record_v2.Person;
|
|
||||||
import org.orcid.jaxb.model.record_v2.ResearcherUrlType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Jonas Van Goolen (jonas at atmire dot com)
|
|
||||||
*/
|
|
||||||
public class Orcidv2AuthorityValue extends PersonAuthorityValue {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The ORCID identifier
|
|
||||||
*/
|
|
||||||
private String orcid_id;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map containing key-value pairs filled in by "setValues(Person person)".
|
|
||||||
* This represents all dynamic information of the object.
|
|
||||||
*/
|
|
||||||
private Map<String, List<String>> otherMetadata = new HashMap<String, List<String>>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The syntax that the ORCID id needs to conform to
|
|
||||||
*/
|
|
||||||
public static final String ORCID_ID_SYNTAX = "\\d{4}-\\d{4}-\\d{4}-(\\d{3}X|\\d{4})";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of Orcidv2AuthorityValue with only uninitialized fields.
|
|
||||||
* This is meant to be filled in with values from an existing record.
|
|
||||||
* To create a brand new Orcidv2AuthorityValue, use create()
|
|
||||||
*/
|
|
||||||
public Orcidv2AuthorityValue() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Orcidv2AuthorityValue(SolrDocument document) {
|
|
||||||
super(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getOrcid_id() {
|
|
||||||
return orcid_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrcid_id(String orcid_id) {
|
|
||||||
this.orcid_id = orcid_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an empty authority.
|
|
||||||
* @return OrcidAuthorityValue
|
|
||||||
*/
|
|
||||||
public static Orcidv2AuthorityValue create() {
|
|
||||||
Orcidv2AuthorityValue orcidAuthorityValue = new Orcidv2AuthorityValue();
|
|
||||||
orcidAuthorityValue.setId(UUID.randomUUID().toString());
|
|
||||||
orcidAuthorityValue.updateLastModifiedDate();
|
|
||||||
orcidAuthorityValue.setCreationDate(new Date());
|
|
||||||
return orcidAuthorityValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an authority based on a given orcid bio
|
|
||||||
* @return OrcidAuthorityValue
|
|
||||||
*/
|
|
||||||
public static Orcidv2AuthorityValue create(Person person) {
|
|
||||||
if (person == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Orcidv2AuthorityValue authority = Orcidv2AuthorityValue.create();
|
|
||||||
|
|
||||||
authority.setValues(person);
|
|
||||||
|
|
||||||
return authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize this instance based on a Person object
|
|
||||||
* @param person Person
|
|
||||||
*/
|
|
||||||
protected void setValues(Person person) {
|
|
||||||
NameType name = person.getName();
|
|
||||||
|
|
||||||
if (!StringUtils.equals(name.getPath(), this.getOrcid_id())) {
|
|
||||||
this.setOrcid_id(name.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StringUtils.equals(name.getFamilyName().getValue(), this.getLastName())) {
|
|
||||||
this.setLastName(name.getFamilyName().getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StringUtils.equals(name.getGivenNames().getValue(), this.getFirstName())) {
|
|
||||||
this.setFirstName(name.getGivenNames().getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.getCreditName() != null && StringUtils.isNotBlank(name.getCreditName().getValue())) {
|
|
||||||
if (!this.getNameVariants().contains(name.getCreditName().getValue())) {
|
|
||||||
this.addNameVariant(name.getCreditName().getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (person.getKeywords() != null) {
|
|
||||||
for (KeywordType keyword : person.getKeywords().getKeyword()) {
|
|
||||||
if (this.isNewMetadata("keyword", keyword.getContent())) {
|
|
||||||
this.addOtherMetadata("keyword", keyword.getContent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalIdentifiers externalIdentifiers = person.getExternalIdentifiers();
|
|
||||||
if (externalIdentifiers != null) {
|
|
||||||
for (ExternalId externalIdentifier : externalIdentifiers.getExternalIdentifier()) {
|
|
||||||
if (this.isNewMetadata("external_identifier", externalIdentifier.getExternalIdValue())) {
|
|
||||||
this.addOtherMetadata("external_identifier", externalIdentifier.getExternalIdValue());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (person.getResearcherUrls() != null) {
|
|
||||||
for (ResearcherUrlType researcherUrl : person.getResearcherUrls().getResearcherUrl()) {
|
|
||||||
if (this.isNewMetadata("researcher_url", researcherUrl.getUrl().getValue())) {
|
|
||||||
this.addOtherMetadata("researcher_url", researcherUrl.getUrl().getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (person.getBiography() != null) {
|
|
||||||
if (this.isNewMetadata("biography", person.getBiography().getContent())) {
|
|
||||||
this.addOtherMetadata("biography", person.getBiography().getContent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setValue(this.getName());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes an instance of the AuthorityValue with the given information.
|
|
||||||
* @param info string info
|
|
||||||
* @return AuthorityValue
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AuthorityValue newInstance(String info) {
|
|
||||||
AuthorityValue authorityValue = null;
|
|
||||||
if (StringUtils.isNotBlank(info)) {
|
|
||||||
Orcidv2 orcid = new DSpace().getServiceManager().getServiceByName("AuthoritySource", Orcidv2.class);
|
|
||||||
authorityValue = orcid.queryAuthorityID(info);
|
|
||||||
} else {
|
|
||||||
authorityValue = this.create();
|
|
||||||
}
|
|
||||||
return authorityValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValue(String value) {
|
|
||||||
super.setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check to see if the provided label / data pair is already present in the "otherMetadata" or not
|
|
||||||
* */
|
|
||||||
public boolean isNewMetadata(String label, String data) {
|
|
||||||
List<String> strings = getOtherMetadata().get(label);
|
|
||||||
boolean update;
|
|
||||||
if (strings == null) {
|
|
||||||
update = StringUtils.isNotBlank(data);
|
|
||||||
} else {
|
|
||||||
update = !strings.contains(data);
|
|
||||||
}
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add additional metadata to the otherMetadata map*/
|
|
||||||
public void addOtherMetadata(String label, String data) {
|
|
||||||
List<String> strings = otherMetadata.get(label);
|
|
||||||
if (strings == null) {
|
|
||||||
strings = new ArrayList<>();
|
|
||||||
}
|
|
||||||
strings.add(data);
|
|
||||||
otherMetadata.put(label, strings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, List<String>> getOtherMetadata() {
|
|
||||||
return otherMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a solr record from this instance
|
|
||||||
* @return SolrInputDocument
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public SolrInputDocument getSolrInputDocument() {
|
|
||||||
SolrInputDocument doc = super.getSolrInputDocument();
|
|
||||||
if (StringUtils.isNotBlank(getOrcid_id())) {
|
|
||||||
doc.addField("orcid_id", getOrcid_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String t : otherMetadata.keySet()) {
|
|
||||||
List<String> data = otherMetadata.get(t);
|
|
||||||
for (String data_entry : data) {
|
|
||||||
doc.addField("label_" + t, data_entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Information that can be used the choice ui
|
|
||||||
* @return map
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, String> choiceSelectMap() {
|
|
||||||
|
|
||||||
Map<String, String> map = super.choiceSelectMap();
|
|
||||||
|
|
||||||
String orcid_id = getOrcid_id();
|
|
||||||
if (StringUtils.isNotBlank(orcid_id)) {
|
|
||||||
map.put("orcid", orcid_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthorityType() {
|
|
||||||
return "orcid";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a string that will allow this AuthorityType to be recognized and provides information to create a new
|
|
||||||
* instance to be created using public Orcidv2AuthorityValue newInstance(String info).
|
|
||||||
* @return see {@link org.dspace.authority.service.AuthorityValueService#GENERATE AuthorityValueService.GENERATE}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String generateString() {
|
|
||||||
String generateString = AuthorityValueServiceImpl.GENERATE + getAuthorityType() +
|
|
||||||
AuthorityValueServiceImpl.SPLIT;
|
|
||||||
if (StringUtils.isNotBlank(getOrcid_id())) {
|
|
||||||
generateString += getOrcid_id();
|
|
||||||
}
|
|
||||||
return generateString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Orcidv2AuthorityValue that = (Orcidv2AuthorityValue) o;
|
|
||||||
|
|
||||||
if (orcid_id != null ? !orcid_id.equals(that.orcid_id) : that.orcid_id != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return orcid_id != null ? orcid_id.hashCode() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The regular equals() only checks if both AuthorityValues describe the same authority.
|
|
||||||
* This method checks if the AuthorityValues have different information
|
|
||||||
* E.g. it is used to decide when lastModified should be updated.
|
|
||||||
* @param o object
|
|
||||||
* @return true or false
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean hasTheSameInformationAs(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!super.hasTheSameInformationAs(o)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Orcidv2AuthorityValue that = (Orcidv2AuthorityValue) o;
|
|
||||||
|
|
||||||
if (orcid_id != null ? !orcid_id.equals(that.orcid_id) : that.orcid_id != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String key : otherMetadata.keySet()) {
|
|
||||||
if (otherMetadata.get(key) != null) {
|
|
||||||
List<String> metadata = otherMetadata.get(key);
|
|
||||||
List<String> otherMetadata = that.otherMetadata.get(key);
|
|
||||||
if (otherMetadata == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
HashSet<String> metadataSet = new HashSet<String>(metadata);
|
|
||||||
HashSet<String> otherMetadataSet = new HashSet<String>(otherMetadata);
|
|
||||||
if (!metadataSet.equals(otherMetadataSet)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (that.otherMetadata.get(key) != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,6 +8,7 @@
|
|||||||
package org.dspace.authority.rest;
|
package org.dspace.authority.rest;
|
||||||
|
|
||||||
import org.dspace.authority.SolrAuthorityInterface;
|
import org.dspace.authority.SolrAuthorityInterface;
|
||||||
|
import org.dspace.external.OrcidRestConnector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Antoine Snyers (antoine at atmire.com)
|
* @author Antoine Snyers (antoine at atmire.com)
|
||||||
@@ -17,9 +18,9 @@ import org.dspace.authority.SolrAuthorityInterface;
|
|||||||
*/
|
*/
|
||||||
public abstract class RestSource implements SolrAuthorityInterface {
|
public abstract class RestSource implements SolrAuthorityInterface {
|
||||||
|
|
||||||
protected RESTConnector restConnector;
|
protected OrcidRestConnector restConnector;
|
||||||
|
|
||||||
public RestSource(String url) {
|
public RestSource(String url) {
|
||||||
this.restConnector = new RESTConnector(url);
|
this.restConnector = new OrcidRestConnector(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ public class DailyReportEmailer {
|
|||||||
email.setSubject(
|
email.setSubject(
|
||||||
"Checksum checker Report - " + numberOfBitstreams + " Bitstreams found with POSSIBLE issues on " +
|
"Checksum checker Report - " + numberOfBitstreams + " Bitstreams found with POSSIBLE issues on " +
|
||||||
hostname);
|
hostname);
|
||||||
email.setContent("report is attached ...");
|
email.setContent("Checker Report", "report is attached ...");
|
||||||
email.addAttachment(attachment, "checksum_checker_report.txt");
|
email.addAttachment(attachment, "checksum_checker_report.txt");
|
||||||
email.addRecipient(ConfigurationManager.getProperty("mail.admin"));
|
email.addRecipient(ConfigurationManager.getProperty("mail.admin"));
|
||||||
email.send();
|
email.send();
|
||||||
|
@@ -99,8 +99,12 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the sequence ID of this bitstream
|
* Get the sequence ID of this bitstream. The sequence ID is a unique (within an Item) integer that references
|
||||||
|
* this bitstream. It acts as a "persistent" identifier within the Item for this Bitstream (as Bitstream names
|
||||||
|
* are not persistent). Because it is unique within an Item, sequence IDs are assigned by the ItemService.update()
|
||||||
|
* method.
|
||||||
*
|
*
|
||||||
|
* @see org.dspace.content.ItemServiceImpl#update(Context, Item)
|
||||||
* @return the sequence ID
|
* @return the sequence ID
|
||||||
*/
|
*/
|
||||||
public int getSequenceID() {
|
public int getSequenceID() {
|
||||||
@@ -112,8 +116,12 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the sequence ID of this bitstream
|
* Set the sequence ID of this bitstream. The sequence ID is a unique (within an Item) integer that references
|
||||||
|
* this bitstream. While this method is public, it should only be used by ItemService.update() or other methods
|
||||||
|
* which validate the uniqueness of the ID within the associated Item. This method itself does not validate
|
||||||
|
* uniqueness of the ID, nor does the underlying database table.
|
||||||
*
|
*
|
||||||
|
* @see org.dspace.content.ItemServiceImpl#update(Context, Item)
|
||||||
* @param sid the ID
|
* @param sid the ID
|
||||||
*/
|
*/
|
||||||
public void setSequenceID(int sid) {
|
public void setSequenceID(int sid) {
|
||||||
@@ -130,7 +138,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getBitstreamService().getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
return getBitstreamService().getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +150,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
* @throws SQLException if database error
|
* @throws SQLException if database error
|
||||||
*/
|
*/
|
||||||
public void setName(Context context, String n) throws SQLException {
|
public void setName(Context context, String n) throws SQLException {
|
||||||
getBitstreamService().setMetadataSingleValue(context, this, MetadataSchema.DC_SCHEMA, "title", null, null, n);
|
getBitstreamService().setMetadataSingleValue(context, this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null, null, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +162,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
* @return the source of the bitstream
|
* @return the source of the bitstream
|
||||||
*/
|
*/
|
||||||
public String getSource() {
|
public String getSource() {
|
||||||
return getBitstreamService().getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "source", null, Item.ANY);
|
return getBitstreamService().getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"source", null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,7 +174,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
* @throws SQLException if database error
|
* @throws SQLException if database error
|
||||||
*/
|
*/
|
||||||
public void setSource(Context context, String n) throws SQLException {
|
public void setSource(Context context, String n) throws SQLException {
|
||||||
getBitstreamService().setMetadataSingleValue(context, this, MetadataSchema.DC_SCHEMA, "source", null, null, n);
|
getBitstreamService().setMetadataSingleValue(context, this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"source", null, null, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,7 +186,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
*/
|
*/
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return getBitstreamService()
|
return getBitstreamService()
|
||||||
.getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "description", null, Item.ANY);
|
.getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "description",
|
||||||
|
null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,7 +199,7 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
*/
|
*/
|
||||||
public void setDescription(Context context, String n) throws SQLException {
|
public void setDescription(Context context, String n) throws SQLException {
|
||||||
getBitstreamService()
|
getBitstreamService()
|
||||||
.setMetadataSingleValue(context, this, MetadataSchema.DC_SCHEMA, "description", null, null, n);
|
.setMetadataSingleValue(context, this, MetadataSchemaEnum.DC.getName(), "description", null, null, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -235,7 +248,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
* @return the user's format description.
|
* @return the user's format description.
|
||||||
*/
|
*/
|
||||||
public String getUserFormatDescription() {
|
public String getUserFormatDescription() {
|
||||||
return getBitstreamService().getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "format", null, Item.ANY);
|
return getBitstreamService().getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"format", null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BitstreamFormat getBitstreamFormat() {
|
protected BitstreamFormat getBitstreamFormat() {
|
||||||
|
@@ -71,7 +71,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity<Integer>
|
|||||||
@Column(name = "internal")
|
@Column(name = "internal")
|
||||||
private boolean internal = false;
|
private boolean internal = false;
|
||||||
|
|
||||||
@ElementCollection(fetch = FetchType.LAZY)
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
@CollectionTable(name = "fileextension", joinColumns = @JoinColumn(name = "bitstream_format_id"))
|
@CollectionTable(name = "fileextension", joinColumns = @JoinColumn(name = "bitstream_format_id"))
|
||||||
@CollectionId(
|
@CollectionId(
|
||||||
columns = @Column(name = "file_extension_id"),
|
columns = @Column(name = "file_extension_id"),
|
||||||
@@ -275,7 +275,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity<Integer>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final BitstreamFormat otherBitstreamFormat = (BitstreamFormat) other;
|
final BitstreamFormat otherBitstreamFormat = (BitstreamFormat) other;
|
||||||
if (this.getID() != otherBitstreamFormat.getID()) {
|
if (!this.getID().equals(otherBitstreamFormat.getID())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -205,7 +205,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
|
|||||||
@Override
|
@Override
|
||||||
public void setUserFormatDescription(Context context, Bitstream bitstream, String desc) throws SQLException {
|
public void setUserFormatDescription(Context context, Bitstream bitstream, String desc) throws SQLException {
|
||||||
setFormat(context, bitstream, null);
|
setFormat(context, bitstream, null);
|
||||||
setMetadataSingleValue(context, bitstream, MetadataSchema.DC_SCHEMA, "format", null, null, desc);
|
setMetadataSingleValue(context, bitstream, MetadataSchemaEnum.DC.getName(), "format", null, null, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -235,7 +235,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove user type description
|
// Remove user type description
|
||||||
clearMetadata(context, bitstream, MetadataSchema.DC_SCHEMA, "format", null, Item.ANY);
|
clearMetadata(context, bitstream, MetadataSchemaEnum.DC.getName(), "format", null, Item.ANY);
|
||||||
|
|
||||||
// Update the ID in the table row
|
// Update the ID in the table row
|
||||||
bitstream.setFormat(bitstreamFormat);
|
bitstream.setFormat(bitstreamFormat);
|
||||||
|
@@ -88,7 +88,7 @@ public class Bundle extends DSpaceObject implements DSpaceObjectLegacySupport {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getBundleService().getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
return getBundleService().getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,7 +100,8 @@ public class Bundle extends DSpaceObject implements DSpaceObjectLegacySupport {
|
|||||||
* @throws SQLException if database error
|
* @throws SQLException if database error
|
||||||
*/
|
*/
|
||||||
public void setName(Context context, String name) throws SQLException {
|
public void setName(Context context, String name) throws SQLException {
|
||||||
getBundleService().setMetadataSingleValue(context, this, MetadataSchema.DC_SCHEMA, "title", null, null, name);
|
getBundleService().setMetadataSingleValue(context, this, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null, null, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -7,6 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.content;
|
package org.dspace.content;
|
||||||
|
|
||||||
|
import static org.dspace.core.Constants.ADD;
|
||||||
|
import static org.dspace.core.Constants.REMOVE;
|
||||||
|
import static org.dspace.core.Constants.WRITE;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -268,6 +272,81 @@ public class BundleServiceImpl extends DSpaceObjectServiceImpl<Bundle> implement
|
|||||||
return authorizeService.getPolicies(context, bundle);
|
return authorizeService.getPolicies(context, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBitstreamOrder(Context context, Bundle bundle, int from, int to)
|
||||||
|
throws AuthorizeException, SQLException {
|
||||||
|
List<Bitstream> bitstreams = bundle.getBitstreams();
|
||||||
|
if (bitstreams.size() < 1 || from >= bitstreams.size() || to >= bitstreams.size() || from < 0 || to < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid 'from' and 'to' arguments supplied for moving a bitstream within bundle " +
|
||||||
|
bundle.getID() + ". from: " + from + "; to: " + to
|
||||||
|
);
|
||||||
|
}
|
||||||
|
List<UUID> bitstreamIds = new LinkedList<>();
|
||||||
|
for (Bitstream bitstream : bitstreams) {
|
||||||
|
bitstreamIds.add(bitstream.getID());
|
||||||
|
}
|
||||||
|
if (from < to) {
|
||||||
|
bitstreamIds.add(to + 1, bitstreamIds.get(from));
|
||||||
|
bitstreamIds.remove(from);
|
||||||
|
} else {
|
||||||
|
bitstreamIds.add(to, bitstreamIds.get(from));
|
||||||
|
bitstreamIds.remove(from + 1);
|
||||||
|
}
|
||||||
|
setOrder(context, bundle, bitstreamIds.toArray(new UUID[bitstreamIds.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveBitstreamToBundle(Context context, Bundle targetBundle, Bitstream bitstream)
|
||||||
|
throws SQLException, AuthorizeException, IOException {
|
||||||
|
List<Bundle> bundles = new LinkedList<>();
|
||||||
|
bundles.addAll(bitstream.getBundles());
|
||||||
|
|
||||||
|
if (hasSufficientMovePermissions(context, bundles, targetBundle)) {
|
||||||
|
this.addBitstream(context, targetBundle, bitstream);
|
||||||
|
this.update(context, targetBundle);
|
||||||
|
for (Bundle bundle : bundles) {
|
||||||
|
this.removeBitstream(context, bundle, bitstream);
|
||||||
|
this.update(context, bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies if the context (user) has sufficient rights to the bundles in order to move a bitstream
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param bundles The current bundles in which the bitstream resides
|
||||||
|
* @param targetBundle The target bundle
|
||||||
|
* @return true when the context has sufficient rights
|
||||||
|
* @throws AuthorizeException When one of the necessary rights is not present
|
||||||
|
*/
|
||||||
|
private boolean hasSufficientMovePermissions(final Context context, final List<Bundle> bundles,
|
||||||
|
final Bundle targetBundle) throws SQLException, AuthorizeException {
|
||||||
|
for (Bundle bundle : bundles) {
|
||||||
|
if (!authorizeService.authorizeActionBoolean(context, bundle, WRITE) || !authorizeService
|
||||||
|
.authorizeActionBoolean(context, bundle, REMOVE)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"The current user does not have WRITE and REMOVE access to the current bundle: " + bundle
|
||||||
|
.getID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!authorizeService.authorizeActionBoolean(context, targetBundle, WRITE) || !authorizeService
|
||||||
|
.authorizeActionBoolean(context, targetBundle, ADD)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"The current user does not have WRITE and ADD access to the target bundle: " + targetBundle
|
||||||
|
.getID());
|
||||||
|
}
|
||||||
|
for (Item item : targetBundle.getItems()) {
|
||||||
|
if (!authorizeService.authorizeActionBoolean(context, item, WRITE)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"The current user does not have WRITE access to the target bundle's item: " + item.getID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOrder(Context context, Bundle bundle, UUID[] bitstreamIds) throws AuthorizeException, SQLException {
|
public void setOrder(Context context, Bundle bundle, UUID[] bitstreamIds) throws AuthorizeException, SQLException {
|
||||||
authorizeService.authorizeAction(context, bundle, Constants.WRITE);
|
authorizeService.authorizeAction(context, bundle, Constants.WRITE);
|
||||||
|
@@ -120,7 +120,7 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
|
|||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
String value = getCollectionService()
|
String value = getCollectionService()
|
||||||
.getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
.getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
return value == null ? "" : value;
|
return value == null ? "" : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -154,10 +154,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Collection> findAll(Context context) throws SQLException {
|
public List<Collection> findAll(Context context) throws SQLException {
|
||||||
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchema.DC_SCHEMA, "title", null);
|
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null);
|
||||||
if (nameField == null) {
|
if (nameField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".title' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".title' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return collectionDAO.findAll(context, nameField);
|
return collectionDAO.findAll(context, nameField);
|
||||||
@@ -165,10 +166,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Collection> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
public List<Collection> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||||
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchema.DC_SCHEMA, "title", null);
|
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null);
|
||||||
if (nameField == null) {
|
if (nameField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".title' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".title' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return collectionDAO.findAll(context, nameField, limit, offset);
|
return collectionDAO.findAll(context, nameField, limit, offset);
|
||||||
@@ -760,6 +762,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
// Remove any workflow roles
|
// Remove any workflow roles
|
||||||
collectionRoleService.deleteByCollection(context, collection);
|
collectionRoleService.deleteByCollection(context, collection);
|
||||||
|
|
||||||
|
collection.getResourcePolicies().clear();
|
||||||
|
|
||||||
// Remove default administrators group
|
// Remove default administrators group
|
||||||
Group g = collection.getAdministrators();
|
Group g = collection.getAdministrators();
|
||||||
|
|
||||||
|
@@ -262,7 +262,7 @@ public class Community extends DSpaceObject implements DSpaceObjectLegacySupport
|
|||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
String value = getCommunityService()
|
String value = getCommunityService()
|
||||||
.getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
.getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
return value == null ? "" : value;
|
return value == null ? "" : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -148,10 +148,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Community> findAll(Context context) throws SQLException {
|
public List<Community> findAll(Context context) throws SQLException {
|
||||||
MetadataField sortField = metadataFieldService.findByElement(context, MetadataSchema.DC_SCHEMA, "title", null);
|
MetadataField sortField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null);
|
||||||
if (sortField == null) {
|
if (sortField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".title' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".title' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return communityDAO.findAll(context, sortField);
|
return communityDAO.findAll(context, sortField);
|
||||||
@@ -159,10 +160,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Community> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
public List<Community> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||||
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchema.DC_SCHEMA, "title", null);
|
MetadataField nameField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null);
|
||||||
if (nameField == null) {
|
if (nameField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".title' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".title' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return communityDAO.findAll(context, nameField, limit, offset);
|
return communityDAO.findAll(context, nameField, limit, offset);
|
||||||
@@ -171,10 +173,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
@Override
|
@Override
|
||||||
public List<Community> findAllTop(Context context) throws SQLException {
|
public List<Community> findAllTop(Context context) throws SQLException {
|
||||||
// get all communities that are not children
|
// get all communities that are not children
|
||||||
MetadataField sortField = metadataFieldService.findByElement(context, MetadataSchema.DC_SCHEMA, "title", null);
|
MetadataField sortField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null);
|
||||||
if (sortField == null) {
|
if (sortField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".title' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".title' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return communityDAO.findAllNoParent(context, sortField);
|
return communityDAO.findAllNoParent(context, sortField);
|
||||||
|
@@ -10,8 +10,10 @@ package org.dspace.content;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
@@ -27,6 +29,7 @@ import org.dspace.content.authority.service.MetadataAuthorityService;
|
|||||||
import org.dspace.content.service.DSpaceObjectService;
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
import org.dspace.content.service.MetadataFieldService;
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
import org.dspace.content.service.MetadataValueService;
|
import org.dspace.content.service.MetadataValueService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.handle.service.HandleService;
|
import org.dspace.handle.service.HandleService;
|
||||||
@@ -60,6 +63,8 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
protected MetadataFieldService metadataFieldService;
|
protected MetadataFieldService metadataFieldService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected MetadataAuthorityService metadataAuthorityService;
|
protected MetadataAuthorityService metadataAuthorityService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipService relationshipService;
|
||||||
|
|
||||||
public DSpaceObjectServiceImpl() {
|
public DSpaceObjectServiceImpl() {
|
||||||
|
|
||||||
@@ -67,7 +72,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName(T dso) {
|
public String getName(T dso) {
|
||||||
String value = getMetadataFirstValue(dso, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
String value = getMetadataFirstValue(dso, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
return value == null ? "" : value;
|
return value == null ? "" : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +146,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
public List<MetadataValue> getMetadataByMetadataString(T dso, String mdString) {
|
public List<MetadataValue> getMetadataByMetadataString(T dso, String mdString) {
|
||||||
StringTokenizer dcf = new StringTokenizer(mdString, ".");
|
StringTokenizer dcf = new StringTokenizer(mdString, ".");
|
||||||
|
|
||||||
String[] tokens = { "", "", "" };
|
String[] tokens = {"", "", ""};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (dcf.hasMoreTokens()) {
|
while (dcf.hasMoreTokens()) {
|
||||||
tokens[i] = dcf.nextToken().trim();
|
tokens[i] = dcf.nextToken().trim();
|
||||||
@@ -235,12 +240,22 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
throws SQLException {
|
throws SQLException {
|
||||||
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
|
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
|
||||||
boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField);
|
boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField);
|
||||||
|
|
||||||
// We will not verify that they are valid entries in the registry
|
// We will not verify that they are valid entries in the registry
|
||||||
// until update() is called.
|
// until update() is called.
|
||||||
for (int i = 0; i < values.size(); i++) {
|
for (int i = 0; i < values.size(); i++) {
|
||||||
|
|
||||||
|
if (authorities != null && authorities.size() >= i) {
|
||||||
|
if (StringUtils.startsWith(authorities.get(i), Constants.VIRTUAL_AUTHORITY_PREFIX)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
|
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
|
||||||
|
//Set place to list length of all metadatavalues for the given schema.element.qualifier combination.
|
||||||
|
// Subtract one to adhere to the 0 as first element rule
|
||||||
|
metadataValue.setPlace(
|
||||||
|
this.getMetadata(dso, metadataField.getMetadataSchema().getName(), metadataField.getElement(),
|
||||||
|
metadataField.getQualifier(), Item.ANY).size() - 1);
|
||||||
|
|
||||||
metadataValue.setLanguage(lang == null ? null : lang.trim());
|
metadataValue.setLanguage(lang == null ? null : lang.trim());
|
||||||
|
|
||||||
// Logic to set Authority and Confidence:
|
// Logic to set Authority and Confidence:
|
||||||
@@ -521,7 +536,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
protected String[] getMDValueByField(String field) {
|
protected String[] getMDValueByField(String field) {
|
||||||
StringTokenizer dcf = new StringTokenizer(field, ".");
|
StringTokenizer dcf = new StringTokenizer(field, ".");
|
||||||
|
|
||||||
String[] tokens = { "", "", "" };
|
String[] tokens = {"", "", ""};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (dcf.hasMoreTokens()) {
|
while (dcf.hasMoreTokens()) {
|
||||||
tokens[i] = dcf.nextToken().trim();
|
tokens[i] = dcf.nextToken().trim();
|
||||||
@@ -543,11 +558,50 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
*/
|
*/
|
||||||
// A map created to store the latest place for each metadata field
|
// A map created to store the latest place for each metadata field
|
||||||
Map<MetadataField, Integer> fieldToLastPlace = new HashMap<>();
|
Map<MetadataField, Integer> fieldToLastPlace = new HashMap<>();
|
||||||
List<MetadataValue> metadataValues = dso.getMetadata();
|
List<MetadataValue> metadataValues = new LinkedList<>();
|
||||||
|
if (dso.getType() == Constants.ITEM) {
|
||||||
|
metadataValues = getMetadata(dso, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||||
|
} else {
|
||||||
|
metadataValues = dso.getMetadata();
|
||||||
|
}
|
||||||
|
//This inline sort function will sort the MetadataValues based on their place in ascending order
|
||||||
|
//If two places are the same then the MetadataValue instance will be placed before the
|
||||||
|
//RelationshipMetadataValue instance.
|
||||||
|
//This is done to ensure that the order is correct.
|
||||||
|
metadataValues.sort(new Comparator<MetadataValue>() {
|
||||||
|
public int compare(MetadataValue o1, MetadataValue o2) {
|
||||||
|
int compare = o1.getPlace() - o2.getPlace();
|
||||||
|
if (compare == 0) {
|
||||||
|
if (o1 instanceof RelationshipMetadataValue) {
|
||||||
|
return 1;
|
||||||
|
} else if (o2 instanceof RelationshipMetadataValue) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
});
|
||||||
for (MetadataValue metadataValue : metadataValues) {
|
for (MetadataValue metadataValue : metadataValues) {
|
||||||
//Retrieve & store the place for each metadata value
|
//Retrieve & store the place for each metadata value
|
||||||
|
if (StringUtils.startsWith(metadataValue.getAuthority(), Constants.VIRTUAL_AUTHORITY_PREFIX) &&
|
||||||
|
((RelationshipMetadataValue) metadataValue).isUseForPlace()) {
|
||||||
int mvPlace = getMetadataValuePlace(fieldToLastPlace, metadataValue);
|
int mvPlace = getMetadataValuePlace(fieldToLastPlace, metadataValue);
|
||||||
metadataValue.setPlace(mvPlace);
|
metadataValue.setPlace(mvPlace);
|
||||||
|
String authority = metadataValue.getAuthority();
|
||||||
|
String relationshipId = StringUtils.split(authority, "::")[1];
|
||||||
|
Relationship relationship = relationshipService.find(context, Integer.parseInt(relationshipId));
|
||||||
|
if (relationship.getLeftItem() == (Item) dso) {
|
||||||
|
relationship.setLeftPlace(mvPlace);
|
||||||
|
} else {
|
||||||
|
relationship.setRightPlace(mvPlace);
|
||||||
|
}
|
||||||
|
relationshipService.update(context, relationship);
|
||||||
|
|
||||||
|
} else if (!StringUtils.startsWith(metadataValue.getAuthority(),
|
||||||
|
Constants.VIRTUAL_AUTHORITY_PREFIX)) {
|
||||||
|
int mvPlace = getMetadataValuePlace(fieldToLastPlace, metadataValue);
|
||||||
|
metadataValue.setPlace(mvPlace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,7 +611,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
*
|
*
|
||||||
* @param fieldToLastPlace the map containing the latest place of each metadata field
|
* @param fieldToLastPlace the map containing the latest place of each metadata field
|
||||||
* @param metadataValue the metadata value that needs to get a place
|
* @param metadataValue the metadata value that needs to get a place
|
||||||
* @return The new place for the metadata valu
|
* @return The new place for the metadata value
|
||||||
*/
|
*/
|
||||||
protected int getMetadataValuePlace(Map<MetadataField, Integer> fieldToLastPlace, MetadataValue metadataValue) {
|
protected int getMetadataValuePlace(Map<MetadataField, Integer> fieldToLastPlace, MetadataValue metadataValue) {
|
||||||
MetadataField metadataField = metadataValue.getMetadataField();
|
MetadataField metadataField = metadataValue.getMetadataField();
|
||||||
@@ -573,23 +627,23 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
protected String[] getMDValueByLegacyField(String field) {
|
protected String[] getMDValueByLegacyField(String field) {
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case "introductory_text":
|
case "introductory_text":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "description", null};
|
||||||
case "short_description":
|
case "short_description":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", "abstract"};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "description", "abstract"};
|
||||||
case "side_bar_text":
|
case "side_bar_text":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", "tableofcontents"};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "description", "tableofcontents"};
|
||||||
case "copyright_text":
|
case "copyright_text":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "rights", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "rights", null};
|
||||||
case "name":
|
case "name":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "title", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "title", null};
|
||||||
case "provenance_description":
|
case "provenance_description":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "provenance", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "provenance", null};
|
||||||
case "license":
|
case "license":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "rights", "license"};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "rights", "license"};
|
||||||
case "user_format_description":
|
case "user_format_description":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "format", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "format", null};
|
||||||
case "source":
|
case "source":
|
||||||
return new String[] {MetadataSchema.DC_SCHEMA, "source", null};
|
return new String[] {MetadataSchemaEnum.DC.getName(), "source", null};
|
||||||
case "firstname":
|
case "firstname":
|
||||||
return new String[] {"eperson", "firstname", null};
|
return new String[] {"eperson", "firstname", null};
|
||||||
case "lastname":
|
case "lastname":
|
||||||
|
68
dspace-api/src/main/java/org/dspace/content/Entity.java
Normal file
68
dspace-api/src/main/java/org/dspace/content/Entity.java
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an Entity object. An Entity object has an Item that it describes with a list
|
||||||
|
* of relationships that it includes as well.
|
||||||
|
*/
|
||||||
|
public class Entity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Item that is being described by this Entity
|
||||||
|
*/
|
||||||
|
private Item item;
|
||||||
|
/**
|
||||||
|
* The relationships for the Item that is included in this Entity
|
||||||
|
*/
|
||||||
|
private List<Relationship> relationships;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for the Entity object
|
||||||
|
* @param item The Item to be included in this Entity object as a property
|
||||||
|
* @param relationshipList The list of relationships
|
||||||
|
*/
|
||||||
|
public Entity(Item item,List<Relationship> relationshipList) {
|
||||||
|
setItem(item);
|
||||||
|
setRelationships(relationshipList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the Item for this Entity object
|
||||||
|
* @return The Item that is described in this Entity object
|
||||||
|
*/
|
||||||
|
public Item getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the Item for this Entity object
|
||||||
|
* @param item The Item to be set
|
||||||
|
*/
|
||||||
|
public void setItem(Item item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the list of relationships for the Item in this Entity object
|
||||||
|
* @return the list of relationships
|
||||||
|
*/
|
||||||
|
public List<Relationship> getRelationships() {
|
||||||
|
return relationships;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the list of relationships for the Item in this Entity object
|
||||||
|
* @param relationships The list of relationships to be set
|
||||||
|
*/
|
||||||
|
public void setRelationships(List<Relationship> relationships) {
|
||||||
|
this.relationships = relationships;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dspace.content.service.EntityService;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class EntityServiceImpl implements EntityService {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected EntityTypeService entityTypeService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipService relationshipService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipTypeService relationshipTypeService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected ItemService itemService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity findByItemId(Context context, UUID itemId) throws SQLException {
|
||||||
|
|
||||||
|
return findByItemId(context, itemId, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity findByItemId(Context context, UUID itemId, Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
Item item = itemService.find(context, itemId);
|
||||||
|
List<Relationship> relationshipList = relationshipService.findByItem(context, item, limit, offset);
|
||||||
|
return new Entity(item, relationshipList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getType(Context context, Entity entity) throws SQLException {
|
||||||
|
Item item = entity.getItem();
|
||||||
|
List<MetadataValue> list = itemService.getMetadata(item, "relationship", "type", null, Item.ANY);
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
return entityTypeService.findByEntityType(context, list.get(0).getValue());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> getLeftRelations(Context context, Entity entity) {
|
||||||
|
List<Relationship> fullList = entity.getRelationships();
|
||||||
|
List<Relationship> listToReturn = new LinkedList<>();
|
||||||
|
for (Relationship relationship : fullList) {
|
||||||
|
if (relationship.getLeftItem().getID() == entity.getItem().getID()) {
|
||||||
|
listToReturn.add(relationship);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listToReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> getRightRelations(Context context, Entity entity) {
|
||||||
|
List<Relationship> fullList = entity.getRelationships();
|
||||||
|
List<Relationship> listToReturn = new LinkedList<>();
|
||||||
|
for (Relationship relationship : fullList) {
|
||||||
|
if (relationship.getRightItem().getID() == entity.getItem().getID()) {
|
||||||
|
listToReturn.add(relationship);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listToReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> getRelationsByTypeName(Context context, String typeName) throws SQLException {
|
||||||
|
return getRelationsByTypeName(context, typeName, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> getRelationsByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipService.findByTypeName(context, typeName, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||||
|
|
||||||
|
return getAllRelationshipTypes(context, entity, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||||
|
|
||||||
|
return getLeftRelationshipTypes(context, entity, true, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), isLeft, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||||
|
|
||||||
|
return getRightRelationshipTypes(context, entity, false, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), isLeft, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getRelationshipTypesByTypeName(Context context, String type) throws SQLException {
|
||||||
|
return getRelationshipTypesByTypeName(context, type, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> getRelationshipTypesByTypeName(Context context, String typeName,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
return relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName, limit, offset);
|
||||||
|
}
|
||||||
|
}
|
77
dspace-api/src/main/java/org/dspace/content/EntityType.java
Normal file
77
dspace-api/src/main/java/org/dspace/content/EntityType.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.dspace.core.ReloadableEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing an EntityType
|
||||||
|
* This class contains an Integer ID that will be the unique value for this class and also the primary key
|
||||||
|
* This also has a label that will be used to identify what kind of EntityType this object is
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "entity_type")
|
||||||
|
public class EntityType implements ReloadableEntity<Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Integer ID used as a primary key for this database object.
|
||||||
|
* This is generated by a sequence
|
||||||
|
*/
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity_type_id_seq")
|
||||||
|
@SequenceGenerator(name = "entity_type_id_seq", sequenceName = "entity_type_id_seq", allocationSize = 1)
|
||||||
|
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)
|
||||||
|
protected Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The String label field for the entity type
|
||||||
|
* This cannot be null
|
||||||
|
*/
|
||||||
|
@Column(name = "label", nullable = false)
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard setter for the ID of this EntityType
|
||||||
|
* @param id The ID that this EntityType's ID will be set to
|
||||||
|
*/
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard getter for the label of this EntityType
|
||||||
|
* @return The label for this EntityType
|
||||||
|
*/
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard setter for the label of this EntityType
|
||||||
|
* @param label The label that this EntityType's label will be set to
|
||||||
|
*/
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard getter for the ID of this EntityType
|
||||||
|
* @return The ID for this EntityType
|
||||||
|
*/
|
||||||
|
public Integer getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.dao.EntityTypeDAO;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class EntityTypeServiceImpl implements EntityTypeService {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected EntityTypeDAO entityTypeDAO;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType findByEntityType(Context context, String entityType) throws SQLException {
|
||||||
|
return entityTypeDAO.findByEntityType(context, entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EntityType> findAll(Context context) throws SQLException {
|
||||||
|
|
||||||
|
return findAll(context, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EntityType> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
return entityTypeDAO.findAll(context, EntityType.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType create(Context context) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify entityType");
|
||||||
|
}
|
||||||
|
return entityTypeDAO.create(context, new EntityType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType create(Context context, String entityTypeString) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify entityType");
|
||||||
|
}
|
||||||
|
EntityType entityType = new EntityType();
|
||||||
|
entityType.setLabel(entityTypeString);
|
||||||
|
return entityTypeDAO.create(context, entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType find(Context context,int id) throws SQLException {
|
||||||
|
EntityType entityType = entityTypeDAO.findByID(context, EntityType.class, id);
|
||||||
|
return entityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context,EntityType entityType) throws SQLException, AuthorizeException {
|
||||||
|
update(context,Collections.singletonList(entityType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context,List<EntityType> entityTypes) throws SQLException, AuthorizeException {
|
||||||
|
if (CollectionUtils.isNotEmpty(entityTypes)) {
|
||||||
|
// Check authorisation - only administrators can change formats
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify entityType");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EntityType entityType : entityTypes) {
|
||||||
|
entityTypeDAO.save(context, entityType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context,EntityType entityType) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can delete entityType");
|
||||||
|
}
|
||||||
|
entityTypeDAO.delete(context, entityType);
|
||||||
|
}
|
||||||
|
}
|
@@ -104,9 +104,10 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
|
|
||||||
// If the item doesn't have a date.accessioned, set it to today
|
// If the item doesn't have a date.accessioned, set it to today
|
||||||
List<MetadataValue> dateAccessioned = itemService
|
List<MetadataValue> dateAccessioned = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "date", "accessioned", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "date", "accessioned", Item.ANY);
|
||||||
if (dateAccessioned.isEmpty()) {
|
if (dateAccessioned.isEmpty()) {
|
||||||
itemService.addMetadata(c, item, MetadataSchema.DC_SCHEMA, "date", "accessioned", null, now.toString());
|
itemService.addMetadata(c, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"date", "accessioned", null, now.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If issue date is set as "today" (literal string), then set it to current date
|
// If issue date is set as "today" (literal string), then set it to current date
|
||||||
@@ -114,8 +115,8 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
// replacing "today" with today's date.
|
// replacing "today" with today's date.
|
||||||
// NOTE: As of DSpace 4.0, DSpace no longer sets an issue date by default
|
// NOTE: As of DSpace 4.0, DSpace no longer sets an issue date by default
|
||||||
List<MetadataValue> currentDateIssued = itemService
|
List<MetadataValue> currentDateIssued = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "date", "issued", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "date", "issued", Item.ANY);
|
||||||
itemService.clearMetadata(c, item, MetadataSchema.DC_SCHEMA, "date", "issued", Item.ANY);
|
itemService.clearMetadata(c, item, MetadataSchemaEnum.DC.getName(), "date", "issued", Item.ANY);
|
||||||
for (MetadataValue dcv : currentDateIssued) {
|
for (MetadataValue dcv : currentDateIssued) {
|
||||||
if (dcv.getValue() != null && dcv.getValue().equalsIgnoreCase("today")) {
|
if (dcv.getValue() != null && dcv.getValue().equalsIgnoreCase("today")) {
|
||||||
DCDate issued = new DCDate(now.getYear(), now.getMonth(), now.getDay(), -1, -1, -1);
|
DCDate issued = new DCDate(now.getYear(), now.getMonth(), now.getDay(), -1, -1, -1);
|
||||||
@@ -127,7 +128,8 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
|
|
||||||
// Record that the item was restored
|
// Record that the item was restored
|
||||||
String provDescription = "Restored into DSpace on " + now + " (GMT).";
|
String provDescription = "Restored into DSpace on " + now + " (GMT).";
|
||||||
itemService.addMetadata(c, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en", provDescription);
|
itemService.addMetadata(c, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"description", "provenance", "en", provDescription);
|
||||||
|
|
||||||
return finishItem(c, item, is);
|
return finishItem(c, item, is);
|
||||||
}
|
}
|
||||||
@@ -137,14 +139,16 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
// create accession date
|
// create accession date
|
||||||
DCDate now = DCDate.getCurrent();
|
DCDate now = DCDate.getCurrent();
|
||||||
itemService.addMetadata(c, item, MetadataSchema.DC_SCHEMA, "date", "accessioned", null, now.toString());
|
itemService.addMetadata(c, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"date", "accessioned", null, now.toString());
|
||||||
|
|
||||||
// add date available if not under embargo, otherwise it will
|
// add date available if not under embargo, otherwise it will
|
||||||
// be set when the embargo is lifted.
|
// be set when the embargo is lifted.
|
||||||
// this will flush out fatal embargo metadata
|
// this will flush out fatal embargo metadata
|
||||||
// problems before we set inArchive.
|
// problems before we set inArchive.
|
||||||
if (embargoService.getEmbargoTermsAsDate(c, item) == null) {
|
if (embargoService.getEmbargoTermsAsDate(c, item) == null) {
|
||||||
itemService.addMetadata(c, item, MetadataSchema.DC_SCHEMA, "date", "available", null, now.toString());
|
itemService.addMetadata(c, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"date", "available", null, now.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If issue date is set as "today" (literal string), then set it to current date
|
// If issue date is set as "today" (literal string), then set it to current date
|
||||||
@@ -152,8 +156,8 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
// replacing "today" with today's date.
|
// replacing "today" with today's date.
|
||||||
// NOTE: As of DSpace 4.0, DSpace no longer sets an issue date by default
|
// NOTE: As of DSpace 4.0, DSpace no longer sets an issue date by default
|
||||||
List<MetadataValue> currentDateIssued = itemService
|
List<MetadataValue> currentDateIssued = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "date", "issued", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "date", "issued", Item.ANY);
|
||||||
itemService.clearMetadata(c, item, MetadataSchema.DC_SCHEMA, "date", "issued", Item.ANY);
|
itemService.clearMetadata(c, item, MetadataSchemaEnum.DC.getName(), "date", "issued", Item.ANY);
|
||||||
for (MetadataValue dcv : currentDateIssued) {
|
for (MetadataValue dcv : currentDateIssued) {
|
||||||
if (dcv.getValue() != null && dcv.getValue().equalsIgnoreCase("today")) {
|
if (dcv.getValue() != null && dcv.getValue().equalsIgnoreCase("today")) {
|
||||||
DCDate issued = new DCDate(now.getYear(), now.getMonth(), now.getDay(), -1, -1, -1);
|
DCDate issued = new DCDate(now.getYear(), now.getMonth(), now.getDay(), -1, -1, -1);
|
||||||
@@ -178,7 +182,8 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add provenance description
|
// Add provenance description
|
||||||
itemService.addMetadata(c, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en", provDescription);
|
itemService.addMetadata(c, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"description", "provenance", "en", provDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -362,7 +362,7 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport, Ind
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getItemService().getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
return getItemService().getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -174,7 +174,7 @@ public class ItemComparator implements Comparator, Serializable {
|
|||||||
protected String getValue(Item item) {
|
protected String getValue(Item item) {
|
||||||
// The overall array and each element are guaranteed non-null
|
// The overall array and each element are guaranteed non-null
|
||||||
List<MetadataValue> dcvalues = itemService
|
List<MetadataValue> dcvalues = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, element, qualifier, language);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), element, qualifier, language);
|
||||||
|
|
||||||
if (dcvalues.isEmpty()) {
|
if (dcvalues.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -11,10 +11,14 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -36,7 +40,9 @@ import org.dspace.content.service.CommunityService;
|
|||||||
import org.dspace.content.service.InstallItemService;
|
import org.dspace.content.service.InstallItemService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.content.service.MetadataSchemaService;
|
import org.dspace.content.service.MetadataSchemaService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
@@ -102,6 +108,14 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected WorkflowItemService workflowItemService;
|
protected WorkflowItemService workflowItemService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipService relationshipService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private RelationshipMetadataService relationshipMetadataService;
|
||||||
|
|
||||||
protected ItemServiceImpl() {
|
protected ItemServiceImpl() {
|
||||||
super();
|
super();
|
||||||
@@ -230,10 +244,10 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
throws SQLException {
|
throws SQLException {
|
||||||
|
|
||||||
MetadataField metadataField = metadataFieldService
|
MetadataField metadataField = metadataFieldService
|
||||||
.findByElement(context, MetadataSchema.DC_SCHEMA, "date", "accessioned");
|
.findByElement(context, MetadataSchemaEnum.DC.getName(), "date", "accessioned");
|
||||||
if (metadataField == null) {
|
if (metadataField == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Required metadata field '" + MetadataSchema.DC_SCHEMA + ".date.accessioned' doesn't exist!");
|
"Required metadata field '" + MetadataSchemaEnum.DC.getName() + ".date.accessioned' doesn't exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemDAO.findBySubmitter(context, eperson, metadataField, limit);
|
return itemDAO.findBySubmitter(context, eperson, metadataField, limit);
|
||||||
@@ -250,6 +264,17 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
return itemDAO.findArchivedByCollection(context, collection, limit, offset);
|
return itemDAO.findArchivedByCollection(context, collection, limit, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Item> findByCollectionMapping(Context context, Collection collection, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return itemDAO.findArchivedByCollectionExcludingOwning(context, collection, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByCollectionMapping(Context context, Collection collection) throws SQLException {
|
||||||
|
return itemDAO.countArchivedByCollectionExcludingOwning(context, collection);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException {
|
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException {
|
||||||
return itemDAO.findAllByCollection(context, collection);
|
return itemDAO.findAllByCollection(context, collection);
|
||||||
@@ -471,7 +496,8 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
|
|
||||||
super.update(context, item);
|
super.update(context, item);
|
||||||
|
|
||||||
// Set sequence IDs for bitstreams in item
|
// Set sequence IDs for bitstreams in Item. To guarantee uniqueness,
|
||||||
|
// sequence IDs are assigned in sequential order (starting with 1)
|
||||||
int sequence = 0;
|
int sequence = 0;
|
||||||
List<Bundle> bunds = item.getBundles();
|
List<Bundle> bunds = item.getBundles();
|
||||||
|
|
||||||
@@ -488,8 +514,6 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
|
|
||||||
// start sequencing bitstreams without sequence IDs
|
// start sequencing bitstreams without sequence IDs
|
||||||
sequence++;
|
sequence++;
|
||||||
|
|
||||||
|
|
||||||
for (Bundle bund : bunds) {
|
for (Bundle bund : bunds) {
|
||||||
List<Bitstream> streams = bund.getBitstreams();
|
List<Bitstream> streams = bund.getBitstreams();
|
||||||
|
|
||||||
@@ -554,7 +578,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
|
|
||||||
prov.append(installItemService.getBitstreamProvenanceMessage(context, item));
|
prov.append(installItemService.getBitstreamProvenanceMessage(context, item));
|
||||||
|
|
||||||
addMetadata(context, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en", prov.toString());
|
addMetadata(context, item, MetadataSchemaEnum.DC.getName(), "description", "provenance", "en", prov.toString());
|
||||||
|
|
||||||
// Update item in DB
|
// Update item in DB
|
||||||
update(context, item);
|
update(context, item);
|
||||||
@@ -609,7 +633,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
// bitstream checksums
|
// bitstream checksums
|
||||||
prov.append(installItemService.getBitstreamProvenanceMessage(context, item));
|
prov.append(installItemService.getBitstreamProvenanceMessage(context, item));
|
||||||
|
|
||||||
addMetadata(context, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en", prov.toString());
|
addMetadata(context, item, MetadataSchemaEnum.DC.getName(), "description", "provenance", "en", prov.toString());
|
||||||
|
|
||||||
// Update item in DB
|
// Update item in DB
|
||||||
update(context, item);
|
update(context, item);
|
||||||
@@ -671,6 +695,11 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
log.info(LogManager.getHeader(context, "delete_item", "item_id="
|
log.info(LogManager.getHeader(context, "delete_item", "item_id="
|
||||||
+ item.getID()));
|
+ item.getID()));
|
||||||
|
|
||||||
|
// Remove relationships
|
||||||
|
for (Relationship relationship : relationshipService.findByItem(context, item)) {
|
||||||
|
relationshipService.delete(context, relationship, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove bundles
|
// Remove bundles
|
||||||
removeAllBundles(context, item);
|
removeAllBundles(context, item);
|
||||||
|
|
||||||
@@ -1294,4 +1323,94 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of MetadataValue objects that contains all the regular
|
||||||
|
* metadata of the item passed along in the parameters as well as all the virtual metadata
|
||||||
|
* which will be generated and processed together with the {@link VirtualMetadataPopulator}
|
||||||
|
* by processing the item's relationships
|
||||||
|
* @param item the Item to be processed
|
||||||
|
* @param schema the schema for the metadata field. <em>Must</em> match
|
||||||
|
* the <code>name</code> of an existing metadata schema.
|
||||||
|
* @param element the element name. <code>DSpaceObject.ANY</code> matches any
|
||||||
|
* element. <code>null</code> doesn't really make sense as all
|
||||||
|
* metadata must have an element.
|
||||||
|
* @param qualifier the qualifier. <code>null</code> means unqualified, and
|
||||||
|
* <code>DSpaceObject.ANY</code> means any qualifier (including
|
||||||
|
* unqualified.)
|
||||||
|
* @param lang the ISO639 language code, optionally followed by an underscore
|
||||||
|
* and the ISO3166 country code. <code>null</code> means only
|
||||||
|
* values with no language are returned, and
|
||||||
|
* <code>DSpaceObject.ANY</code> means values with any country code or
|
||||||
|
* no country code are returned.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang) {
|
||||||
|
return this.getMetadata(item, schema, element, qualifier, lang, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
|
||||||
|
boolean enableVirtualMetadata) {
|
||||||
|
//Fields of the relation schema are virtual metadata
|
||||||
|
//except for relation.type which is the type of item in the model
|
||||||
|
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) {
|
||||||
|
|
||||||
|
List<RelationshipMetadataValue> relationMetadata = relationshipMetadataService
|
||||||
|
.getRelationshipMetadata(item, false);
|
||||||
|
List<MetadataValue> listToReturn = new LinkedList<>();
|
||||||
|
for (MetadataValue metadataValue : relationMetadata) {
|
||||||
|
if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) {
|
||||||
|
listToReturn.add(metadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listToReturn = sortMetadataValueList(listToReturn);
|
||||||
|
|
||||||
|
return listToReturn;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
List<MetadataValue> dbMetadataValues = super.getMetadata(item, schema, element, qualifier, lang);
|
||||||
|
|
||||||
|
List<MetadataValue> fullMetadataValueList = new LinkedList<>();
|
||||||
|
if (enableVirtualMetadata) {
|
||||||
|
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
|
||||||
|
|
||||||
|
}
|
||||||
|
fullMetadataValueList.addAll(dbMetadataValues);
|
||||||
|
|
||||||
|
List<MetadataValue> finalList = new LinkedList<>();
|
||||||
|
for (MetadataValue metadataValue : fullMetadataValueList) {
|
||||||
|
if (match(schema, element, qualifier, lang, metadataValue)) {
|
||||||
|
finalList.add(metadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalList = sortMetadataValueList(finalList);
|
||||||
|
return finalList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element,
|
||||||
|
* MetadataField Qualifier and MetadataField Place in that order.
|
||||||
|
* @param listToReturn The list to be sorted
|
||||||
|
* @return The list sorted on those criteria
|
||||||
|
*/
|
||||||
|
private List<MetadataValue> sortMetadataValueList(List<MetadataValue> listToReturn) {
|
||||||
|
Comparator<MetadataValue> comparator = Comparator.comparing(
|
||||||
|
metadataValue -> metadataValue.getMetadataField().getMetadataSchema().getName(),
|
||||||
|
Comparator.nullsFirst(Comparator.naturalOrder()));
|
||||||
|
comparator = comparator.thenComparing(metadataValue -> metadataValue.getMetadataField().getElement(),
|
||||||
|
Comparator.nullsFirst(Comparator.naturalOrder()));
|
||||||
|
comparator = comparator.thenComparing(metadataValue -> metadataValue.getMetadataField().getQualifier(),
|
||||||
|
Comparator.nullsFirst(Comparator.naturalOrder()));
|
||||||
|
comparator = comparator.thenComparing(metadataValue -> metadataValue.getPlace(),
|
||||||
|
Comparator.nullsFirst(Comparator.naturalOrder()));
|
||||||
|
|
||||||
|
Stream<MetadataValue> metadataValueStream = listToReturn.stream().sorted(comparator);
|
||||||
|
listToReturn = metadataValueStream.collect(Collectors.toList());
|
||||||
|
return listToReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -39,10 +39,6 @@ import org.hibernate.proxy.HibernateProxyHelper;
|
|||||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
|
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
|
||||||
@Table(name = "metadataschemaregistry")
|
@Table(name = "metadataschemaregistry")
|
||||||
public class MetadataSchema implements ReloadableEntity<Integer> {
|
public class MetadataSchema implements ReloadableEntity<Integer> {
|
||||||
/**
|
|
||||||
* Short Name of built-in Dublin Core schema.
|
|
||||||
*/
|
|
||||||
public static final String DC_SCHEMA = "dc";
|
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "metadata_schema_id")
|
@Column(name = "metadata_schema_id")
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an enum that holds track of a few special MetadataSchema types.
|
||||||
|
* It is important to note that this list is not exhaustive for the MetadataSchema
|
||||||
|
* types and different MetadataSchema can easily be made.
|
||||||
|
* These MetadataSchema objects are simply required.
|
||||||
|
*/
|
||||||
|
public enum MetadataSchemaEnum {
|
||||||
|
DC("dc"), RELATION("relation");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The String representation of the MetadataSchemaEnum
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor with the name parameter
|
||||||
|
* @param name The name parameter
|
||||||
|
*/
|
||||||
|
MetadataSchemaEnum(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the String representation of the enum object
|
||||||
|
* @return The name of the enum object
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@@ -71,6 +71,12 @@ public class MetadataValueServiceImpl implements MetadataValueService {
|
|||||||
return metadataValueDAO.findByField(context, metadataField);
|
return metadataValueDAO.findByField(context, metadataField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<MetadataValue> findByFieldAndValue(Context context, MetadataField metadataField, String value)
|
||||||
|
throws SQLException {
|
||||||
|
return metadataValueDAO.findItemValuesByFieldAndValue(context, metadataField, value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Context context, MetadataValue metadataValue) throws SQLException {
|
public void update(Context context, MetadataValue metadataValue) throws SQLException {
|
||||||
metadataValueDAO.save(context, metadataValue);
|
metadataValueDAO.save(context, metadataValue);
|
||||||
|
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Enum holds a representation of all the possible states that a Process can be in
|
||||||
|
*/
|
||||||
|
public enum ProcessStatus {
|
||||||
|
SCHEDULED,
|
||||||
|
RUNNING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED
|
||||||
|
|
||||||
|
}
|
224
dspace-api/src/main/java/org/dspace/content/Relationship.java
Normal file
224
dspace-api/src/main/java/org/dspace/content/Relationship.java
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.ReloadableEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a relationship
|
||||||
|
* It has a leftItem and a rightItem which are both DSpaceObjects
|
||||||
|
* that have a specified RelationshipType that links them together
|
||||||
|
* It also has a left and right place column that works just like a normal DSpace metadata place column
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "relationship")
|
||||||
|
public class Relationship implements ReloadableEntity<Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Integer ID field for this object
|
||||||
|
* This is automatically generated
|
||||||
|
*/
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "relationship_id_seq")
|
||||||
|
@SequenceGenerator(name = "relationship_id_seq", sequenceName = "relationship_id_seq", allocationSize = 1)
|
||||||
|
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)
|
||||||
|
protected Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The leftItem property for the Relationship object.
|
||||||
|
* This leftItem is a DSpaceObject and is stored as an ID
|
||||||
|
*/
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "left_id", nullable = false)
|
||||||
|
private Item leftItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The relationshipType property for this Relationship object
|
||||||
|
* This is stored as an ID in the database
|
||||||
|
*/
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "type_id", nullable = false)
|
||||||
|
private RelationshipType relationshipType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rightItem property for the Relationship object.
|
||||||
|
* This rightItem is a DSpaceObject and is stored as an ID
|
||||||
|
*/
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "right_id", nullable = false)
|
||||||
|
private Item rightItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Integer to describe the left place for this relationship
|
||||||
|
*/
|
||||||
|
@Column(name = "left_place")
|
||||||
|
private int leftPlace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Integer to describe the right place for this relationship
|
||||||
|
*/
|
||||||
|
@Column(name = "right_place")
|
||||||
|
private int rightPlace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String containing an alternative value (name variant) for the left side
|
||||||
|
*/
|
||||||
|
@Column(name = "leftward_value")
|
||||||
|
private String leftwardValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String containing an alternative value (name variant) for the right side
|
||||||
|
*/
|
||||||
|
@Column(name = "rightward_value")
|
||||||
|
private String rightwardValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor, create object using:
|
||||||
|
* {@link org.dspace.content.service.RelationshipService#create(Context)} }
|
||||||
|
*/
|
||||||
|
protected Relationship() {}
|
||||||
|
/**
|
||||||
|
* Standard setter for the ID field
|
||||||
|
* @param id The ID to be set
|
||||||
|
*/
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftItem field
|
||||||
|
* @return The leftItem Item object in this relationship
|
||||||
|
*/
|
||||||
|
public Item getLeftItem() {
|
||||||
|
return leftItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftItem field
|
||||||
|
* @param leftItem The leftItem Item object that the leftItem field should be set to
|
||||||
|
*/
|
||||||
|
public void setLeftItem(Item leftItem) {
|
||||||
|
this.leftItem = leftItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the relationshipType field
|
||||||
|
* @return The relationshipType RelationshipType object in this relationship
|
||||||
|
*/
|
||||||
|
public RelationshipType getRelationshipType() {
|
||||||
|
return relationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the relationshipType field for the Relationship
|
||||||
|
* @param relationshipType The relationshipType that will be set in this Relationship
|
||||||
|
*/
|
||||||
|
public void setRelationshipType(RelationshipType relationshipType) {
|
||||||
|
this.relationshipType = relationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightItem Item object in this Relationship
|
||||||
|
* @return the rightItem Item object
|
||||||
|
*/
|
||||||
|
public Item getRightItem() {
|
||||||
|
return rightItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightItem Item object in this Relationship
|
||||||
|
* @param rightItem The rightItem Item object that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setRightItem(Item rightItem) {
|
||||||
|
this.rightItem = rightItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftPlace Integer in this Relationship
|
||||||
|
* @return The leftPlace integer for this relationship
|
||||||
|
*/
|
||||||
|
public int getLeftPlace() {
|
||||||
|
return leftPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftPlace Integer in this Relationship
|
||||||
|
* @param leftPlace the leftPlace Integer that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setLeftPlace(int leftPlace) {
|
||||||
|
this.leftPlace = leftPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightPlace Integer in this Relationship
|
||||||
|
* @return the rightPlace integer for this relationship
|
||||||
|
*/
|
||||||
|
public int getRightPlace() {
|
||||||
|
return rightPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightPlace Integer in this Relationship
|
||||||
|
* @param rightPlace the rightPlace Integer that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setRightPlace(int rightPlace) {
|
||||||
|
this.rightPlace = rightPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftwardValue String in this Relationship
|
||||||
|
* @return the leftwardValue String for this relationship
|
||||||
|
*/
|
||||||
|
public String getLeftwardValue() {
|
||||||
|
return leftwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftwardValue String in this Relationship
|
||||||
|
* @param leftwardValue the leftwardValue String that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setLeftwardValue(String leftwardValue) {
|
||||||
|
this.leftwardValue = leftwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightwardValue String in this Relationship
|
||||||
|
* @return the rightwardValue string for this relationship
|
||||||
|
*/
|
||||||
|
public String getRightwardValue() {
|
||||||
|
return rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightwardValue String in this Relationship
|
||||||
|
* @param rightwardValue the rightwardValue String that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setRightwardValue(String rightwardValue) {
|
||||||
|
this.rightwardValue = rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the ID for this Relationship
|
||||||
|
* @return The ID of this relationship
|
||||||
|
*/
|
||||||
|
public Integer getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used for the {@link RelationshipMetadataServiceImpl}
|
||||||
|
* This will define methods regarding the RelationshipMetadata
|
||||||
|
*/
|
||||||
|
public interface RelationshipMetadataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method retrieves a list of MetadataValue objects that get constructed from processing
|
||||||
|
* the given Item's Relationships through the config given to the {@link VirtualMetadataPopulator}
|
||||||
|
* @param item The Item that will be processed through it's Relationships
|
||||||
|
* @param enableVirtualMetadata This parameter will determine whether the list of Relationship metadata
|
||||||
|
* should be populated with metadata that is being generated through the
|
||||||
|
* VirtualMetadataPopulator functionality or not
|
||||||
|
* @return The list of MetadataValue objects constructed through the Relationships
|
||||||
|
*/
|
||||||
|
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of RelationshipMetadataValue objects specific to only one Relationship of the item.
|
||||||
|
*
|
||||||
|
* This method processes one Relationship of an Item and will return a list of RelationshipMetadataValue objects
|
||||||
|
* that are generated for this specific relationship for the item through the config in VirtualMetadataPopulator
|
||||||
|
*
|
||||||
|
* It returns a combination of the output of the findVirtualMetadataFromConfiguration method and
|
||||||
|
* the getRelationMetadataFromOtherItem method.
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param entityType The entity type of the given item
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param enableVirtualMetadata Determines whether the VirtualMetadataPopulator should be used.
|
||||||
|
* If false, only the relation."relationname" metadata is populated
|
||||||
|
* If true, fields from the spring config virtual metadata is included as well
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
public List<RelationshipMetadataValue> findRelationshipMetadataValueForItemRelationship(
|
||||||
|
Context context, Item item, String entityType, Relationship relationship, boolean enableVirtualMetadata)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will retrieve the EntityType String from an item
|
||||||
|
* @param item The Item for which the entityType String will be returned
|
||||||
|
* @return A String value indicating the entityType
|
||||||
|
*/
|
||||||
|
public String getEntityTypeStringFromMetadata(Item item);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,276 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataConfiguration;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class RelationshipMetadataServiceImpl implements RelationshipMetadataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log4j category
|
||||||
|
*/
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger();
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipService relationshipService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected MetadataFieldService metadataFieldService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata) {
|
||||||
|
Context context = new Context();
|
||||||
|
List<RelationshipMetadataValue> fullMetadataValueList = new LinkedList<>();
|
||||||
|
try {
|
||||||
|
String entityType = getEntityTypeStringFromMetadata(item);
|
||||||
|
if (StringUtils.isNotBlank(entityType)) {
|
||||||
|
List<Relationship> relationships = relationshipService.findByItem(context, item);
|
||||||
|
for (Relationship relationship : relationships) {
|
||||||
|
fullMetadataValueList
|
||||||
|
.addAll(findRelationshipMetadataValueForItemRelationship(context, item, entityType,
|
||||||
|
relationship, enableVirtualMetadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Lookup for Relationships for item with uuid: " + item.getID() + " caused DSpace to crash", e);
|
||||||
|
}
|
||||||
|
return fullMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntityTypeStringFromMetadata(Item item) {
|
||||||
|
List<MetadataValue> list = item.getMetadata();
|
||||||
|
for (MetadataValue mdv : list) {
|
||||||
|
if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(),
|
||||||
|
"relationship")
|
||||||
|
&& StringUtils.equals(mdv.getMetadataField().getElement(),
|
||||||
|
"type")) {
|
||||||
|
|
||||||
|
return mdv.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipMetadataValue> findRelationshipMetadataValueForItemRelationship(
|
||||||
|
Context context, Item item, String entityType, Relationship relationship, boolean enableVirtualMetadata)
|
||||||
|
throws SQLException {
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||||
|
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
||||||
|
String relationName;
|
||||||
|
Item otherItem;
|
||||||
|
int place = 0;
|
||||||
|
boolean isLeftwards;
|
||||||
|
if (StringUtils.equals(relationshipType.getLeftType().getLabel(), entityType)) {
|
||||||
|
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getLeftwardType());
|
||||||
|
otherItem = relationship.getRightItem();
|
||||||
|
relationName = relationship.getRelationshipType().getLeftwardType();
|
||||||
|
place = relationship.getLeftPlace();
|
||||||
|
isLeftwards = false; //if the current item is stored on the left,
|
||||||
|
// the name variant is retrieved from the rightwards label
|
||||||
|
} else if (StringUtils.equals(relationshipType.getRightType().getLabel(), entityType)) {
|
||||||
|
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getRightwardType());
|
||||||
|
otherItem = relationship.getLeftItem();
|
||||||
|
relationName = relationship.getRelationshipType().getRightwardType();
|
||||||
|
place = relationship.getRightPlace();
|
||||||
|
isLeftwards = true; //if the current item is stored on the right,
|
||||||
|
// the name variant is retrieved from the leftwards label
|
||||||
|
} else {
|
||||||
|
//No virtual metadata can be created
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashMaps != null && enableVirtualMetadata) {
|
||||||
|
resultingMetadataValueList.addAll(findVirtualMetadataFromConfiguration(context, item, hashMaps,
|
||||||
|
otherItem, relationName,
|
||||||
|
relationship, place, isLeftwards));
|
||||||
|
}
|
||||||
|
RelationshipMetadataValue relationMetadataFromOtherItem =
|
||||||
|
getRelationMetadataFromOtherItem(context, otherItem, relationName, relationship.getID(), place);
|
||||||
|
if (relationMetadataFromOtherItem != null) {
|
||||||
|
resultingMetadataValueList.add(relationMetadataFromOtherItem);
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the
|
||||||
|
* hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects
|
||||||
|
* and the keys of the hashmap will be used to construct the RelationshipMetadataValue object.
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param hashMaps The list of VirtualMetadataConfiguration objects which will generate the
|
||||||
|
* virtual metadata. These configurations are applicable for a relationship
|
||||||
|
* between both items
|
||||||
|
* @param otherItem The related item whose actual metadata is requested
|
||||||
|
* @param relationName The name of the relationship
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param place The place to use in the virtual metadata
|
||||||
|
* @param isLeftwards Determines the direction of the virtual metadata
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
private List<RelationshipMetadataValue> findVirtualMetadataFromConfiguration(Context context, Item item,
|
||||||
|
HashMap<String, VirtualMetadataConfiguration> hashMaps, Item otherItem, String relationName,
|
||||||
|
Relationship relationship, int place, boolean isLeftwards) throws SQLException {
|
||||||
|
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
VirtualMetadataConfiguration virtualBean = entry.getValue();
|
||||||
|
|
||||||
|
if (virtualBean.getPopulateWithNameVariant()) {
|
||||||
|
String wardLabel = isLeftwards ? relationship.getLeftwardValue() : relationship.getRightwardValue();
|
||||||
|
if (wardLabel != null) {
|
||||||
|
resultingMetadataValueList.add(
|
||||||
|
constructRelationshipMetadataValue(context, item, relationship.getID(), place, key, virtualBean,
|
||||||
|
wardLabel));
|
||||||
|
} else {
|
||||||
|
resultingMetadataValueList.addAll(
|
||||||
|
findRelationshipMetadataValueFromBean(context, item, otherItem, relationship, place, key,
|
||||||
|
virtualBean));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultingMetadataValueList.addAll(
|
||||||
|
findRelationshipMetadataValueFromBean(context, item, otherItem, relationship, place, key,
|
||||||
|
virtualBean));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the
|
||||||
|
* hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects
|
||||||
|
* and the keys of the hashmap will be used to construct the RelationshipMetadataValue object.
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param otherItem The related item whose actual metadata is requested
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param place The place to use in the virtual metadata
|
||||||
|
* @param key The key corresponding to the VirtualMetadataConfiguration
|
||||||
|
* @param virtualBean The VirtualMetadataConfiguration object which will generate the
|
||||||
|
* virtual metadata. This configuration is applicable for a relationship
|
||||||
|
* between both items
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
private List<RelationshipMetadataValue> findRelationshipMetadataValueFromBean(
|
||||||
|
Context context, Item item, Item otherItem, Relationship relationship, int place,
|
||||||
|
String key, VirtualMetadataConfiguration virtualBean) throws SQLException {
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
for (String value : virtualBean.getValues(context, otherItem)) {
|
||||||
|
RelationshipMetadataValue relationshipMetadataValue = constructRelationshipMetadataValue(context, item,
|
||||||
|
relationship
|
||||||
|
.getID(),
|
||||||
|
place,
|
||||||
|
key, virtualBean,
|
||||||
|
value);
|
||||||
|
if (relationshipMetadataValue != null) {
|
||||||
|
resultingMetadataValueList.add(relationshipMetadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This method will construct a RelationshipMetadataValue object with proper schema, element, qualifier,
|
||||||
|
//authority, item, place and useForPlace based on the key String parameter passed along to it
|
||||||
|
private RelationshipMetadataValue constructRelationshipMetadataValue(Context context, Item item,
|
||||||
|
Integer relationshipId, int place,
|
||||||
|
String key,
|
||||||
|
VirtualMetadataConfiguration virtualBean,
|
||||||
|
String value) {
|
||||||
|
RelationshipMetadataValue metadataValue = constructMetadataValue(context, key);
|
||||||
|
if (metadataValue != null) {
|
||||||
|
metadataValue = constructResultingMetadataValue(item, value, metadataValue, relationshipId);
|
||||||
|
metadataValue.setUseForPlace(virtualBean.getUseForPlace());
|
||||||
|
metadataValue.setPlace(place);
|
||||||
|
if (StringUtils.isNotBlank(metadataValue.getValue())) {
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This method will construct a RelationshipMetadataValue object with proper schema, element and qualifier based
|
||||||
|
//on the key String parameter passed along to it
|
||||||
|
private RelationshipMetadataValue constructMetadataValue(Context context, String key) {
|
||||||
|
String[] splittedKey = key.split("\\.");
|
||||||
|
RelationshipMetadataValue metadataValue = new RelationshipMetadataValue();
|
||||||
|
String metadataSchema = splittedKey.length > 0 ? splittedKey[0] : null;
|
||||||
|
String metadataElement = splittedKey.length > 1 ? splittedKey[1] : null;
|
||||||
|
String metadataQualifier = splittedKey.length > 2 ? splittedKey[2] : null;
|
||||||
|
MetadataField metadataField = null;
|
||||||
|
try {
|
||||||
|
metadataField = metadataFieldService
|
||||||
|
.findByElement(context, metadataSchema, metadataElement, metadataQualifier);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Could not find element with MetadataSchema: " + metadataSchema +
|
||||||
|
", MetadataElement: " + metadataElement + " and MetadataQualifier: " + metadataQualifier, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (metadataField == null) {
|
||||||
|
log.error("A MetadataValue was attempted to construct with MetadataField for parameters: " +
|
||||||
|
"metadataschema: {}, metadataelement: {}, metadataqualifier: {}",
|
||||||
|
metadataSchema, metadataElement, metadataQualifier);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
metadataValue.setMetadataField(metadataField);
|
||||||
|
metadataValue.setLanguage(Item.ANY);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//This method will update a RelationshipMetadataValue object with authority info and relation to the item
|
||||||
|
private RelationshipMetadataValue constructResultingMetadataValue(Item item, String value,
|
||||||
|
RelationshipMetadataValue metadataValue,
|
||||||
|
Integer relationshipId) {
|
||||||
|
metadataValue.setValue(value);
|
||||||
|
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
||||||
|
metadataValue.setConfidence(-1);
|
||||||
|
metadataValue.setDSpaceObject(item);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method will create the Relationship Metadatavalue that describes the relationship type and has the ID
|
||||||
|
// of the other item as value
|
||||||
|
private RelationshipMetadataValue getRelationMetadataFromOtherItem(Context context, Item otherItem,
|
||||||
|
String relationName,
|
||||||
|
Integer relationshipId, int place) {
|
||||||
|
RelationshipMetadataValue metadataValue = constructMetadataValue(context,
|
||||||
|
MetadataSchemaEnum.RELATION
|
||||||
|
.getName() + "." + relationName);
|
||||||
|
if (metadataValue != null) {
|
||||||
|
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
||||||
|
metadataValue.setValue(otherItem.getID().toString());
|
||||||
|
metadataValue.setPlace(place);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used as a representation of MetadataValues for the MetadataValues that are derived from the
|
||||||
|
* Relationships that the item has. This includes the useForPlace property which we'll have to use to determine
|
||||||
|
* whether these Values should be counted for place calculation on both the native MetadataValues and the
|
||||||
|
* Relationship's place attributes.
|
||||||
|
*/
|
||||||
|
public class RelationshipMetadataValue extends MetadataValue {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This property determines whether this RelationshipMetadataValue should be used in place calculation or not
|
||||||
|
*/
|
||||||
|
private boolean useForPlace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This property determines whether this RelationshipMetadataValue should be used in place calculation or not.
|
||||||
|
* This is retrieved from Spring configuration when constructing RelationshipMetadataValues. This Spring
|
||||||
|
* configuration is located in the core-services.xml configuration file.
|
||||||
|
* Putting this property on true will imply that we're now mixing plain-text metadatavalues with the
|
||||||
|
* metadatavalues that are constructed through Relationships with regards to the place attribute.
|
||||||
|
* For example, currently the RelationshipMetadataValue dc.contributor.author that is constructed through a
|
||||||
|
* Relationship for a Publication will have its useForPlace set to true. This means that the place
|
||||||
|
* calculation will take both these RelationshipMetadataValues into account together with the normal
|
||||||
|
* plain text metadatavalues.
|
||||||
|
* On the other hand, the journal name, volume and issue number which are constructed through a
|
||||||
|
* Relationship from a Publication to a journal issue will have its useForPlace set to false.
|
||||||
|
* This would typically be set to false for any singular metadata, and for any relationship where no mixing
|
||||||
|
* with plain text variables is applicable
|
||||||
|
*/
|
||||||
|
public boolean isUseForPlace() {
|
||||||
|
return useForPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseForPlace(boolean useForPlace) {
|
||||||
|
this.useForPlace = useForPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! (obj instanceof RelationshipMetadataValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final RelationshipMetadataValue other = (RelationshipMetadataValue) obj;
|
||||||
|
if (this.isUseForPlace() != other.isUseForPlace()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.equals(obj);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,540 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.dao.RelationshipDAO;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class RelationshipServiceImpl implements RelationshipService {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipDAO relationshipDAO;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected ItemService itemService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipTypeService relationshipTypeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RelationshipMetadataService relationshipMetadataService;
|
||||||
|
@Autowired
|
||||||
|
private VirtualMetadataPopulator virtualMetadataPopulator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Relationship create(Context context) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify relationship");
|
||||||
|
}
|
||||||
|
return relationshipDAO.create(context, new Relationship());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
|
int leftPlace, int rightPlace) throws AuthorizeException, SQLException {
|
||||||
|
return create(c, leftItem, rightItem, relationshipType, leftPlace, rightPlace, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
|
int leftPlace, int rightPlace, String leftwardValue, String rightwardValue)
|
||||||
|
throws AuthorizeException, SQLException {
|
||||||
|
Relationship relationship = new Relationship();
|
||||||
|
relationship.setLeftItem(leftItem);
|
||||||
|
relationship.setRightItem(rightItem);
|
||||||
|
relationship.setRelationshipType(relationshipType);
|
||||||
|
relationship.setLeftPlace(leftPlace);
|
||||||
|
relationship.setRightPlace(rightPlace);
|
||||||
|
relationship.setLeftwardValue(leftwardValue);
|
||||||
|
relationship.setRightwardValue(rightwardValue);
|
||||||
|
return create(c, relationship);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Relationship create(Context context, Relationship relationship) throws SQLException, AuthorizeException {
|
||||||
|
if (isRelationshipValidToCreate(context, relationship)) {
|
||||||
|
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
|
||||||
|
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||||
|
// This order of execution should be handled in the creation (create, updateplace, update relationship)
|
||||||
|
// for a proper place allocation
|
||||||
|
Relationship relationshipToReturn = relationshipDAO.create(context, relationship);
|
||||||
|
updatePlaceInRelationship(context, relationshipToReturn);
|
||||||
|
update(context, relationshipToReturn);
|
||||||
|
return relationshipToReturn;
|
||||||
|
} else {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"You do not have write rights on this relationship's items");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("The relationship given was not valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePlaceInRelationship(Context context, Relationship relationship)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
Item leftItem = relationship.getLeftItem();
|
||||||
|
// Max value is used to ensure that these will get added to the back of the list and thus receive the highest
|
||||||
|
// (last) place as it's set to a -1 for creation
|
||||||
|
if (relationship.getLeftPlace() == -1) {
|
||||||
|
relationship.setLeftPlace(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
Item rightItem = relationship.getRightItem();
|
||||||
|
if (relationship.getRightPlace() == -1) {
|
||||||
|
relationship.setRightPlace(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
List<Relationship> leftRelationships = findByItemAndRelationshipType(context,
|
||||||
|
leftItem,
|
||||||
|
relationship.getRelationshipType(), true);
|
||||||
|
List<Relationship> rightRelationships = findByItemAndRelationshipType(context,
|
||||||
|
rightItem,
|
||||||
|
relationship.getRelationshipType(),
|
||||||
|
false);
|
||||||
|
|
||||||
|
// These relationships are only deleted from the temporary lists incase they're present in them so that we can
|
||||||
|
// properly perform our place calculation later down the line in this method.
|
||||||
|
if (leftRelationships.contains(relationship)) {
|
||||||
|
leftRelationships.remove(relationship);
|
||||||
|
}
|
||||||
|
if (rightRelationships.contains(relationship)) {
|
||||||
|
rightRelationships.remove(relationship);
|
||||||
|
}
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
//If useForPlace for the leftwardType is false for the relationshipType,
|
||||||
|
// we need to sort the relationships here based on leftplace.
|
||||||
|
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), true)) {
|
||||||
|
if (!leftRelationships.isEmpty()) {
|
||||||
|
leftRelationships.sort(Comparator.comparingInt(Relationship::getLeftPlace));
|
||||||
|
for (int i = 0; i < leftRelationships.size(); i++) {
|
||||||
|
leftRelationships.get(i).setLeftPlace(i);
|
||||||
|
}
|
||||||
|
relationship.setLeftPlace(leftRelationships.size());
|
||||||
|
} else {
|
||||||
|
relationship.setLeftPlace(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateItem(context, leftItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//If useForPlace for the rightwardType is false for the relationshipType,
|
||||||
|
// we need to sort the relationships here based on the rightplace.
|
||||||
|
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), false)) {
|
||||||
|
if (!rightRelationships.isEmpty()) {
|
||||||
|
rightRelationships.sort(Comparator.comparingInt(Relationship::getRightPlace));
|
||||||
|
for (int i = 0; i < rightRelationships.size(); i++) {
|
||||||
|
rightRelationships.get(i).setRightPlace(i);
|
||||||
|
}
|
||||||
|
relationship.setRightPlace(rightRelationships.size());
|
||||||
|
} else {
|
||||||
|
relationship.setRightPlace(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
updateItem(context, rightItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(Context context, Item relatedItem)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
relatedItem.setMetadataModified();
|
||||||
|
itemService.update(context, relatedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||||
|
return relationshipDAO.findNextLeftPlaceByLeftItem(context, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||||
|
return relationshipDAO.findNextRightPlaceByRightItem(context, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRelationshipValidToCreate(Context context, Relationship relationship) throws SQLException {
|
||||||
|
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||||
|
|
||||||
|
if (!verifyEntityTypes(relationship.getLeftItem(), relationshipType.getLeftType())) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the leftItem" +
|
||||||
|
" and leftType do no match on entityType");
|
||||||
|
logRelationshipTypeDetailsForError(relationshipType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!verifyEntityTypes(relationship.getRightItem(), relationshipType.getRightType())) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the rightItem" +
|
||||||
|
" and rightType do no match on entityType");
|
||||||
|
logRelationshipTypeDetailsForError(relationshipType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!verifyMaxCardinality(context, relationship.getLeftItem(),
|
||||||
|
relationshipType.getLeftMaxCardinality(), relationshipType)) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the left item has more" +
|
||||||
|
" relationships than the left max cardinality allows after we'd store this relationship");
|
||||||
|
logRelationshipTypeDetailsForError(relationshipType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!verifyMaxCardinality(context, relationship.getRightItem(),
|
||||||
|
relationshipType.getRightMaxCardinality(), relationshipType)) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the right item has more" +
|
||||||
|
" relationships than the right max cardinality allows after we'd store this relationship");
|
||||||
|
logRelationshipTypeDetailsForError(relationshipType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logRelationshipTypeDetailsForError(RelationshipType relationshipType) {
|
||||||
|
log.warn("The relationshipType's ID is: " + relationshipType.getID());
|
||||||
|
log.warn("The relationshipType's leftward type is: " + relationshipType.getLeftwardType());
|
||||||
|
log.warn("The relationshipType's rightward type is: " + relationshipType.getRightwardType());
|
||||||
|
log.warn("The relationshipType's left entityType label is: " + relationshipType.getLeftType().getLabel());
|
||||||
|
log.warn("The relationshipType's right entityType label is: " + relationshipType.getRightType().getLabel());
|
||||||
|
log.warn("The relationshipType's left min cardinality is: " + relationshipType.getLeftMinCardinality());
|
||||||
|
log.warn("The relationshipType's left max cardinality is: " + relationshipType.getLeftMaxCardinality());
|
||||||
|
log.warn("The relationshipType's right min cardinality is: " + relationshipType.getRightMinCardinality());
|
||||||
|
log.warn("The relationshipType's right max cardinality is: " + relationshipType.getRightMaxCardinality());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean verifyMaxCardinality(Context context, Item itemToProcess,
|
||||||
|
Integer maxCardinality,
|
||||||
|
RelationshipType relationshipType) throws SQLException {
|
||||||
|
List<Relationship> rightRelationships = findByItemAndRelationshipType(context, itemToProcess, relationshipType,
|
||||||
|
false);
|
||||||
|
if (maxCardinality != null && rightRelationships.size() >= maxCardinality) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean verifyEntityTypes(Item itemToProcess, EntityType entityTypeToProcess) {
|
||||||
|
List<MetadataValue> list = itemService.getMetadata(itemToProcess, "relationship", "type", null, Item.ANY);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String leftEntityType = list.get(0).getValue();
|
||||||
|
return StringUtils.equals(leftEntityType, entityTypeToProcess.getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Relationship find(Context context, int id) throws SQLException {
|
||||||
|
Relationship relationship = relationshipDAO.findByID(context, Relationship.class, id);
|
||||||
|
return relationship;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
|
||||||
|
|
||||||
|
return findByItem(context, item, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
List<Relationship> list = relationshipDAO.findByItem(context, item, limit, offset);
|
||||||
|
|
||||||
|
list.sort((o1, o2) -> {
|
||||||
|
int relationshipType = o1.getRelationshipType().getLeftwardType()
|
||||||
|
.compareTo(o2.getRelationshipType().getLeftwardType());
|
||||||
|
if (relationshipType != 0) {
|
||||||
|
return relationshipType;
|
||||||
|
} else {
|
||||||
|
if (o1.getLeftItem() == item) {
|
||||||
|
return o1.getLeftPlace() - o2.getLeftPlace();
|
||||||
|
} else {
|
||||||
|
return o1.getRightPlace() - o2.getRightPlace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findAll(Context context) throws SQLException {
|
||||||
|
return findAll(context, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||||
|
return relationshipDAO.findAll(context, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context, Relationship relationship) throws SQLException, AuthorizeException {
|
||||||
|
update(context, Collections.singletonList(relationship));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context, List<Relationship> relationships) throws SQLException, AuthorizeException {
|
||||||
|
if (CollectionUtils.isNotEmpty(relationships)) {
|
||||||
|
for (Relationship relationship : relationships) {
|
||||||
|
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
|
||||||
|
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||||
|
if (isRelationshipValidToCreate(context, relationship)) {
|
||||||
|
relationshipDAO.save(context, relationship);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new AuthorizeException("You do not have write rights on this relationship's items");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context, Relationship relationship) throws SQLException, AuthorizeException {
|
||||||
|
//TODO: retrieve default settings from configuration
|
||||||
|
delete(context, relationship, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context, Relationship relationship, boolean copyToLeftItem, boolean copyToRightItem)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
log.info(org.dspace.core.LogManager.getHeader(context, "delete_relationship",
|
||||||
|
"relationship_id=" + relationship.getID() + "&" +
|
||||||
|
"copyMetadataValuesToLeftItem=" + copyToLeftItem + "&" +
|
||||||
|
"copyMetadataValuesToRightItem=" + copyToRightItem));
|
||||||
|
if (isRelationshipValidToDelete(context, relationship) &&
|
||||||
|
copyToItemPermissionCheck(context, relationship, copyToLeftItem, copyToRightItem)) {
|
||||||
|
// To delete a relationship, a user must have WRITE permissions on one of the related Items
|
||||||
|
copyMetadataValues(context, relationship, copyToLeftItem, copyToRightItem);
|
||||||
|
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
|
||||||
|
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||||
|
relationshipDAO.delete(context, relationship);
|
||||||
|
updatePlaceInRelationship(context, relationship);
|
||||||
|
} else {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"You do not have write rights on this relationship's items");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("The relationship given was not valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts virtual metadata from RelationshipMetadataValue objects to actual item metadata.
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationship The relationship containing the left and right items
|
||||||
|
* @param copyToLeftItem The boolean indicating whether we want to write to left item or not
|
||||||
|
* @param copyToRightItem The boolean indicating whether we want to write to right item or not
|
||||||
|
*/
|
||||||
|
private void copyMetadataValues(Context context, Relationship relationship, boolean copyToLeftItem,
|
||||||
|
boolean copyToRightItem)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
if (copyToLeftItem) {
|
||||||
|
String entityTypeString = relationshipMetadataService
|
||||||
|
.getEntityTypeStringFromMetadata(relationship.getLeftItem());
|
||||||
|
List<RelationshipMetadataValue> relationshipMetadataValues =
|
||||||
|
relationshipMetadataService.findRelationshipMetadataValueForItemRelationship(context,
|
||||||
|
relationship.getLeftItem(), entityTypeString, relationship, true);
|
||||||
|
for (RelationshipMetadataValue relationshipMetadataValue : relationshipMetadataValues) {
|
||||||
|
itemService.addMetadata(context, relationship.getLeftItem(),
|
||||||
|
relationshipMetadataValue.getMetadataField(), null,
|
||||||
|
relationshipMetadataValue.getValue() );
|
||||||
|
}
|
||||||
|
itemService.update(context, relationship.getLeftItem());
|
||||||
|
}
|
||||||
|
if (copyToRightItem) {
|
||||||
|
String entityTypeString = relationshipMetadataService
|
||||||
|
.getEntityTypeStringFromMetadata(relationship.getRightItem());
|
||||||
|
List<RelationshipMetadataValue> relationshipMetadataValues =
|
||||||
|
relationshipMetadataService.findRelationshipMetadataValueForItemRelationship(context,
|
||||||
|
relationship.getRightItem(), entityTypeString, relationship, true);
|
||||||
|
for (RelationshipMetadataValue relationshipMetadataValue : relationshipMetadataValues) {
|
||||||
|
itemService.addMetadata(context, relationship.getRightItem(),
|
||||||
|
relationshipMetadataValue.getMetadataField(), null,
|
||||||
|
relationshipMetadataValue.getValue() );
|
||||||
|
}
|
||||||
|
itemService.update(context, relationship.getRightItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will check if the current user has sufficient rights to write to the respective items if requested
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationship The relationship containing the left and right items
|
||||||
|
* @param copyToLeftItem The boolean indicating whether we want to write to left item or not
|
||||||
|
* @param copyToRightItem The boolean indicating whether we want to write to right item or not
|
||||||
|
* @return A boolean indicating whether the permissions are okay for this request
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
private boolean copyToItemPermissionCheck(Context context, Relationship relationship,
|
||||||
|
boolean copyToLeftItem, boolean copyToRightItem) throws SQLException {
|
||||||
|
boolean isPermissionCorrect = true;
|
||||||
|
if (copyToLeftItem) {
|
||||||
|
if (!authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE)) {
|
||||||
|
isPermissionCorrect = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (copyToRightItem) {
|
||||||
|
if (!authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||||
|
isPermissionCorrect = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isPermissionCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRelationshipValidToDelete(Context context, Relationship relationship) throws SQLException {
|
||||||
|
if (relationship == null) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the relation was null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (relationship.getID() == null) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the ID" +
|
||||||
|
" off the given relationship was null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.find(context, relationship.getID()) == null) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the relationship" +
|
||||||
|
" is not present in the DB with the current ID");
|
||||||
|
logRelationshipTypeDetailsForError(relationship.getRelationshipType());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!checkMinCardinality(context, relationship.getLeftItem(),
|
||||||
|
relationship, relationship.getRelationshipType().getLeftMinCardinality(), true)) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the leftMinCardinality" +
|
||||||
|
" constraint would be violated upon deletion");
|
||||||
|
logRelationshipTypeDetailsForError(relationship.getRelationshipType());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkMinCardinality(context, relationship.getRightItem(),
|
||||||
|
relationship, relationship.getRelationshipType().getRightMinCardinality(), false)) {
|
||||||
|
log.warn("The relationship has been deemed invalid since the rightMinCardinality" +
|
||||||
|
" constraint would be violated upon deletion");
|
||||||
|
logRelationshipTypeDetailsForError(relationship.getRelationshipType());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkMinCardinality(Context context, Item item,
|
||||||
|
Relationship relationship,
|
||||||
|
Integer minCardinality, boolean isLeft) throws SQLException {
|
||||||
|
List<Relationship> list = this.findByItemAndRelationshipType(context, item, relationship.getRelationshipType(),
|
||||||
|
isLeft, -1, -1);
|
||||||
|
if (minCardinality != null && !(list.size() > minCardinality)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType, boolean isLeft)
|
||||||
|
throws SQLException {
|
||||||
|
return this.findByItemAndRelationshipType(context, item, relationshipType, isLeft, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType, int limit, int offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType, boolean isLeft,
|
||||||
|
int limit, int offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, isLeft, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
return findByRelationshipType(context, relationshipType, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType, Integer limit,
|
||||||
|
Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.findByRelationshipType(context, relationshipType, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException {
|
||||||
|
return this.findByTypeName(context, typeName, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.findByTypeName(context, typeName, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countTotal(Context context) throws SQLException {
|
||||||
|
return relationshipDAO.countRows(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByItem(Context context, Item item) throws SQLException {
|
||||||
|
return relationshipDAO.countByItem(context, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException {
|
||||||
|
return relationshipDAO.countByRelationshipType(context, relationshipType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.countByItemAndRelationshipType(context, item, relationshipType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipDAO.countByTypeName(context, typeName);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,254 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.ReloadableEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a RelationshipType
|
||||||
|
* This class contains an Integer ID that will be the unique value and primary key in the database.
|
||||||
|
* This key is automatically generated
|
||||||
|
* It also has a leftType and rightType EntityType that describes the relationshipType together with a leftwardType and
|
||||||
|
* rightwardType.
|
||||||
|
* The cardinality properties describe how many of each relations this relationshipType can support
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "relationship_type")
|
||||||
|
public class RelationshipType implements ReloadableEntity<Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Integer ID used as a primary key for this database object.
|
||||||
|
* This is generated by a sequence
|
||||||
|
*/
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "relationship_type_id_seq")
|
||||||
|
@SequenceGenerator(name = "relationship_type_id_seq", sequenceName = "relationship_type_id_seq", allocationSize = 1)
|
||||||
|
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)
|
||||||
|
protected Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The leftType EntityType field for the relationshipType
|
||||||
|
* This is stored as an ID and cannot be null
|
||||||
|
*/
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
|
||||||
|
@JoinColumn(name = "left_type", nullable = false)
|
||||||
|
private EntityType leftType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rightType EntityType field for the relationshipType
|
||||||
|
* This is stored as an ID and cannot be null
|
||||||
|
*/
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
|
||||||
|
@JoinColumn(name = "right_type", nullable = false)
|
||||||
|
private EntityType rightType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The leftwardType String field for the relationshipType
|
||||||
|
* This is stored as a String and cannot be null
|
||||||
|
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||||
|
*/
|
||||||
|
@Column(name = "leftward_type", nullable = false)
|
||||||
|
private String leftwardType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rightwardType String field for the relationshipType
|
||||||
|
* This is stored as a String and cannot be null
|
||||||
|
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||||
|
*/
|
||||||
|
@Column(name = "rightward_type", nullable = false)
|
||||||
|
private String rightwardType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount of relations for the leftItem that need to be present at all times
|
||||||
|
* This is stored as an Integer
|
||||||
|
*/
|
||||||
|
@Column(name = "left_min_cardinality")
|
||||||
|
private Integer leftMinCardinality;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum amount of relations for the leftItem that can to be present at all times
|
||||||
|
* This is stored as an Integer
|
||||||
|
*/
|
||||||
|
@Column(name = "left_max_cardinality")
|
||||||
|
private Integer leftMaxCardinality;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount of relations for the rightItem that need to be present at all times
|
||||||
|
*/
|
||||||
|
@Column(name = "right_min_cardinality")
|
||||||
|
private Integer rightMinCardinality;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tha maximum amount of relations for the rightItem that can be present at all times
|
||||||
|
*/
|
||||||
|
@Column(name = "right_max_cardinality")
|
||||||
|
private Integer rightMaxCardinality;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor, create object using:
|
||||||
|
* {@link org.dspace.content.service.RelationshipTypeService#create(Context)} }
|
||||||
|
*/
|
||||||
|
protected RelationshipType() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the ID of this RelationshipType
|
||||||
|
* @param id The ID that this RelationshipType should receive
|
||||||
|
*/
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for The leftType EntityType for this RelationshipType
|
||||||
|
* @return The leftType EntityType of this RelationshipType
|
||||||
|
*/
|
||||||
|
public EntityType getLeftType() {
|
||||||
|
return leftType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftType EntityType for this RelationshipType
|
||||||
|
* @param leftType The leftType EntityType that this RelationshipType should receive
|
||||||
|
*/
|
||||||
|
public void setLeftType(EntityType leftType) {
|
||||||
|
this.leftType = leftType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for The rightType EntityType for this RelationshipType
|
||||||
|
* @return The rightType EntityType of this RelationshipType
|
||||||
|
*/
|
||||||
|
public EntityType getRightType() {
|
||||||
|
return rightType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightType EntityType for this RelationshipType
|
||||||
|
* @param rightType The rightType EntityType that this RelationshipType should receive
|
||||||
|
*/
|
||||||
|
public void setRightType(EntityType rightType) {
|
||||||
|
this.rightType = rightType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftwardType String for this RelationshipType
|
||||||
|
* @return The leftwardType String of this RelationshipType
|
||||||
|
*/
|
||||||
|
public String getLeftwardType() {
|
||||||
|
return leftwardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftwardType String for this RelationshipType
|
||||||
|
* @param leftwardType The leftwardType String that this RelationshipType should receive
|
||||||
|
*/
|
||||||
|
public void setLeftwardType(String leftwardType) {
|
||||||
|
this.leftwardType = leftwardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightwardType String for this RelationshipType
|
||||||
|
* @return The rightwardType String of this RelationshipType
|
||||||
|
*/
|
||||||
|
public String getRightwardType() {
|
||||||
|
return rightwardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightwardType String for this RelationshipType
|
||||||
|
* @param rightwardType The rightwardType String that this RelationshipType should receive
|
||||||
|
*/
|
||||||
|
public void setRightwardType(String rightwardType) {
|
||||||
|
this.rightwardType = rightwardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftMinCardinality Integer for this RelationshipType
|
||||||
|
* @return the leftMinCardinality Integer of this RelationshipType
|
||||||
|
*/
|
||||||
|
public Integer getLeftMinCardinality() {
|
||||||
|
return leftMinCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftMinCardinality Integer for this RelationshipType
|
||||||
|
* @param leftMinCardinality The leftMinCardinality Integer that this RelationshipType should recieve
|
||||||
|
*/
|
||||||
|
public void setLeftMinCardinality(Integer leftMinCardinality) {
|
||||||
|
this.leftMinCardinality = leftMinCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftMaxCardinality Integer for this RelationshipType
|
||||||
|
* @return the leftMaxCardinality Integer of this RelationshipType
|
||||||
|
*/
|
||||||
|
public Integer getLeftMaxCardinality() {
|
||||||
|
return leftMaxCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftMaxCardinality Integer for this RelationshipType
|
||||||
|
* @param leftMaxCardinality The leftMaxCardinality Integer that this RelationshipType should recieve
|
||||||
|
*/
|
||||||
|
public void setLeftMaxCardinality(Integer leftMaxCardinality) {
|
||||||
|
this.leftMaxCardinality = leftMaxCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightMinCardinality Integer for this RelationshipType
|
||||||
|
* @return the rightMinCardinality Integer of this RelationshipType
|
||||||
|
*/
|
||||||
|
public Integer getRightMinCardinality() {
|
||||||
|
return rightMinCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightMinCardinality Integer for this RelationshipType
|
||||||
|
* @param rightMinCardinality The rightMinCardinality Integer that this RelationshipType should recieve
|
||||||
|
*/
|
||||||
|
public void setRightMinCardinality(Integer rightMinCardinality) {
|
||||||
|
this.rightMinCardinality = rightMinCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightMaxCardinality Integer for this RelationshipType
|
||||||
|
* @return the rightMaxCardinality Integer of this RelationshipType
|
||||||
|
*/
|
||||||
|
public Integer getRightMaxCardinality() {
|
||||||
|
return rightMaxCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightMaxCardinality Integer for this RelationshipType
|
||||||
|
* @param rightMaxCardinality The rightMaxCardinality Integer that this RelationshipType should recieve
|
||||||
|
*/
|
||||||
|
public void setRightMaxCardinality(Integer rightMaxCardinality) {
|
||||||
|
this.rightMaxCardinality = rightMaxCardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the ID of this RelationshipType
|
||||||
|
* @return The ID of this RelationshipType
|
||||||
|
*/
|
||||||
|
public Integer getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.dao.RelationshipTypeDAO;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class RelationshipTypeServiceImpl implements RelationshipTypeService {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipTypeDAO relationshipTypeDAO;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType create(Context context) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify relationshipType");
|
||||||
|
}
|
||||||
|
return relationshipTypeDAO.create(context, new RelationshipType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType create(Context context, RelationshipType relationshipType)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify relationshipType");
|
||||||
|
}
|
||||||
|
return relationshipTypeDAO.create(context, relationshipType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType findbyTypesAndTypeName(Context context,EntityType leftType,EntityType rightType,
|
||||||
|
String leftwardType,String rightwardType) throws SQLException {
|
||||||
|
return relationshipTypeDAO.findbyTypesAndTypeName(context, leftType, rightType, leftwardType, rightwardType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findAll(Context context) throws SQLException {
|
||||||
|
return findAll(context, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
return relationshipTypeDAO.findAll(context, RelationshipType.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName)
|
||||||
|
throws SQLException {
|
||||||
|
return findByLeftwardOrRightwardTypeName(context, typeName, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName, Integer limit,
|
||||||
|
Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
return relationshipTypeDAO.findByLeftwardOrRightwardTypeName(context, typeName, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException {
|
||||||
|
return findByEntityType(context, entityType, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
return relationshipTypeDAO.findByEntityType(context, entityType, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft)
|
||||||
|
throws SQLException {
|
||||||
|
return findByEntityType(context, entityType, isLeft, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
return relationshipTypeDAO.findByEntityType(context, entityType, isLeft, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||||
|
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
|
||||||
|
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
||||||
|
Integer rightCardinalityMaxInteger)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
RelationshipType relationshipType = new RelationshipType();
|
||||||
|
relationshipType.setLeftType(leftEntityType);
|
||||||
|
relationshipType.setRightType(rightEntityType);
|
||||||
|
relationshipType.setLeftwardType(leftwardType);
|
||||||
|
relationshipType.setRightwardType(rightwardType);
|
||||||
|
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
||||||
|
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
||||||
|
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
||||||
|
relationshipType.setRightMaxCardinality(rightCardinalityMaxInteger);
|
||||||
|
return create(context, relationshipType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType find(Context context,int id) throws SQLException {
|
||||||
|
return relationshipTypeDAO.findByID(context, RelationshipType.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context,RelationshipType relationshipType) throws SQLException, AuthorizeException {
|
||||||
|
update(context,Collections.singletonList(relationshipType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context,List<RelationshipType> relationshipTypes)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
if (CollectionUtils.isNotEmpty(relationshipTypes)) {
|
||||||
|
// Check authorisation - only administrators can change formats
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can modify RelationshipType");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RelationshipType relationshipType : relationshipTypes) {
|
||||||
|
relationshipTypeDAO.save(context, relationshipType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context,RelationshipType relationshipType) throws SQLException, AuthorizeException {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException(
|
||||||
|
"Only administrators can delete entityType");
|
||||||
|
}
|
||||||
|
relationshipTypeDAO.delete(context, relationshipType);
|
||||||
|
}
|
||||||
|
}
|
@@ -220,6 +220,11 @@ public final class ChoiceAuthorityServiceImpl implements ChoiceAuthorityService
|
|||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearCache() {
|
||||||
|
controller.clear();
|
||||||
|
authorities.clear();
|
||||||
|
}
|
||||||
private void loadChoiceAuthorityConfigurations() {
|
private void loadChoiceAuthorityConfigurations() {
|
||||||
// Get all configuration keys starting with a given prefix
|
// Get all configuration keys starting with a given prefix
|
||||||
List<String> propKeys = configurationService.getPropertyKeys(CHOICES_PLUGIN_PREFIX);
|
List<String> propKeys = configurationService.getPropertyKeys(CHOICES_PLUGIN_PREFIX);
|
||||||
|
@@ -241,7 +241,7 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
|
|||||||
} catch (XPathExpressionException e) {
|
} catch (XPathExpressionException e) {
|
||||||
log.warn(e.getMessage(), e);
|
log.warn(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
return new Choice("", "", "");
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readNode(String[] authorities, String[] values, String[] labels, String[] parent, String[] notes,
|
private void readNode(String[] authorities, String[] values, String[] labels, String[] parent, String[] notes,
|
||||||
|
@@ -65,7 +65,7 @@ public class InputFormSelfRegisterWrapperAuthority implements ChoiceAuthority {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!choices.isEmpty()) {
|
if (!choices.isEmpty()) {
|
||||||
Choice[] results = new Choice[choices.size() - 1];
|
Choice[] results = new Choice[choices.size()];
|
||||||
choices.toArray(results);
|
choices.toArray(results);
|
||||||
return new Choices(results, 0, choices.size(), Choices.CF_AMBIGUOUS, false);
|
return new Choices(results, 0, choices.size(), Choices.CF_AMBIGUOUS, false);
|
||||||
}
|
}
|
||||||
|
@@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.content.authority;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
import org.dspace.content.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample Journal-name authority based on SHERPA/RoMEO
|
|
||||||
*
|
|
||||||
* WARNING: This is a very crude and incomplete implementation, done mainly
|
|
||||||
* as a proof-of-concept. Any site that actually wants to use it will
|
|
||||||
* probably have to refine it (and give patches back to dspace.org).
|
|
||||||
*
|
|
||||||
* @author Larry Stone
|
|
||||||
* @version $Revision $
|
|
||||||
* @see SHERPARoMEOProtocol
|
|
||||||
*/
|
|
||||||
public class SHERPARoMEOJournalTitle extends SHERPARoMEOProtocol {
|
|
||||||
private static final String RESULT = "journal";
|
|
||||||
private static final String LABEL = "jtitle";
|
|
||||||
private static final String AUTHORITY = "issn";
|
|
||||||
|
|
||||||
public SHERPARoMEOJournalTitle() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Choices getMatches(String text, Collection collection, int start, int limit, String locale) {
|
|
||||||
// punt if there is no query text
|
|
||||||
if (text == null || text.trim().length() == 0) {
|
|
||||||
return new Choices(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// query args to add to SHERPA/RoMEO request URL
|
|
||||||
List<BasicNameValuePair> args = new ArrayList<BasicNameValuePair>();
|
|
||||||
args.add(new BasicNameValuePair("jtitle", text));
|
|
||||||
args.add(new BasicNameValuePair("qtype", "contains")); // OR: starts, exact
|
|
||||||
|
|
||||||
Choices result = query(RESULT, LABEL, AUTHORITY, args, start, limit);
|
|
||||||
if (result == null) {
|
|
||||||
result = new Choices(true);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Choices getMatches(String field, String text, Collection collection, int start, int limit, String locale) {
|
|
||||||
return getMatches(text, collection, start, limit, locale);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,228 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.content.authority;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.parsers.SAXParser;
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.dspace.content.Collection;
|
|
||||||
import org.dspace.core.ConfigurationManager;
|
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
import org.xml.sax.SAXParseException;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Choice Authority based on SHERPA/RoMEO - for Publishers and Journals
|
|
||||||
* See the subclasses SHERPARoMEOPublisher and SHERPARoMEOJournalTitle
|
|
||||||
* for actual choice plugin implementations. This is a superclass
|
|
||||||
* containing all the common protocol logic.
|
|
||||||
*
|
|
||||||
* Reads these DSpace Config properties:
|
|
||||||
*
|
|
||||||
* # contact URL for server
|
|
||||||
* sherpa.romeo.url = http://www.sherpa.ac.uk/romeoapi11.php
|
|
||||||
*
|
|
||||||
* WARNING: This is a very crude and incomplete implementation, done mainly
|
|
||||||
* as a proof-of-concept. Any site that actually wants to use it will
|
|
||||||
* probably have to refine it (and give patches back to dspace.org).
|
|
||||||
*
|
|
||||||
* @author Larry Stone
|
|
||||||
* @version $Revision $
|
|
||||||
* @see SHERPARoMEOPublisher
|
|
||||||
* @see SHERPARoMEOJournalTitle
|
|
||||||
*/
|
|
||||||
public abstract class SHERPARoMEOProtocol implements ChoiceAuthority {
|
|
||||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPARoMEOProtocol.class);
|
|
||||||
|
|
||||||
// contact URL from configuration
|
|
||||||
private static String url = null;
|
|
||||||
|
|
||||||
public SHERPARoMEOProtocol() {
|
|
||||||
if (url == null) {
|
|
||||||
url = ConfigurationManager.getProperty("sherpa.romeo.url");
|
|
||||||
|
|
||||||
// sanity check
|
|
||||||
if (url == null) {
|
|
||||||
throw new IllegalStateException("Missing DSpace configuration keys for SHERPA/RoMEO Query");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this implements the specific RoMEO API args and XML tag naming
|
|
||||||
public abstract Choices getMatches(String text, Collection collection, int start, int limit, String locale);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Choices getBestMatch(String field, String text, Collection collection, String locale) {
|
|
||||||
return getMatches(field, text, collection, 0, 2, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX FIXME just punt, returning value, never got around to
|
|
||||||
// implementing a reverse query.
|
|
||||||
@Override
|
|
||||||
public String getLabel(String field, String key, String locale) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE - ignore limit and start for now
|
|
||||||
protected Choices query(String result, String label, String authority,
|
|
||||||
List<BasicNameValuePair> args, int start, int limit) {
|
|
||||||
HttpClient hc = new DefaultHttpClient();
|
|
||||||
String srUrl = url + "?" + URLEncodedUtils.format(args, "UTF8");
|
|
||||||
HttpGet get = new HttpGet(srUrl);
|
|
||||||
|
|
||||||
log.debug("Trying SHERPA/RoMEO Query, URL=" + srUrl);
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpResponse response = hc.execute(get);
|
|
||||||
if (response.getStatusLine().getStatusCode() == 200) {
|
|
||||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
|
||||||
SAXParser sp = spf.newSAXParser();
|
|
||||||
XMLReader xr = sp.getXMLReader();
|
|
||||||
SRHandler handler = new SRHandler(result, label, authority);
|
|
||||||
|
|
||||||
// XXX FIXME: should turn off validation here explicitly, but
|
|
||||||
// it seems to be off by default.
|
|
||||||
xr.setFeature("http://xml.org/sax/features/namespaces", true);
|
|
||||||
xr.setContentHandler(handler);
|
|
||||||
xr.setErrorHandler(handler);
|
|
||||||
xr.parse(new InputSource(response.getEntity().getContent()));
|
|
||||||
int confidence;
|
|
||||||
if (handler.total == 0) {
|
|
||||||
confidence = Choices.CF_NOTFOUND;
|
|
||||||
} else if (handler.total == 1) {
|
|
||||||
confidence = Choices.CF_UNCERTAIN;
|
|
||||||
} else {
|
|
||||||
confidence = Choices.CF_AMBIGUOUS;
|
|
||||||
}
|
|
||||||
return new Choices(handler.result, start, handler.total, confidence, false);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("SHERPA/RoMEO query failed: ", e);
|
|
||||||
return null;
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
log.warn("Failed parsing SHERPA/RoMEO result: ", e);
|
|
||||||
return null;
|
|
||||||
} catch (SAXException e) {
|
|
||||||
log.warn("Failed parsing SHERPA/RoMEO result: ", e);
|
|
||||||
return null;
|
|
||||||
} finally {
|
|
||||||
get.releaseConnection();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SAX handler to grab SHERPA/RoMEO (and eventually other details) from result
|
|
||||||
private static class SRHandler
|
|
||||||
extends DefaultHandler {
|
|
||||||
private Choice result[] = null;
|
|
||||||
int rindex = 0; // result index
|
|
||||||
int total = 0;
|
|
||||||
|
|
||||||
// name of element containing a result, e.g. <journal>
|
|
||||||
private String resultElement = null;
|
|
||||||
|
|
||||||
// name of element containing the label e.g. <name>
|
|
||||||
private String labelElement = null;
|
|
||||||
|
|
||||||
// name of element containing the authority value e.g. <issn>
|
|
||||||
private String authorityElement = null;
|
|
||||||
|
|
||||||
protected String textValue = null;
|
|
||||||
|
|
||||||
public SRHandler(String result, String label, String authority) {
|
|
||||||
super();
|
|
||||||
resultElement = result;
|
|
||||||
labelElement = label;
|
|
||||||
authorityElement = authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: text value MAY be presented in multiple calls, even if
|
|
||||||
// it all one word, so be ready to splice it together.
|
|
||||||
// BEWARE: subclass's startElement method should call super()
|
|
||||||
// to null out 'value'. (Don't you miss the method combination
|
|
||||||
// options of a real object system like CLOS?)
|
|
||||||
@Override
|
|
||||||
public void characters(char[] ch, int start, int length)
|
|
||||||
throws SAXException {
|
|
||||||
String newValue = new String(ch, start, length);
|
|
||||||
if (newValue.length() > 0) {
|
|
||||||
if (textValue == null) {
|
|
||||||
textValue = newValue;
|
|
||||||
} else {
|
|
||||||
textValue += newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this was the FIRST "numhits" element, it's size of results:
|
|
||||||
@Override
|
|
||||||
public void endElement(String namespaceURI, String localName,
|
|
||||||
String qName)
|
|
||||||
throws SAXException {
|
|
||||||
if (localName.equals("numhits")) {
|
|
||||||
String stotal = textValue.trim();
|
|
||||||
if (stotal.length() > 0) {
|
|
||||||
total = Integer.parseInt(stotal);
|
|
||||||
result = new Choice[total];
|
|
||||||
if (total > 0) {
|
|
||||||
result[0] = new Choice();
|
|
||||||
log.debug("Got " + total + " records in results.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (localName.equals(resultElement)) {
|
|
||||||
// after start of result element, get next hit ready
|
|
||||||
if (++rindex < result.length) {
|
|
||||||
result[rindex] = new Choice();
|
|
||||||
}
|
|
||||||
} else if (localName.equals(labelElement) && textValue != null) {
|
|
||||||
// plug in label value
|
|
||||||
result[rindex].value = textValue.trim();
|
|
||||||
result[rindex].label = result[rindex].value;
|
|
||||||
} else if (authorityElement != null && localName.equals(authorityElement) && textValue != null) {
|
|
||||||
// plug in authority value
|
|
||||||
result[rindex].authority = textValue.trim();
|
|
||||||
} else if (localName.equals("message") && textValue != null) {
|
|
||||||
// error message
|
|
||||||
log.warn("SHERPA/RoMEO response error message: " + textValue.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// subclass overriding this MUST call it with super()
|
|
||||||
@Override
|
|
||||||
public void startElement(String namespaceURI, String localName,
|
|
||||||
String qName, Attributes atts)
|
|
||||||
throws SAXException {
|
|
||||||
textValue = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void error(SAXParseException exception)
|
|
||||||
throws SAXException {
|
|
||||||
throw new SAXException(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fatalError(SAXParseException exception)
|
|
||||||
throws SAXException {
|
|
||||||
throw new SAXException(exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.content.authority;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
import org.dspace.content.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample Publisher name authority based on SHERPA/RoMEO
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* WARNING: This is a very crude and incomplete implementation, done mainly
|
|
||||||
* as a proof-of-concept. Any site that actually wants to use it will
|
|
||||||
* probably have to refine it (and give patches back to dspace.org).
|
|
||||||
*
|
|
||||||
* @author Larry Stone
|
|
||||||
* @version $Revision $
|
|
||||||
* @see SHERPARoMEOProtocol
|
|
||||||
*/
|
|
||||||
public class SHERPARoMEOPublisher extends SHERPARoMEOProtocol {
|
|
||||||
protected static final String RESULT = "publisher";
|
|
||||||
protected static final String LABEL = "name";
|
|
||||||
// note: the publisher records have nothing we can use as authority code.
|
|
||||||
protected static final String AUTHORITY = null;
|
|
||||||
|
|
||||||
public SHERPARoMEOPublisher() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Choices getMatches(String text, Collection collection, int start, int limit, String locale) {
|
|
||||||
// punt if there is no query text
|
|
||||||
if (text == null || text.trim().length() == 0) {
|
|
||||||
return new Choices(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// query args to add to SHERPA/RoMEO request URL
|
|
||||||
List<BasicNameValuePair> args = new ArrayList<BasicNameValuePair>();
|
|
||||||
args.add(new BasicNameValuePair("pub", text));
|
|
||||||
args.add(new BasicNameValuePair("qtype", "all")); // OR: starts, exact
|
|
||||||
|
|
||||||
Choices result = query(RESULT, LABEL, AUTHORITY, args, start, limit);
|
|
||||||
if (result == null) {
|
|
||||||
result = new Choices(true);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Choices getMatches(String field, String text, Collection collection, int start, int limit, String locale) {
|
|
||||||
return getMatches(text, collection, start, limit, locale);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -188,8 +188,8 @@ public class SolrAuthority implements ChoiceAuthority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String toQuery(String searchField, String text) {
|
private String toQuery(String searchField, String text) {
|
||||||
return searchField + ":\"" + text.toLowerCase().replaceAll(":", "\\:") + "*\" or " + searchField + ":\"" + text
|
return searchField + ":(" + text.toLowerCase().replaceAll(":", "\\:") + "*) or " + searchField + ":(" + text
|
||||||
.toLowerCase().replaceAll(":", "\\:") + "\"";
|
.toLowerCase().replaceAll(":", "\\:") + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -168,4 +168,9 @@ public interface ChoiceAuthorityService {
|
|||||||
|
|
||||||
public ChoiceAuthority getChoiceAuthorityByAuthorityName(String authorityName);
|
public ChoiceAuthority getChoiceAuthorityByAuthorityName(String authorityName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method has been created to have a way of clearing the cache kept inside the service
|
||||||
|
*/
|
||||||
|
public void clearCache();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import org.dspace.content.Community;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.Site;
|
import org.dspace.content.Site;
|
||||||
|
import org.dspace.content.dto.MetadataValueDTO;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.packager.DSpaceAIPIngester;
|
import org.dspace.content.packager.DSpaceAIPIngester;
|
||||||
import org.dspace.content.packager.METSManifest;
|
import org.dspace.content.packager.METSManifest;
|
||||||
@@ -195,7 +196,7 @@ public class AIPTechMDCrosswalk implements IngestionCrosswalk, DisseminationCros
|
|||||||
public Element disseminateElement(Context context, DSpaceObject dso)
|
public Element disseminateElement(Context context, DSpaceObject dso)
|
||||||
throws CrosswalkException, IOException, SQLException,
|
throws CrosswalkException, IOException, SQLException,
|
||||||
AuthorizeException {
|
AuthorizeException {
|
||||||
List<MockMetadataValue> dc = new ArrayList<>();
|
List<MetadataValueDTO> dc = new ArrayList<>();
|
||||||
if (dso.getType() == Constants.ITEM) {
|
if (dso.getType() == Constants.ITEM) {
|
||||||
Item item = (Item) dso;
|
Item item = (Item) dso;
|
||||||
EPerson is = item.getSubmitter();
|
EPerson is = item.getSubmitter();
|
||||||
@@ -282,8 +283,8 @@ public class AIPTechMDCrosswalk implements IngestionCrosswalk, DisseminationCros
|
|||||||
return XSLTDisseminationCrosswalk.createDIM(dso, dc);
|
return XSLTDisseminationCrosswalk.createDIM(dso, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MockMetadataValue makeDC(String element, String qualifier, String value) {
|
private static MetadataValueDTO makeDC(String element, String qualifier, String value) {
|
||||||
MockMetadataValue dcv = new MockMetadataValue();
|
MetadataValueDTO dcv = new MetadataValueDTO();
|
||||||
dcv.setSchema("dc");
|
dcv.setSchema("dc");
|
||||||
dcv.setLanguage(null);
|
dcv.setLanguage(null);
|
||||||
dcv.setElement(element);
|
dcv.setElement(element);
|
||||||
|
@@ -29,6 +29,7 @@ import org.dspace.content.DSpaceObject;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.Site;
|
import org.dspace.content.Site;
|
||||||
|
import org.dspace.content.dto.MetadataValueDTO;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
@@ -327,7 +328,7 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
|
|
||||||
private List<Element> disseminateListInternal(DSpaceObject dso, boolean addSchema)
|
private List<Element> disseminateListInternal(DSpaceObject dso, boolean addSchema)
|
||||||
throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
List<MockMetadataValue> dcvs = null;
|
List<MetadataValueDTO> dcvs = null;
|
||||||
if (dso.getType() == Constants.ITEM) {
|
if (dso.getType() == Constants.ITEM) {
|
||||||
dcvs = item2Metadata((Item) dso);
|
dcvs = item2Metadata((Item) dso);
|
||||||
} else if (dso.getType() == Constants.COLLECTION) {
|
} else if (dso.getType() == Constants.COLLECTION) {
|
||||||
@@ -344,7 +345,7 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
|
|
||||||
List<Element> result = new ArrayList<Element>(dcvs.size());
|
List<Element> result = new ArrayList<Element>(dcvs.size());
|
||||||
|
|
||||||
for (MockMetadataValue dcv : dcvs) {
|
for (MetadataValueDTO dcv : dcvs) {
|
||||||
String qdc = dcv.getSchema() + "." + dcv.getElement();
|
String qdc = dcv.getSchema() + "." + dcv.getElement();
|
||||||
if (dcv.getQualifier() != null) {
|
if (dcv.getQualifier() != null) {
|
||||||
qdc += "." + dcv.getQualifier();
|
qdc += "." + dcv.getQualifier();
|
||||||
@@ -418,8 +419,8 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
* @param site The site to derive metadata from
|
* @param site The site to derive metadata from
|
||||||
* @return list of metadata
|
* @return list of metadata
|
||||||
*/
|
*/
|
||||||
protected List<MockMetadataValue> site2Metadata(Site site) {
|
protected List<MetadataValueDTO> site2Metadata(Site site) {
|
||||||
List<MockMetadataValue> metadata = new ArrayList<>();
|
List<MetadataValueDTO> metadata = new ArrayList<>();
|
||||||
|
|
||||||
String identifier_uri = handleService.getCanonicalPrefix()
|
String identifier_uri = handleService.getCanonicalPrefix()
|
||||||
+ site.getHandle();
|
+ site.getHandle();
|
||||||
@@ -449,8 +450,8 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
* @param community The community to derive metadata from
|
* @param community The community to derive metadata from
|
||||||
* @return list of metadata
|
* @return list of metadata
|
||||||
*/
|
*/
|
||||||
protected List<MockMetadataValue> community2Metadata(Community community) {
|
protected List<MetadataValueDTO> community2Metadata(Community community) {
|
||||||
List<MockMetadataValue> metadata = new ArrayList<>();
|
List<MetadataValueDTO> metadata = new ArrayList<>();
|
||||||
|
|
||||||
String description = communityService.getMetadata(community, "introductory_text");
|
String description = communityService.getMetadata(community, "introductory_text");
|
||||||
String description_abstract = communityService.getMetadata(community, "short_description");
|
String description_abstract = communityService.getMetadata(community, "short_description");
|
||||||
@@ -492,8 +493,8 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
* @param collection The collection to derive metadata from
|
* @param collection The collection to derive metadata from
|
||||||
* @return list of metadata
|
* @return list of metadata
|
||||||
*/
|
*/
|
||||||
protected List<MockMetadataValue> collection2Metadata(Collection collection) {
|
protected List<MetadataValueDTO> collection2Metadata(Collection collection) {
|
||||||
List<MockMetadataValue> metadata = new ArrayList<>();
|
List<MetadataValueDTO> metadata = new ArrayList<>();
|
||||||
|
|
||||||
String description = collectionService.getMetadata(collection, "introductory_text");
|
String description = collectionService.getMetadata(collection, "introductory_text");
|
||||||
String description_abstract = collectionService.getMetadata(collection, "short_description");
|
String description_abstract = collectionService.getMetadata(collection, "short_description");
|
||||||
@@ -546,19 +547,19 @@ public class MODSDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
* @param item The item to derive metadata from
|
* @param item The item to derive metadata from
|
||||||
* @return list of metadata
|
* @return list of metadata
|
||||||
*/
|
*/
|
||||||
protected List<MockMetadataValue> item2Metadata(Item item) {
|
protected List<MetadataValueDTO> item2Metadata(Item item) {
|
||||||
List<MetadataValue> dcvs = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY,
|
List<MetadataValue> dcvs = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY,
|
||||||
Item.ANY);
|
Item.ANY);
|
||||||
List<MockMetadataValue> result = new ArrayList<>();
|
List<MetadataValueDTO> result = new ArrayList<>();
|
||||||
for (MetadataValue metadataValue : dcvs) {
|
for (MetadataValue metadataValue : dcvs) {
|
||||||
result.add(new MockMetadataValue(metadataValue));
|
result.add(new MetadataValueDTO(metadataValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MockMetadataValue createDCValue(String element, String qualifier, String value) {
|
protected MetadataValueDTO createDCValue(String element, String qualifier, String value) {
|
||||||
MockMetadataValue dcv = new MockMetadataValue();
|
MetadataValueDTO dcv = new MetadataValueDTO();
|
||||||
dcv.setSchema("dc");
|
dcv.setSchema("dc");
|
||||||
dcv.setElement(element);
|
dcv.setElement(element);
|
||||||
dcv.setQualifier(qualifier);
|
dcv.setQualifier(qualifier);
|
||||||
|
@@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.content.crosswalk;
|
|
||||||
|
|
||||||
import org.dspace.content.MetadataField;
|
|
||||||
import org.dspace.content.MetadataSchema;
|
|
||||||
import org.dspace.content.MetadataValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Metadata Value is bound to a database, the dissemination crosswalk require mock metadata just need for desimanation
|
|
||||||
* This class provides a wrapper for this.
|
|
||||||
* This class should only be used for the dissemniation metadata values that aren't to be written to the database
|
|
||||||
*
|
|
||||||
* @author kevinvandevelde at atmire.com
|
|
||||||
*/
|
|
||||||
public class MockMetadataValue {
|
|
||||||
|
|
||||||
private String schema;
|
|
||||||
private String element;
|
|
||||||
private String qualifier;
|
|
||||||
private String language;
|
|
||||||
private String value;
|
|
||||||
private String authority;
|
|
||||||
private int confidence;
|
|
||||||
|
|
||||||
public MockMetadataValue(MetadataValue metadataValue) {
|
|
||||||
MetadataField metadataField = metadataValue.getMetadataField();
|
|
||||||
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
|
|
||||||
schema = metadataSchema.getName();
|
|
||||||
element = metadataField.getElement();
|
|
||||||
qualifier = metadataField.getQualifier();
|
|
||||||
language = metadataValue.getLanguage();
|
|
||||||
value = metadataValue.getValue();
|
|
||||||
authority = metadataValue.getAuthority();
|
|
||||||
confidence = metadataValue.getConfidence();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MockMetadataValue() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSchema() {
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getElement() {
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQualifier() {
|
|
||||||
return qualifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSchema(String schema) {
|
|
||||||
this.schema = schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setElement(String element) {
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQualifier(String qualifier) {
|
|
||||||
this.qualifier = qualifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLanguage() {
|
|
||||||
return language;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLanguage(String language) {
|
|
||||||
this.language = language;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthority() {
|
|
||||||
return authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthority(String authority) {
|
|
||||||
this.authority = authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getConfidence() {
|
|
||||||
return confidence;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConfidence(int confidence) {
|
|
||||||
this.confidence = confidence;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,7 +15,7 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
@@ -67,7 +67,8 @@ public class OAIDCIngestionCrosswalk
|
|||||||
lang = element.getAttributeValue("lang");
|
lang = element.getAttributeValue("lang");
|
||||||
}
|
}
|
||||||
MetadataField metadataField = metadataValidator
|
MetadataField metadataField = metadataValidator
|
||||||
.checkMetadata(context, MetadataSchema.DC_SCHEMA, element.getName(), null, createMissingMetadataFields);
|
.checkMetadata(context, MetadataSchemaEnum.DC.getName(),
|
||||||
|
element.getName(), null, createMissingMetadataFields);
|
||||||
itemService.addMetadata(context, item, metadataField, lang, element.getText());
|
itemService.addMetadata(context, item, metadataField, lang, element.getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,7 +22,7 @@ import org.dspace.content.Bitstream;
|
|||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -122,7 +122,7 @@ public class OREDisseminationCrosswalk
|
|||||||
|
|
||||||
Element aggLink;
|
Element aggLink;
|
||||||
List<MetadataValue> uris = itemService
|
List<MetadataValue> uris = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "identifier", "uri", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||||
for (MetadataValue uri : uris) {
|
for (MetadataValue uri : uris) {
|
||||||
aggLink = new Element("link", ATOM_NS);
|
aggLink = new Element("link", ATOM_NS);
|
||||||
aggLink.setAttribute("rel", "alternate");
|
aggLink.setAttribute("rel", "alternate");
|
||||||
@@ -159,7 +159,8 @@ public class OREDisseminationCrosswalk
|
|||||||
|
|
||||||
// Information about the aggregation (item) itself
|
// Information about the aggregation (item) itself
|
||||||
Element aggTitle = new Element("title", ATOM_NS);
|
Element aggTitle = new Element("title", ATOM_NS);
|
||||||
List<MetadataValue> titles = itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
List<MetadataValue> titles = itemService.getMetadata(item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"title", null, Item.ANY);
|
||||||
if (titles != null && titles.size() > 0) {
|
if (titles != null && titles.size() > 0) {
|
||||||
aggTitle.addContent(titles.get(0).getValue());
|
aggTitle.addContent(titles.get(0).getValue());
|
||||||
} else {
|
} else {
|
||||||
@@ -170,7 +171,7 @@ public class OREDisseminationCrosswalk
|
|||||||
Element aggAuthor;
|
Element aggAuthor;
|
||||||
Element aggAuthorName;
|
Element aggAuthorName;
|
||||||
List<MetadataValue> authors = itemService
|
List<MetadataValue> authors = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "contributor", "author", Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "contributor", "author", Item.ANY);
|
||||||
for (MetadataValue author : authors) {
|
for (MetadataValue author : authors) {
|
||||||
aggAuthor = new Element("author", ATOM_NS);
|
aggAuthor = new Element("author", ATOM_NS);
|
||||||
aggAuthorName = new Element("name", ATOM_NS);
|
aggAuthorName = new Element("name", ATOM_NS);
|
||||||
|
@@ -26,6 +26,7 @@ import org.dspace.content.DSpaceObject;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -353,7 +354,7 @@ public class QDCCrosswalk extends SelfNamedPlugin
|
|||||||
|
|
||||||
// only complain about missing elements in the DC schema:
|
// only complain about missing elements in the DC schema:
|
||||||
if (elt == null) {
|
if (elt == null) {
|
||||||
if (metadataField.getMetadataSchema().getName().equals(MetadataSchema.DC_SCHEMA)) {
|
if (metadataField.getMetadataSchema().getName().equals(MetadataSchemaEnum.DC.getName())) {
|
||||||
log.warn("WARNING: " + myName + ": No QDC mapping for \"" + qdc + "\"");
|
log.warn("WARNING: " + myName + ": No QDC mapping for \"" + qdc + "\"");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -17,7 +17,7 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -101,7 +101,7 @@ public class SimpleDCDisseminationCrosswalk extends SelfNamedPlugin
|
|||||||
|
|
||||||
Item item = (Item) dso;
|
Item item = (Item) dso;
|
||||||
List<MetadataValue> allDC = itemService
|
List<MetadataValue> allDC = itemService
|
||||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, Item.ANY, Item.ANY, Item.ANY);
|
.getMetadata(item, MetadataSchemaEnum.DC.getName(), Item.ANY, Item.ANY, Item.ANY);
|
||||||
|
|
||||||
List<Element> dcl = new ArrayList<Element>(allDC.size());
|
List<Element> dcl = new ArrayList<Element>(allDC.size());
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@ import org.dspace.content.Item;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.Site;
|
import org.dspace.content.Site;
|
||||||
import org.dspace.content.authority.Choices;
|
import org.dspace.content.authority.Choices;
|
||||||
|
import org.dspace.content.dto.MetadataValueDTO;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
@@ -307,13 +308,13 @@ public class XSLTDisseminationCrosswalk
|
|||||||
* @param dcvs list of metadata
|
* @param dcvs list of metadata
|
||||||
* @return element
|
* @return element
|
||||||
*/
|
*/
|
||||||
public static Element createDIM(DSpaceObject dso, List<MockMetadataValue> dcvs) {
|
public static Element createDIM(DSpaceObject dso, List<MetadataValueDTO> dcvs) {
|
||||||
Element dim = new Element("dim", DIM_NS);
|
Element dim = new Element("dim", DIM_NS);
|
||||||
String type = Constants.typeText[dso.getType()];
|
String type = Constants.typeText[dso.getType()];
|
||||||
dim.setAttribute("dspaceType", type);
|
dim.setAttribute("dspaceType", type);
|
||||||
|
|
||||||
for (int i = 0; i < dcvs.size(); i++) {
|
for (int i = 0; i < dcvs.size(); i++) {
|
||||||
MockMetadataValue dcv = dcvs.get(i);
|
MetadataValueDTO dcv = dcvs.get(i);
|
||||||
Element field =
|
Element field =
|
||||||
createField(dcv.getSchema(), dcv.getElement(), dcv.getQualifier(),
|
createField(dcv.getSchema(), dcv.getElement(), dcv.getQualifier(),
|
||||||
dcv.getLanguage(), dcv.getValue(), dcv.getAuthority(), dcv.getConfidence());
|
dcv.getLanguage(), dcv.getValue(), dcv.getAuthority(), dcv.getConfidence());
|
||||||
@@ -390,12 +391,12 @@ public class XSLTDisseminationCrosswalk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static List<MockMetadataValue> item2Metadata(Item item) {
|
protected static List<MetadataValueDTO> item2Metadata(Item item) {
|
||||||
List<MetadataValue> dcvs = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY,
|
List<MetadataValue> dcvs = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY,
|
||||||
Item.ANY);
|
Item.ANY);
|
||||||
List<MockMetadataValue> result = new ArrayList<>();
|
List<MetadataValueDTO> result = new ArrayList<>();
|
||||||
for (MetadataValue metadataValue : dcvs) {
|
for (MetadataValue metadataValue : dcvs) {
|
||||||
result.add(new MockMetadataValue(metadataValue));
|
result.add(new MetadataValueDTO(metadataValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.dspace.content.EntityType;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.GenericDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Access Object Interface class for the EntityType object
|
||||||
|
* The implementation of this class is responsible for all database calls for the EntityType object and is autowired by
|
||||||
|
* spring
|
||||||
|
* This class should only be accessed from a single service and should never be exposed outside of the API
|
||||||
|
*/
|
||||||
|
public interface EntityTypeDAO extends GenericDAO<EntityType> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the EntityType object that has the given entityType String
|
||||||
|
* as label
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param entityType The entityType String that will be matched on to find
|
||||||
|
* the correct EntityType
|
||||||
|
* @return The EntityType object that has the entityType String as label
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
public EntityType findByEntityType(Context context, String entityType) throws SQLException;
|
||||||
|
|
||||||
|
}
|
@@ -63,6 +63,29 @@ public interface ItemDAO extends DSpaceObjectLegacySupportDAO<Item> {
|
|||||||
public Iterator<Item> findArchivedByCollection(Context context, Collection collection, Integer limit,
|
public Iterator<Item> findArchivedByCollection(Context context, Collection collection, Integer limit,
|
||||||
Integer offset) throws SQLException;
|
Integer offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the Items in an iterator that are archived and for which the given Collection is part of the Item's
|
||||||
|
* Collections but it is not the owning collection
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param collection The collection to check on
|
||||||
|
* @param limit The limit for the query
|
||||||
|
* @param offset The offset for the query
|
||||||
|
* @return An iterator containing the items for which the constraints hold true
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
public Iterator<Item> findArchivedByCollectionExcludingOwning(Context context, Collection collection, Integer limit,
|
||||||
|
Integer offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts all the items that are archived and for which the given Collection is part of the Item's Collections
|
||||||
|
* but it is not the owning Collection
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param collection The collection to check on
|
||||||
|
* @return The total amount of items that fit the constraints
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
public int countArchivedByCollectionExcludingOwning(Context context, Collection collection) throws SQLException;
|
||||||
|
|
||||||
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException;
|
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException;
|
||||||
|
|
||||||
public Iterator<Item> findAllByCollection(Context context, Collection collection, Integer limit, Integer offset)
|
public Iterator<Item> findAllByCollection(Context context, Collection collection, Integer limit, Integer offset)
|
||||||
|
@@ -28,6 +28,10 @@ public interface MetadataValueDAO extends GenericDAO<MetadataValue> {
|
|||||||
|
|
||||||
public List<MetadataValue> findByField(Context context, MetadataField fieldId) throws SQLException;
|
public List<MetadataValue> findByField(Context context, MetadataField fieldId) throws SQLException;
|
||||||
|
|
||||||
|
public Iterator<MetadataValue> findItemValuesByFieldAndValue(Context context,
|
||||||
|
MetadataField metadataField, String value)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
public Iterator<MetadataValue> findByValueLike(Context context, String value) throws SQLException;
|
public Iterator<MetadataValue> findByValueLike(Context context, String value) throws SQLException;
|
||||||
|
|
||||||
public void deleteByMetadataField(Context context, MetadataField metadataField) throws SQLException;
|
public void deleteByMetadataField(Context context, MetadataField metadataField) throws SQLException;
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.GenericDAO;
|
||||||
|
import org.dspace.scripts.Process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the Data Access Object for the {@link Process} object
|
||||||
|
*/
|
||||||
|
public interface ProcessDAO extends GenericDAO<Process> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return all the Process objects in the database in a list and it'll be sorted by script name
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @return The list of all Process objects in the database sorted on scriptname
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
public List<Process> findAllSortByScript(Context context) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return all the Process objects in the database in a list and it'll be sorted by start time.
|
||||||
|
* The most recent one will be shown first
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @return The list of all Process objects in the database sorted by starttime
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
public List<Process> findAllSortByStartTime(Context context) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all Process objects in the database
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param limit The limit for the amount of Processes returned
|
||||||
|
* @param offset The offset for the Processes to be returned
|
||||||
|
* @return The list of all Process objects in the Database
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Process> findAll(Context context, int limit, int offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total amount of Process objects in the dataase
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @return An integer that describes the amount of Process objects in the database
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
int countRows(Context context) throws SQLException;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,213 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.Relationship;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.GenericDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Access Object Interface class for the Relationship object
|
||||||
|
* The implementation of this class is responsible for all
|
||||||
|
* database calls for the Relationship object and is autowired by spring
|
||||||
|
* This class should only be accessed from a single service and should never be exposed outside of the API
|
||||||
|
*/
|
||||||
|
public interface RelationshipDAO extends GenericDAO<Relationship> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects that have the given Item object
|
||||||
|
* as a leftItem or a rightItem
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param item The item that should be either a leftItem or a rightItem of all
|
||||||
|
* the Relationship objects in the returned list
|
||||||
|
* @return The list of Relationship objects that contain either a left or a
|
||||||
|
* right item that is equal to the given item
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByItem(Context context, Item item) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects that have the given Item object
|
||||||
|
* as a leftItem or a rightItem
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param item The item that should be either a leftItem or a rightItem of all
|
||||||
|
* the Relationship objects in the returned list
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return The list of Relationship objects that contain either a left or a
|
||||||
|
* right item that is equal to the given item
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param item The item to be matched on leftItem
|
||||||
|
* @return The next integer to be used for the leftplace of a relationship with the given item
|
||||||
|
* as a left item
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the next rightplace integer to use for a relationship with this item as the rightItem
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param item The item to be matched on rightItem
|
||||||
|
* @return The next integer to be used for the rightplace of a relationship with the given item
|
||||||
|
* as a right item
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||||
|
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||||
|
* as the relationshipType property
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationshipType The RelationshipType object to be checked on
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||||
|
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||||
|
* as the relationshipType property
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationshipType The RelationshipType object to be checked on
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType,
|
||||||
|
Integer limit, Integer offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||||
|
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||||
|
* as the relationshipType property
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationshipType The RelationshipType object to be checked on
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @param item item to filter by
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType,
|
||||||
|
Integer limit, Integer offset) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||||
|
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||||
|
* as the relationshipType property
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param relationshipType The RelationshipType object to be checked on
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @param item item to filter by
|
||||||
|
* @param isLeft Is item left or right
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType,
|
||||||
|
boolean isLeft, Integer limit, Integer offset)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given typeName
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param typeName The leftward or rightward typeName of the relationship type
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of Relationship objects for the given typeName
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param typeName The leftward or rightward typeName of the relationship type
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||||
|
* relationshipType property
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count total number of relationships (rows in relationship table)
|
||||||
|
*
|
||||||
|
* @param context context
|
||||||
|
* @return total count
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
int countRows(Context context) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count total number of relationships (rows in relationship table) by a relationship type
|
||||||
|
*
|
||||||
|
* @param context context
|
||||||
|
* @param relationshipType relationship type to filter by
|
||||||
|
* @return total count
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a count of Relationship objects that have the given Item object
|
||||||
|
* as a leftItem or a rightItem
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param item The item that should be either a leftItem or a rightItem of all
|
||||||
|
* the Relationship objects in the returned list
|
||||||
|
* @return The list of Relationship objects that contain either a left or a
|
||||||
|
* right item that is equal to the given item
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
int countByItem(Context context, Item item) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count total number of relationships (rows in relationship table) by an item and a relationship type
|
||||||
|
*
|
||||||
|
* @param context context
|
||||||
|
* @param relationshipType relationship type to filter by
|
||||||
|
* @param item item to filter by
|
||||||
|
* @return total count
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count total number of relationships (rows in relationship table) given a typeName
|
||||||
|
*
|
||||||
|
* @param context context
|
||||||
|
* @param typeName the relationship typeName to filter by
|
||||||
|
* @return total count
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
int countByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException;
|
||||||
|
}
|
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.EntityType;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.GenericDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Access Object Interface class for the RelationshipType object
|
||||||
|
* The implementation of this class is responsible for all
|
||||||
|
* database calls for the RelationshipType object and is autowired by spring
|
||||||
|
* This class should only be accessed from a single service and should never be exposed outside of the API
|
||||||
|
*/
|
||||||
|
public interface RelationshipTypeDAO extends GenericDAO<RelationshipType> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to retrieve the RelationshipType object that has the same
|
||||||
|
* leftType, rightType, leftwardType and rightwardType as given in the parameters
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param leftType The leftType EntityType object to be matched in the query
|
||||||
|
* @param rightType The rightType EntityType object to be matched in the query
|
||||||
|
* @param leftwardType The leftwardType String to be matched in the query
|
||||||
|
* @param rightwardType The rightwardType String to be matched in the query
|
||||||
|
* @return The RelationshipType object that matches all the given parameters
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
RelationshipType findbyTypesAndTypeName(Context context, EntityType leftType,EntityType rightType,
|
||||||
|
String leftwardType,
|
||||||
|
String rightwardType)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given label is equal to
|
||||||
|
* either the leftwardType or rightwardType.
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param type The label that will be used to check on
|
||||||
|
* @return A list of RelationshipType objects that have the given label as either the leftwardType
|
||||||
|
* or rightwardType
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given label is equal to
|
||||||
|
* either the leftLabel or rightLabel.
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param type The label that will be used to check on
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return A list of RelationshipType objects that have the given label as either the leftLabel or rightLabel
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type, Integer limit,
|
||||||
|
Integer offset)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||||
|
* to the leftType or rightType
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param entityType The EntityType object that will be used to check on
|
||||||
|
* @return The list of RelationshipType objects that have the given EntityType object
|
||||||
|
* as either a leftType or rightType
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||||
|
* to the leftType or rightType
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param entityType The EntityType object that will be used to check on
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return The list of RelationshipType objects that have the given EntityType object
|
||||||
|
* as either a leftType or rightType
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Integer limit, Integer offset)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||||
|
* to the leftType or rightType
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param entityType The EntityType object that will be used to check on
|
||||||
|
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||||
|
* else right_type results.
|
||||||
|
* @return The list of RelationshipType objects that have the given EntityType object
|
||||||
|
* as either a leftType or rightType
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||||
|
* to the leftType or rightType
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param entityType The EntityType object that will be used to check on
|
||||||
|
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||||
|
* else right_type results.
|
||||||
|
* @param limit paging limit
|
||||||
|
* @param offset paging offset
|
||||||
|
* @return The list of RelationshipType objects that have the given EntityType object
|
||||||
|
* as either a leftType or rightType
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft,
|
||||||
|
Integer limit, Integer offset)
|
||||||
|
throws SQLException;
|
||||||
|
}
|
@@ -9,7 +9,6 @@ package org.dspace.content.dao.impl;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -64,11 +63,20 @@ public class CollectionDAOImpl extends AbstractHibernateDSODAO<Collection> imple
|
|||||||
public List<Collection> findAll(Context context, MetadataField order, Integer limit, Integer offset)
|
public List<Collection> findAll(Context context, MetadataField order, Integer limit, Integer offset)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
query.append("SELECT ").append(Collection.class.getSimpleName()).append(" FROM Collection as ")
|
|
||||||
.append(Collection.class.getSimpleName()).append(" ");
|
|
||||||
addMetadataLeftJoin(query, Collection.class.getSimpleName(), Arrays.asList(order));
|
|
||||||
addMetadataSortQuery(query, Arrays.asList(order), null);
|
|
||||||
|
|
||||||
|
// The query has to be rather complex because we want to sort the retrieval of Collections based on the title
|
||||||
|
// We'll join the Collections with the metadata fields on the sortfield specified in the parameters
|
||||||
|
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||||
|
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||||
|
query.append("SELECT c" +
|
||||||
|
" FROM Collection c" +
|
||||||
|
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||||
|
" title.dSpaceObject = c.id and" +
|
||||||
|
" title.place = (select min(internal.place) " +
|
||||||
|
"from c.metadata internal " +
|
||||||
|
"where internal.metadataField = :sortField and" +
|
||||||
|
" internal.dSpaceObject = c.id)" +
|
||||||
|
" ORDER BY LOWER(title.value)");
|
||||||
Query hibernateQuery = createQuery(context, query.toString());
|
Query hibernateQuery = createQuery(context, query.toString());
|
||||||
if (offset != null) {
|
if (offset != null) {
|
||||||
hibernateQuery.setFirstResult(offset);
|
hibernateQuery.setFirstResult(offset);
|
||||||
@@ -76,7 +84,7 @@ public class CollectionDAOImpl extends AbstractHibernateDSODAO<Collection> imple
|
|||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
hibernateQuery.setMaxResults(limit);
|
hibernateQuery.setMaxResults(limit);
|
||||||
}
|
}
|
||||||
hibernateQuery.setParameter(order.toString(), order.getID());
|
hibernateQuery.setParameter("sortField", order);
|
||||||
return list(hibernateQuery);
|
return list(hibernateQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,8 +8,6 @@
|
|||||||
package org.dspace.content.dao.impl;
|
package org.dspace.content.dao.impl;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
@@ -62,11 +60,20 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
public List<Community> findAll(Context context, MetadataField sortField, Integer limit, Integer offset)
|
public List<Community> findAll(Context context, MetadataField sortField, Integer limit, Integer offset)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
queryBuilder.append("SELECT ").append(Community.class.getSimpleName()).append(" FROM Community as ")
|
|
||||||
.append(Community.class.getSimpleName()).append(" ");
|
|
||||||
addMetadataLeftJoin(queryBuilder, Community.class.getSimpleName(), Arrays.asList(sortField));
|
|
||||||
addMetadataSortQuery(queryBuilder, Arrays.asList(sortField), Collections.EMPTY_LIST);
|
|
||||||
|
|
||||||
|
// The query has to be rather complex because we want to sort the retrieval of Communities based on the title
|
||||||
|
// We'll join the Communities with the metadata fields on the sortfield specified in the parameters
|
||||||
|
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||||
|
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||||
|
queryBuilder.append("SELECT c" +
|
||||||
|
" FROM Community c" +
|
||||||
|
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||||
|
" title.dSpaceObject = c.id and" +
|
||||||
|
" title.place = (select min(internal.place) " +
|
||||||
|
"from c.metadata internal " +
|
||||||
|
"where internal.metadataField = :sortField and" +
|
||||||
|
" internal.dSpaceObject = c.id)" +
|
||||||
|
" ORDER BY LOWER(title.value)");
|
||||||
Query query = createQuery(context, queryBuilder.toString());
|
Query query = createQuery(context, queryBuilder.toString());
|
||||||
if (offset != null) {
|
if (offset != null) {
|
||||||
query.setFirstResult(offset);
|
query.setFirstResult(offset);
|
||||||
@@ -74,7 +81,8 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
query.setMaxResults(limit);
|
query.setMaxResults(limit);
|
||||||
}
|
}
|
||||||
query.setParameter(sortField.toString(), sortField.getID());
|
query.setParameter("sortField", sortField);
|
||||||
|
|
||||||
return list(query);
|
return list(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +99,26 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
@Override
|
@Override
|
||||||
public List<Community> findAllNoParent(Context context, MetadataField sortField) throws SQLException {
|
public List<Community> findAllNoParent(Context context, MetadataField sortField) throws SQLException {
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
queryBuilder.append("SELECT community FROM Community as community ");
|
|
||||||
addMetadataLeftJoin(queryBuilder, Community.class.getSimpleName().toLowerCase(), Arrays.asList(sortField));
|
|
||||||
addMetadataValueWhereQuery(queryBuilder, Collections.EMPTY_LIST, null, " community.parentCommunities IS EMPTY");
|
|
||||||
addMetadataSortQuery(queryBuilder, Arrays.asList(sortField), Collections.EMPTY_LIST);
|
|
||||||
|
|
||||||
|
// The query has to be rather complex because we want to sort the retrieval of Communities based on the title
|
||||||
|
// We'll join the Communities with the metadata fields on the sortfield specified in the parameters
|
||||||
|
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||||
|
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||||
|
// This query has the added where clause to enforce that the community cannot have any parent communities
|
||||||
|
queryBuilder.append("SELECT c" +
|
||||||
|
" FROM Community c" +
|
||||||
|
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||||
|
" title.dSpaceObject = c.id and" +
|
||||||
|
" title.place = (select min(internal.place) " +
|
||||||
|
"from c.metadata internal " +
|
||||||
|
"where internal.metadataField = :sortField and" +
|
||||||
|
" internal.dSpaceObject = c.id)" +
|
||||||
|
" WHERE c.parentCommunities IS EMPTY " +
|
||||||
|
" ORDER BY LOWER(title.value)");
|
||||||
Query query = createQuery(context, queryBuilder.toString());
|
Query query = createQuery(context, queryBuilder.toString());
|
||||||
query.setParameter(sortField.toString(), sortField.getID());
|
query.setParameter("sortField", sortField);
|
||||||
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
||||||
|
|
||||||
|
|
||||||
return findMany(context, query);
|
return findMany(context, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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.content.dao.impl;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.dspace.content.EntityType;
|
||||||
|
import org.dspace.content.EntityType_;
|
||||||
|
import org.dspace.content.dao.EntityTypeDAO;
|
||||||
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
public class EntityTypeDAOImpl extends AbstractHibernateDAO<EntityType> implements EntityTypeDAO {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType findByEntityType(Context context, String entityType) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, EntityType.class);
|
||||||
|
Root<EntityType> entityTypeRoot = criteriaQuery.from(EntityType.class);
|
||||||
|
criteriaQuery.select(entityTypeRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.equal(criteriaBuilder.upper(entityTypeRoot.get(EntityType_.label)),
|
||||||
|
entityType.toUpperCase()));
|
||||||
|
return uniqueResult(context, criteriaQuery, true, EntityType.class, -1, -1);
|
||||||
|
}
|
||||||
|
}
|
@@ -15,10 +15,14 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.Item_;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.dao.ItemDAO;
|
import org.dspace.content.dao.ItemDAO;
|
||||||
@@ -283,6 +287,33 @@ public class ItemDAOImpl extends AbstractHibernateDSODAO<Item> implements ItemDA
|
|||||||
return iterate(query);
|
return iterate(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Item> findArchivedByCollectionExcludingOwning(Context context, Collection collection, Integer limit,
|
||||||
|
Integer offset) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Item.class);
|
||||||
|
Root<Item> itemRoot = criteriaQuery.from(Item.class);
|
||||||
|
criteriaQuery.select(itemRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.and(
|
||||||
|
criteriaBuilder.notEqual(itemRoot.get(Item_.owningCollection), collection),
|
||||||
|
criteriaBuilder.isMember(collection, itemRoot.get(Item_.collections)),
|
||||||
|
criteriaBuilder.isTrue(itemRoot.get(Item_.inArchive))));
|
||||||
|
return list(context, criteriaQuery, false, Item.class, limit, offset).iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countArchivedByCollectionExcludingOwning(Context context, Collection collection) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Item.class);
|
||||||
|
Root<Item> itemRoot = criteriaQuery.from(Item.class);
|
||||||
|
criteriaQuery.select(itemRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.and(
|
||||||
|
criteriaBuilder.notEqual(itemRoot.get(Item_.owningCollection), collection),
|
||||||
|
criteriaBuilder.isMember(collection, itemRoot.get(Item_.collections)),
|
||||||
|
criteriaBuilder.isTrue(itemRoot.get(Item_.inArchive))));
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, itemRoot);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException {
|
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException {
|
||||||
Query query = createQuery(context, "select i from Item i join i.collections c WHERE :collection IN c");
|
Query query = createQuery(context, "select i from Item i join i.collections c WHERE :collection IN c");
|
||||||
|
@@ -45,10 +45,22 @@ public class MetadataValueDAOImpl extends AbstractHibernateDAO<MetadataValue> im
|
|||||||
criteriaQuery.select(metadataValueRoot);
|
criteriaQuery.select(metadataValueRoot);
|
||||||
criteriaQuery.where(criteriaBuilder.equal(join.get(MetadataField_.id), metadataField.getID()));
|
criteriaQuery.where(criteriaBuilder.equal(join.get(MetadataField_.id), metadataField.getID()));
|
||||||
|
|
||||||
|
|
||||||
return list(context, criteriaQuery, false, MetadataValue.class, -1, -1);
|
return list(context, criteriaQuery, false, MetadataValue.class, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<MetadataValue> findItemValuesByFieldAndValue(Context context,
|
||||||
|
MetadataField metadataField, String value)
|
||||||
|
throws SQLException {
|
||||||
|
String queryString = "SELECT m from MetadataValue m " +
|
||||||
|
"join Item i on m.dSpaceObject = i.id where m.metadataField.id = :metadata_field_id " +
|
||||||
|
"and m.value = :text_value";
|
||||||
|
Query query = createQuery(context, queryString);
|
||||||
|
query.setParameter("metadata_field_id", metadataField.getID());
|
||||||
|
query.setParameter("text_value", value);
|
||||||
|
return iterate(query);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<MetadataValue> findByValueLike(Context context, String value) throws SQLException {
|
public Iterator<MetadataValue> findByValueLike(Context context, String value) throws SQLException {
|
||||||
String queryString = "SELECT m FROM MetadataValue m JOIN m.metadataField f " +
|
String queryString = "SELECT m FROM MetadataValue m JOIN m.metadataField f " +
|
||||||
|
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao.impl;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.dspace.content.dao.ProcessDAO;
|
||||||
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.Process;
|
||||||
|
import org.dspace.scripts.Process_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation class for {@link ProcessDAO}
|
||||||
|
*/
|
||||||
|
public class ProcessDAOImpl extends AbstractHibernateDAO<Process> implements ProcessDAO {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Process> findAllSortByScript(Context context) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||||
|
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||||
|
criteriaQuery.select(processRoot);
|
||||||
|
criteriaQuery.orderBy(criteriaBuilder.asc(processRoot.get(Process_.name)));
|
||||||
|
|
||||||
|
return list(context, criteriaQuery, false, Process.class, -1, -1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Process> findAllSortByStartTime(Context context) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||||
|
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||||
|
criteriaQuery.select(processRoot);
|
||||||
|
criteriaQuery.orderBy(criteriaBuilder.desc(processRoot.get(Process_.startTime)),
|
||||||
|
criteriaBuilder.desc(processRoot.get(Process_.processId)));
|
||||||
|
|
||||||
|
return list(context, criteriaQuery, false, Process.class, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Process> findAll(Context context, int limit, int offset) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||||
|
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||||
|
criteriaQuery.select(processRoot);
|
||||||
|
|
||||||
|
return list(context, criteriaQuery, false, Process.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countRows(Context context) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||||
|
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||||
|
criteriaQuery.select(processRoot);
|
||||||
|
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, processRoot);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao.impl;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.Relationship;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.content.Relationship_;
|
||||||
|
import org.dspace.content.dao.RelationshipDAO;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> implements RelationshipDAO {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
|
||||||
|
|
||||||
|
return findByItem(context, item, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.or(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||||
|
return list(context, criteriaQuery, false, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByItem(Context context, Item item)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.or(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item));
|
||||||
|
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
|
||||||
|
list.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
return list.get(0).getLeftPlace() + 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item));
|
||||||
|
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
|
||||||
|
list.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
return list.get(0).getRightPlace() + 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
return findByRelationshipType(context, relationshipType, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType), relationshipType));
|
||||||
|
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType, Integer limit,
|
||||||
|
Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||||
|
relationshipType), criteriaBuilder.or
|
||||||
|
(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||||
|
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||||
|
RelationshipType relationshipType, boolean isLeft,
|
||||||
|
Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
if (isLeft) {
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||||
|
relationshipType),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item));
|
||||||
|
} else {
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||||
|
relationshipType),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item));
|
||||||
|
}
|
||||||
|
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException {
|
||||||
|
return this.findByTypeName(context, typeName, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||||
|
.getRelationshipTypeService();
|
||||||
|
List<RelationshipType> relTypes = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName);
|
||||||
|
List<Integer> ids = new ArrayList<>();
|
||||||
|
for ( RelationshipType relationshipType : relTypes) {
|
||||||
|
ids.add(relationshipType.getID());
|
||||||
|
}
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.where(relationshipRoot.get(Relationship_.relationshipType).in(ids));
|
||||||
|
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType), relationshipType));
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countRows(Context context) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.select(relationshipRoot);
|
||||||
|
criteriaQuery
|
||||||
|
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||||
|
relationshipType), criteriaBuilder.or
|
||||||
|
(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||||
|
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByTypeName(Context context, String typeName)
|
||||||
|
throws SQLException {
|
||||||
|
RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||||
|
.getRelationshipTypeService();
|
||||||
|
List<RelationshipType> relTypes = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName);
|
||||||
|
List<Integer> ids = new ArrayList<>();
|
||||||
|
for ( RelationshipType relationshipType : relTypes) {
|
||||||
|
ids.add(relationshipType.getID());
|
||||||
|
}
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||||
|
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||||
|
criteriaQuery.where(relationshipRoot.get(Relationship_.relationshipType).in(ids));
|
||||||
|
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dao.impl;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.dspace.content.EntityType;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.content.RelationshipType_;
|
||||||
|
import org.dspace.content.dao.RelationshipTypeDAO;
|
||||||
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
public class RelationshipTypeDAOImpl extends AbstractHibernateDAO<RelationshipType> implements RelationshipTypeDAO {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipType findbyTypesAndTypeName(Context context, EntityType leftType, EntityType rightType,
|
||||||
|
String leftwardType, String rightwardType)
|
||||||
|
throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
|
criteriaQuery.where(
|
||||||
|
criteriaBuilder.and(
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), leftType),
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), rightType),
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), leftwardType),
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), rightwardType)));
|
||||||
|
return uniqueResult(context, criteriaQuery, false, RelationshipType.class, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException {
|
||||||
|
|
||||||
|
return findByLeftwardOrRightwardTypeName(context, type, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type, Integer limit,
|
||||||
|
Integer offset)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
|
criteriaQuery.where(
|
||||||
|
criteriaBuilder.or(
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), type),
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), type)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return list(context, criteriaQuery, true, RelationshipType.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException {
|
||||||
|
return findByEntityType(context, entityType, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
|
criteriaQuery.where(
|
||||||
|
criteriaBuilder.or(criteriaBuilder.
|
||||||
|
equal(relationshipTypeRoot.get(RelationshipType_.leftType), entityType),
|
||||||
|
criteriaBuilder
|
||||||
|
.equal(relationshipTypeRoot.get(RelationshipType_.rightType), entityType)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return list(context, criteriaQuery, false, RelationshipType.class, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft)
|
||||||
|
throws SQLException {
|
||||||
|
return findByEntityType(context, entityType, isLeft, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft,
|
||||||
|
Integer limit, Integer offset) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
|
if (isLeft) {
|
||||||
|
criteriaQuery.where(
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), entityType)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
criteriaQuery.where(
|
||||||
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), entityType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return list(context, criteriaQuery, false, RelationshipType.class, limit, offset);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* 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.content.dto;
|
||||||
|
|
||||||
|
import org.dspace.content.MetadataField;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataValue;
|
||||||
|
import org.dspace.content.authority.Choices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class acts as Data transfer object in which we can store data like in a regular MetadataValue object, but this
|
||||||
|
* one isn't saved in the DB. This can freely be used to represent Metadata without it being saved in the database,
|
||||||
|
* this will typically be used when transferring data
|
||||||
|
*
|
||||||
|
* @author kevinvandevelde at atmire.com
|
||||||
|
*/
|
||||||
|
public class MetadataValueDTO {
|
||||||
|
|
||||||
|
private String schema;
|
||||||
|
private String element;
|
||||||
|
private String qualifier;
|
||||||
|
private String language;
|
||||||
|
private String value;
|
||||||
|
private String authority;
|
||||||
|
private int confidence = Choices.CF_UNSET;
|
||||||
|
|
||||||
|
public MetadataValueDTO(MetadataValue metadataValue) {
|
||||||
|
MetadataField metadataField = metadataValue.getMetadataField();
|
||||||
|
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
|
||||||
|
schema = metadataSchema.getName();
|
||||||
|
element = metadataField.getElement();
|
||||||
|
qualifier = metadataField.getQualifier();
|
||||||
|
language = metadataValue.getLanguage();
|
||||||
|
value = metadataValue.getValue();
|
||||||
|
authority = metadataValue.getAuthority();
|
||||||
|
confidence = metadataValue.getConfidence();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetadataValueDTO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the MetadataValueDTO class
|
||||||
|
* @param schema The schema to be assigned to this MetadataValueDTO object
|
||||||
|
* @param element The element to be assigned to this MetadataValueDTO object
|
||||||
|
* @param qualifier The qualifier to be assigned to this MetadataValueDTO object
|
||||||
|
* @param language The language to be assigend to this MetadataValueDTO object
|
||||||
|
* @param value The value to be assigned to this MetadataValueDTO object
|
||||||
|
* @param authority The authority to be assigned to this MetadataValueDTO object
|
||||||
|
* @param confidence The confidence to be assigned to this MetadataValueDTO object
|
||||||
|
*/
|
||||||
|
public MetadataValueDTO(String schema, String element, String qualifier, String language, String value,
|
||||||
|
String authority, int confidence) {
|
||||||
|
this.schema = schema;
|
||||||
|
this.element = element;
|
||||||
|
this.qualifier = qualifier;
|
||||||
|
this.language = language;
|
||||||
|
this.value = value;
|
||||||
|
this.authority = authority;
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the MetadataValueDTO class
|
||||||
|
* @param schema The schema to be assigned to this MetadataValueDTO object
|
||||||
|
* @param element The element to be assigned to this MetadataValueDTO object
|
||||||
|
* @param qualifier The qualifier to be assigned to this MetadataValueDTO object
|
||||||
|
* @param language The language to be assigend to this MetadataValueDTO object
|
||||||
|
* @param value The value to be assigned to this MetadataValueDTO object
|
||||||
|
*/
|
||||||
|
public MetadataValueDTO(String schema, String element, String qualifier, String language, String value) {
|
||||||
|
this.schema = schema;
|
||||||
|
this.element = element;
|
||||||
|
this.qualifier = qualifier;
|
||||||
|
this.language = language;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchema() {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQualifier() {
|
||||||
|
return qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSchema(String schema) {
|
||||||
|
this.schema = schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElement(String element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQualifier(String qualifier) {
|
||||||
|
this.qualifier = qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthority() {
|
||||||
|
return authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthority(String authority) {
|
||||||
|
this.authority = authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConfidence() {
|
||||||
|
return confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfidence(int confidence) {
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.InProgressSubmission;
|
import org.dspace.content.InProgressSubmission;
|
||||||
|
import org.dspace.content.RelationshipMetadataService;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.service.BitstreamFormatService;
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
@@ -20,6 +21,8 @@ import org.dspace.content.service.CollectionService;
|
|||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.content.service.DSpaceObjectLegacySupportService;
|
import org.dspace.content.service.DSpaceObjectLegacySupportService;
|
||||||
import org.dspace.content.service.DSpaceObjectService;
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
|
import org.dspace.content.service.EntityService;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
import org.dspace.content.service.InProgressSubmissionService;
|
import org.dspace.content.service.InProgressSubmissionService;
|
||||||
import org.dspace.content.service.IndexableObjectService;
|
import org.dspace.content.service.IndexableObjectService;
|
||||||
import org.dspace.content.service.InstallItemService;
|
import org.dspace.content.service.InstallItemService;
|
||||||
@@ -27,6 +30,8 @@ import org.dspace.content.service.ItemService;
|
|||||||
import org.dspace.content.service.MetadataFieldService;
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
import org.dspace.content.service.MetadataSchemaService;
|
import org.dspace.content.service.MetadataSchemaService;
|
||||||
import org.dspace.content.service.MetadataValueService;
|
import org.dspace.content.service.MetadataValueService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
import org.dspace.content.service.SiteService;
|
import org.dspace.content.service.SiteService;
|
||||||
import org.dspace.content.service.SupervisedItemService;
|
import org.dspace.content.service.SupervisedItemService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
@@ -80,6 +85,36 @@ public abstract class ContentServiceFactory {
|
|||||||
|
|
||||||
public abstract SiteService getSiteService();
|
public abstract SiteService getSiteService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the implementation of the RelationshipTypeService interface
|
||||||
|
*
|
||||||
|
* @return the RelationshipTypeService
|
||||||
|
*/
|
||||||
|
public abstract RelationshipTypeService getRelationshipTypeService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the implementation of the RelationshipService interface
|
||||||
|
*
|
||||||
|
* @return the RelationshipService
|
||||||
|
*/
|
||||||
|
public abstract RelationshipService getRelationshipService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the implementation of the EntityTypeService interface
|
||||||
|
*
|
||||||
|
* @return the EntityTypeService
|
||||||
|
*/
|
||||||
|
public abstract EntityTypeService getEntityTypeService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the implementation of the EntityService interface
|
||||||
|
*
|
||||||
|
* @return the EntityService
|
||||||
|
*/
|
||||||
|
public abstract EntityService getEntityService();
|
||||||
|
|
||||||
|
public abstract RelationshipMetadataService getRelationshipMetadataService();
|
||||||
|
|
||||||
public InProgressSubmissionService getInProgressSubmissionService(InProgressSubmission inProgressSubmission) {
|
public InProgressSubmissionService getInProgressSubmissionService(InProgressSubmission inProgressSubmission) {
|
||||||
if (inProgressSubmission instanceof WorkspaceItem) {
|
if (inProgressSubmission instanceof WorkspaceItem) {
|
||||||
return getWorkspaceItemService();
|
return getWorkspaceItemService();
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.content.factory;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.RelationshipMetadataService;
|
||||||
import org.dspace.content.service.BitstreamFormatService;
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.BundleService;
|
import org.dspace.content.service.BundleService;
|
||||||
@@ -17,12 +18,16 @@ import org.dspace.content.service.CollectionService;
|
|||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.content.service.DSpaceObjectLegacySupportService;
|
import org.dspace.content.service.DSpaceObjectLegacySupportService;
|
||||||
import org.dspace.content.service.DSpaceObjectService;
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
|
import org.dspace.content.service.EntityService;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
import org.dspace.content.service.IndexableObjectService;
|
import org.dspace.content.service.IndexableObjectService;
|
||||||
import org.dspace.content.service.InstallItemService;
|
import org.dspace.content.service.InstallItemService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.content.service.MetadataFieldService;
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
import org.dspace.content.service.MetadataSchemaService;
|
import org.dspace.content.service.MetadataSchemaService;
|
||||||
import org.dspace.content.service.MetadataValueService;
|
import org.dspace.content.service.MetadataValueService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
import org.dspace.content.service.SiteService;
|
import org.dspace.content.service.SiteService;
|
||||||
import org.dspace.content.service.SupervisedItemService;
|
import org.dspace.content.service.SupervisedItemService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
@@ -69,6 +74,17 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private SiteService siteService;
|
private SiteService siteService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private RelationshipService relationshipService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
private RelationshipTypeService relationshipTypeService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
private RelationshipMetadataService relationshipMetadataService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
private EntityTypeService entityTypeService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
private EntityService entityService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IndexableObjectService> getIndexableObjectServices() {
|
public List<IndexableObjectService> getIndexableObjectServices() {
|
||||||
return new DSpace().getServiceManager().getServicesByType(IndexableObjectService.class);
|
return new DSpace().getServiceManager().getServicesByType(IndexableObjectService.class);
|
||||||
@@ -149,4 +165,28 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
|||||||
return siteService;
|
return siteService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipTypeService getRelationshipTypeService() {
|
||||||
|
return relationshipTypeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipService getRelationshipService() {
|
||||||
|
return relationshipService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityTypeService getEntityTypeService() {
|
||||||
|
return entityTypeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityService getEntityService() {
|
||||||
|
return entityService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipMetadataService getRelationshipMetadataService() {
|
||||||
|
return relationshipMetadataService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,7 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.DCDate;
|
import org.dspace.content.DCDate;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.crosswalk.CrosswalkException;
|
import org.dspace.content.crosswalk.CrosswalkException;
|
||||||
import org.dspace.content.crosswalk.MetadataValidationException;
|
import org.dspace.content.crosswalk.MetadataValidationException;
|
||||||
@@ -377,10 +377,11 @@ public class PDFPackager
|
|||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("PDF Info dict title=\"" + title + "\"");
|
log.debug("PDF Info dict title=\"" + title + "\"");
|
||||||
}
|
}
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "title", null, "en", title);
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(), "title", null, "en", title);
|
||||||
String value = docinfo.getAuthor();
|
String value = docinfo.getAuthor();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "contributor", "author", null, value);
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"contributor", "author", null, value);
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("PDF Info dict author=\"" + value + "\"");
|
log.debug("PDF Info dict author=\"" + value + "\"");
|
||||||
}
|
}
|
||||||
@@ -388,25 +389,29 @@ public class PDFPackager
|
|||||||
|
|
||||||
value = docinfo.getCreator();
|
value = docinfo.getCreator();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en",
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"description", "provenance", "en",
|
||||||
"Application that created the original document: " + value);
|
"Application that created the original document: " + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = docinfo.getProducer();
|
value = docinfo.getProducer();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "description", "provenance", "en",
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"description", "provenance", "en",
|
||||||
"Original document converted to PDF by: " + value);
|
"Original document converted to PDF by: " + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = docinfo.getSubject();
|
value = docinfo.getSubject();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
itemService
|
itemService
|
||||||
.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "description", "abstract", null, value);
|
.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"description", "abstract", null, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = docinfo.getKeywords();
|
value = docinfo.getKeywords();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "subject", "other", null, value);
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||||
|
"subject", "other", null, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take either CreationDate or ModDate as "date.created",
|
// Take either CreationDate or ModDate as "date.created",
|
||||||
@@ -417,7 +422,7 @@ public class PDFPackager
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (calValue != null) {
|
if (calValue != null) {
|
||||||
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "date", "created", null,
|
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(), "date", "created", null,
|
||||||
(new DCDate(calValue.getTime())).toString());
|
(new DCDate(calValue.getTime())).toString());
|
||||||
}
|
}
|
||||||
itemService.update(context, item);
|
itemService.update(context, item);
|
||||||
|
@@ -30,7 +30,7 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
@@ -158,7 +158,7 @@ public class PackageUtils {
|
|||||||
*/
|
*/
|
||||||
public static void checkItemMetadata(Item item)
|
public static void checkItemMetadata(Item item)
|
||||||
throws PackageValidationException {
|
throws PackageValidationException {
|
||||||
List<MetadataValue> t = itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
List<MetadataValue> t = itemService.getMetadata(item, MetadataSchemaEnum.DC.getName(), "title", null, Item.ANY);
|
||||||
if (t == null || t.size() == 0) {
|
if (t == null || t.size() == 0) {
|
||||||
throw new PackageValidationException("Item cannot be created without the required \"title\" DC metadata.");
|
throw new PackageValidationException("Item cannot be created without the required \"title\" DC metadata.");
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user