mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-16 14:33:09 +00:00
Merge remote-tracking branch 'upstream/main' into w2p-72472_Delete-eperson
This commit is contained in:
@@ -3,3 +3,9 @@
|
||||
.settings/
|
||||
*/target/
|
||||
dspace/modules/*/target/
|
||||
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/
|
||||
|
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -1,6 +1,12 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Ensure Unix files always keep Unix line endings
|
||||
*.sh text eol=lf
|
||||
|
||||
# Ensure Windows files always keep Windows line endings
|
||||
*.bat text eol=crlf
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
|
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug, needs triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. Include the version(s) of DSpace where you've seen this problem. Link to examples if they are public.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Do this
|
||||
2. Then this...
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Related work**
|
||||
Link to any related tickets or PRs here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest a new feature for this project
|
||||
title: ''
|
||||
labels: new feature, needs triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives or workarounds you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
26
.github/disabled-workflows/pull_request_opened.yml
vendored
Normal file
26
.github/disabled-workflows/pull_request_opened.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# This workflow runs whenever a new pull request is created
|
||||
# TEMPORARILY DISABLED. Unfortunately this doesn't work for PRs created from forked repositories (which is how we tend to create PRs).
|
||||
# There is no known workaround yet. See https://github.community/t/how-to-use-github-token-for-prs-from-forks/16818
|
||||
name: Pull Request opened
|
||||
|
||||
# Only run for newly opened PRs against the "main" branch
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
automation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Assign the PR to whomever created it. This is useful for visualizing assignments on project boards
|
||||
# See https://github.com/marketplace/actions/pull-request-assigner
|
||||
- name: Assign PR to creator
|
||||
uses: thomaseizinger/assign-pr-creator-action@v1.0.0
|
||||
# Note, this authentication token is created automatically
|
||||
# See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Ignore errors. It is possible the PR was created by someone who cannot be assigned
|
||||
continue-on-error: true
|
26
.github/pull_request_template.md
vendored
Normal file
26
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
## References
|
||||
_Add references/links to any related issues or PRs. These may include:_
|
||||
* Related to [REST Contract](https://github.com/DSpace/Rest7Contract) or an open REST Contract PR, if any
|
||||
* Fixes [GitHub issue](https://github.com/DSpace/DSpace/issues), if any
|
||||
|
||||
## Description
|
||||
Short summary of changes (1-2 sentences).
|
||||
|
||||
## Instructions for Reviewers
|
||||
Please add a more detailed description of the changes made by your PR. At a minimum, providing a bulleted list of changes in your PR is helpful to reviewers.
|
||||
|
||||
List of changes in this PR:
|
||||
* First, ...
|
||||
* Second, ...
|
||||
|
||||
**Include guidance for how to test or review your PR.** This may include: steps to reproduce a bug, screenshots or description of a new feature, or reasons behind specific changes.
|
||||
|
||||
## Checklist
|
||||
_This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!_
|
||||
|
||||
- [ ] My PR is small in size (e.g. less than 1,000 lines of code, not including comments & integration tests). Exceptions may be made if previously agreed upon.
|
||||
- [ ] My PR passes Checkstyle validation based on the [Code Style Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Style+Guide).
|
||||
- [ ] My PR includes Javadoc for _all new (or modified) public methods and classes_. It also includes Javadoc for large or complex private methods.
|
||||
- [ ] My PR passes all tests and includes new/updated Unit or Integration Tests based on the [Code Testing Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Testing+Guide).
|
||||
- [ ] If my PR includes new, third-party dependencies (in any `pom.xml`), I've made sure their licenses align with the [DSpace BSD License](https://github.com/DSpace/DSpace/blob/main/LICENSE) based on the [Licensing of Contributions](https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines#CodeContributionGuidelines-LicensingofContributions) documentation.
|
||||
- [ ] If my PR modifies the REST API, I've linked to the REST Contract page (or open PR) related to this change.
|
29
.github/workflows/issue_opened.yml
vendored
Normal file
29
.github/workflows/issue_opened.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# This workflow runs whenever a new issue is created
|
||||
name: Issue opened
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
automation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Add the new issue to a project board, if it needs triage
|
||||
# See https://github.com/marketplace/actions/create-project-card-action
|
||||
- name: Add issue to project board
|
||||
# Only add to project board if issue is flagged as "needs triage" or has no labels
|
||||
# NOTE: By default we flag new issues as "needs triage" in our issue template
|
||||
if: (contains(github.event.issue.labels.*.name, 'needs triage') || join(github.event.issue.labels.*.name) == '')
|
||||
uses: technote-space/create-project-card-action@v1
|
||||
# Note, the authentication token below is an ORG level Secret.
|
||||
# It must be created/recreated manually via a personal access token with "public_repo" and "admin:org" permissions
|
||||
# See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#permissions-for-the-github_token
|
||||
# This is necessary because the "DSpace Backlog" project is an org level project (i.e. not repo specific)
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_PROJECT_TOKEN }}
|
||||
PROJECT: DSpace Backlog
|
||||
COLUMN: Triage
|
||||
CHECK_ORG_PROJECT: true
|
||||
# Ignore errors.
|
||||
continue-on-error: true
|
9
.lgtm.yml
Normal file
9
.lgtm.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
# LGTM Settings (https://lgtm.com/)
|
||||
# For reference, see https://lgtm.com/help/lgtm/lgtm.yml-configuration-file
|
||||
# or template at https://lgtm.com/static/downloads/lgtm.template.yml
|
||||
|
||||
extraction:
|
||||
java:
|
||||
index:
|
||||
# Specify the Java version required to build the project
|
||||
java_version: 11
|
28
.travis.yml
28
.travis.yml
@@ -1,14 +1,15 @@
|
||||
language: java
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
# Give Maven 1GB of memory to work with
|
||||
- MAVEN_OPTS=-Xmx1024M
|
||||
|
||||
jdk:
|
||||
# DS-3384 Oracle JDK 8 has DocLint enabled by default.
|
||||
# DS-3384 Oracle JDK has DocLint enabled by default.
|
||||
# Let's use this to catch any newly introduced DocLint issues.
|
||||
- oraclejdk8
|
||||
- oraclejdk11
|
||||
|
||||
## Should we run into any problems with oraclejdk8 on Travis, we may try the following workaround.
|
||||
## https://docs.travis-ci.com/user/languages/java#Testing-Against-Multiple-JDKs
|
||||
@@ -18,7 +19,6 @@ jdk:
|
||||
# packages:
|
||||
# - oracle-java8-installer
|
||||
|
||||
# Install prerequisites for building Mirage2 more rapidly
|
||||
before_install:
|
||||
# Remove outdated settings.xml from Travis builds. Workaround for https://github.com/travis-ci/travis-ci/issues/4629
|
||||
- rm ~/.m2/settings.xml
|
||||
@@ -26,19 +26,21 @@ before_install:
|
||||
# Skip install stage, as we'll do it below
|
||||
install: "echo 'Skipping install stage, dependencies will be downloaded during build and test stages.'"
|
||||
|
||||
# Two stage Build and Test
|
||||
# 1. Install & Unit Test APIs
|
||||
# 2. Assemble DSpace
|
||||
# Build DSpace and run both Unit and Integration Tests
|
||||
script:
|
||||
# 1. [Install & Unit Test] Check source code licenses and run source code Unit Tests
|
||||
# Summary of flags used (below):
|
||||
# license:check => Validate all source code license headers
|
||||
# -Dmaven.test.skip=false => Enable DSpace Unit Tests
|
||||
# -DskipTests=false => Enable DSpace Unit Tests
|
||||
# -DskipITs=false => Enable DSpace Integration Tests
|
||||
# -P !assembly => Skip normal assembly (as it can be memory intensive)
|
||||
# -Pdspace-rest => Enable optional dspace-rest module as part of build
|
||||
# -P !assembly => Skip assembly of "dspace-installer" directory (as it can be memory intensive)
|
||||
# -B => Maven batch/non-interactive mode (recommended for CI)
|
||||
# -V => Display Maven version info before build
|
||||
# -Dsurefire.rerunFailingTestsCount=2 => try again for flakey tests, and keep track of/report on number of retries
|
||||
- "mvn clean install license:check -Dmaven.test.skip=false -DskipITs=false -P !assembly -B -V -Dsurefire.rerunFailingTestsCount=2"
|
||||
# 2. [Assemble DSpace] Ensure overlay & assembly process works (from [src]/dspace/)
|
||||
# -P !assembly => SKIP the actual building of [src]/dspace/dspace-installer (as it can be memory intensive)
|
||||
- "cd dspace && mvn package -P !assembly -B -V -Dsurefire.rerunFailingTestsCount=2"
|
||||
- "mvn clean install license:check -DskipTests=false -DskipITs=false -Pdspace-rest -P !assembly -B -V -Dsurefire.rerunFailingTestsCount=2"
|
||||
|
||||
# After a successful build and test (see 'script'), send code coverage reports to coveralls.io
|
||||
# These code coverage reports are generated by jacoco-maven-plugin (during test process above).
|
||||
after_success:
|
||||
# Run "verify", enabling the "coveralls" profile. This sends our reports to coveralls.io (see coveralls-maven-plugin)
|
||||
- "cd dspace && mvn verify -P coveralls"
|
||||
|
63
Dockerfile
Normal file
63
Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
||||
# This image will be published as dspace/dspace
|
||||
# See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details
|
||||
#
|
||||
# This version is JDK11 compatible
|
||||
# - tomcat:8-jdk11
|
||||
# - ANT 1.10.7
|
||||
# - maven:3-jdk-11 (see dspace-dependencies)
|
||||
# - note: default tag for branch: dspace/dspace: dspace/dspace: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 (note: this build doesn't include the optional, deprecated "dspace-rest" webapp)
|
||||
# Copy the dspace-install directory to /install. Clean up the build to keep the docker image small
|
||||
RUN mvn package && \
|
||||
mv /app/dspace/target/${TARGET_DIR}/* /install && \
|
||||
mvn clean
|
||||
|
||||
# Step 2 - Run Ant Deploy
|
||||
FROM tomcat:8-jdk11 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 update_webapps
|
||||
|
||||
# Step 3 - Run tomcat
|
||||
# Create a new tomcat image that does not retain the the build directory contents
|
||||
FROM tomcat:8-jdk11
|
||||
ENV DSPACE_INSTALL=/dspace
|
||||
COPY --from=ant_build /dspace $DSPACE_INSTALL
|
||||
EXPOSE 8080 8009
|
||||
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server
|
||||
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||
# 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
|
53
Dockerfile.cli
Normal file
53
Dockerfile.cli
Normal file
@@ -0,0 +1,53 @@
|
||||
# This image will be published as dspace/dspace-cli
|
||||
# See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details
|
||||
#
|
||||
# This version is JDK11 compatible
|
||||
# - openjdk:11
|
||||
# - ANT 1.10.7
|
||||
# - maven:3-jdk-11 (see dspace-dependencies)
|
||||
# - 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 && \
|
||||
mv /app/dspace/target/${TARGET_DIR}/* /install && \
|
||||
mvn clean
|
||||
|
||||
# Step 2 - Run Ant Deploy
|
||||
FROM openjdk:11 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:11
|
||||
ENV DSPACE_INSTALL=/dspace
|
||||
COPY --from=ant_build /dspace $DSPACE_INSTALL
|
||||
|
||||
ENV JAVA_OPTS=-Xmx1000m
|
27
Dockerfile.dependencies
Normal file
27
Dockerfile.dependencies
Normal file
@@ -0,0 +1,27 @@
|
||||
# This image will be published as dspace/dspace-dependencies
|
||||
# The purpose of this image is to make the build for dspace/dspace run faster
|
||||
#
|
||||
# This version is JDK11 compatible
|
||||
# - maven:3-jdk-11
|
||||
|
||||
# Step 1 - Run Maven Build
|
||||
FROM maven:3-jdk-11 as build
|
||||
ARG TARGET_DIR=dspace-installer
|
||||
WORKDIR /app
|
||||
|
||||
RUN useradd dspace \
|
||||
&& mkdir /home/dspace \
|
||||
&& chown -Rv dspace: /home/dspace
|
||||
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
|
||||
|
||||
# Trigger the installation of all maven dependencies
|
||||
RUN mvn package
|
||||
|
||||
# Clear the contents of the /app directory (including all maven builds), so no artifacts remain.
|
||||
# This ensures when dspace:dspace is built, it will just the Maven local cache (.m2) for dependencies
|
||||
USER root
|
||||
RUN rm -rf /app/*
|
@@ -1,60 +0,0 @@
|
||||
# This image will be published as dspace/dspace
|
||||
# See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details
|
||||
#
|
||||
# This version is JDK8 compatible
|
||||
# - tomcat:8-jre8
|
||||
# - ANT 1.10.5
|
||||
# - maven:latest
|
||||
# - note:
|
||||
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8
|
||||
|
||||
# Step 1 - Run Maven Build
|
||||
FROM maven as build
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the DSpace source code into the workdir (excluding .dockerignore contents)
|
||||
ADD . /app/
|
||||
COPY dspace/src/main/docker/local.cfg /app/local.cfg
|
||||
|
||||
RUN mvn package
|
||||
|
||||
# Step 2 - Run Ant Deploy
|
||||
FROM tomcat:8-jre8 as ant_build
|
||||
ARG TARGET_DIR=dspace-installer
|
||||
COPY --from=build /app /dspace-src
|
||||
WORKDIR /dspace-src/dspace/target/${TARGET_DIR}
|
||||
|
||||
# Create the initial install deployment using ANT
|
||||
ENV ANT_VERSION 1.10.5
|
||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||
ENV PATH $ANT_HOME/bin:$PATH
|
||||
|
||||
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
|
||||
|
||||
RUN ant update_configs update_code update_webapps update_solr_indexes
|
||||
|
||||
# Step 3 - Run tomcat
|
||||
# Create a new tomcat image that does not retain the the build directory contents
|
||||
FROM tomcat:8-jre8
|
||||
COPY --from=ant_build /dspace /dspace
|
||||
EXPOSE 8080 8009
|
||||
|
||||
# Ant will be embedded in the final container to allow additional deployments
|
||||
ENV ANT_VERSION 1.10.5
|
||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||
ENV PATH $ANT_HOME/bin:$PATH
|
||||
|
||||
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
|
||||
|
||||
ENV DSPACE_INSTALL=/dspace
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
@@ -1,64 +0,0 @@
|
||||
# This image will be published as dspace/dspace
|
||||
# See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details
|
||||
#
|
||||
# This version is JDK8 compatible
|
||||
# - tomcat:8-jre8
|
||||
# - ANT 1.10.5
|
||||
# - maven:latest
|
||||
# - note: expose /solr to any host; provide /rest over http
|
||||
# - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8-test
|
||||
|
||||
# Step 1 - Run Maven Build
|
||||
FROM maven as build
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the DSpace source code into the workdir (excluding .dockerignore contents)
|
||||
ADD . /app/
|
||||
COPY dspace/src/main/docker/local.cfg /app/local.cfg
|
||||
|
||||
# Provide web.xml overrides to make webapps easier to test
|
||||
COPY dspace/src/main/docker/test/solr_web.xml /app/dspace-solr/src/main/webapp/WEB-INF/web.xml
|
||||
COPY dspace/src/main/docker/test/rest_web.xml /app/dspace-rest/src/main/webapp/WEB-INF/web.xml
|
||||
|
||||
RUN mvn package
|
||||
|
||||
# Step 2 - Run Ant Deploy
|
||||
FROM tomcat:8-jre8 as ant_build
|
||||
ARG TARGET_DIR=dspace-installer
|
||||
COPY --from=build /app /dspace-src
|
||||
WORKDIR /dspace-src/dspace/target/${TARGET_DIR}
|
||||
|
||||
# Create the initial install deployment using ANT
|
||||
ENV ANT_VERSION 1.10.5
|
||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||
ENV PATH $ANT_HOME/bin:$PATH
|
||||
|
||||
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
|
||||
|
||||
RUN ant update_configs update_code update_webapps update_solr_indexes
|
||||
|
||||
# Step 3 - Run tomcat
|
||||
# Create a new tomcat image that does not retain the the build directory contents
|
||||
FROM tomcat:8-jre8
|
||||
COPY --from=ant_build /dspace /dspace
|
||||
EXPOSE 8080 8009
|
||||
|
||||
# Ant will be embedded in the final container to allow additional deployments
|
||||
ENV ANT_VERSION 1.10.5
|
||||
ENV ANT_HOME /tmp/ant-$ANT_VERSION
|
||||
ENV PATH $ANT_HOME/bin:$PATH
|
||||
|
||||
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
|
||||
|
||||
ENV DSPACE_INSTALL=/dspace
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
72
Dockerfile.test
Normal file
72
Dockerfile.test
Normal file
@@ -0,0 +1,72 @@
|
||||
# This image will be published as dspace/dspace
|
||||
# See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details
|
||||
#
|
||||
# This version is JDK11 compatible
|
||||
# - tomcat:8-jdk11
|
||||
# - ANT 1.10.7
|
||||
# - maven:3-jdk-11 (see dspace-dependencies)
|
||||
# - note: default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-test
|
||||
#
|
||||
# This image is meant for TESTING/DEVELOPMENT ONLY as it deploys the old v6 REST API under HTTP (not HTTPS)
|
||||
|
||||
# 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 (including the optional, deprecated "dspace-rest" webapp)
|
||||
# Copy the dspace-install directory to /install. Clean up the build to keep the docker image small
|
||||
RUN mvn package -Pdspace-rest && \
|
||||
mv /app/dspace/target/${TARGET_DIR}/* /install && \
|
||||
mvn clean
|
||||
|
||||
# Step 2 - Run Ant Deploy
|
||||
FROM tomcat:8-jdk11 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 update_webapps
|
||||
|
||||
# Step 3 - Run tomcat
|
||||
# Create a new tomcat image that does not retain the the build directory contents
|
||||
FROM tomcat:8-jdk11
|
||||
ENV DSPACE_INSTALL=/dspace
|
||||
COPY --from=ant_build /dspace $DSPACE_INSTALL
|
||||
EXPOSE 8080 8009
|
||||
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||
# and the v6.x (deprecated) REST API off the "/rest" path
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||
# 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
|
||||
|
||||
# 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
|
||||
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
5
LICENSE
5
LICENSE
@@ -1,7 +1,6 @@
|
||||
DSpace source code license:
|
||||
DSpace source code BSD License:
|
||||
|
||||
|
||||
Copyright (c) 2002-2016, DuraSpace. All rights reserved.
|
||||
Copyright (c) 2002-2020, LYRASIS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
9
NOTICE
9
NOTICE
@@ -1,11 +1,14 @@
|
||||
Licensing Notices
|
||||
=================
|
||||
|
||||
Licensing Notice
|
||||
[July 2019] DuraSpace joined with LYRASIS (another 501(c)3 organization) in July 2019.
|
||||
LYRASIS holds the copyrights of DuraSpace.
|
||||
|
||||
Fedora Commons joined with the DSpace Foundation and began operating under
|
||||
[July 2009] Fedora Commons joined with the DSpace Foundation and began operating under
|
||||
the new name DuraSpace in July 2009. DuraSpace holds the copyrights of
|
||||
the DSpace Foundation, Inc.
|
||||
|
||||
The DSpace Foundation, Inc. is a 501(c)3 corporation established in July 2007
|
||||
[July 2007] The DSpace Foundation, Inc. is a 501(c)3 corporation established in July 2007
|
||||
with a mission to promote and advance the dspace platform enabling management,
|
||||
access and preservation of digital works. The Foundation was able to transfer
|
||||
the legal copyright from Hewlett-Packard Company (HP) and Massachusetts
|
||||
|
92
README.md
92
README.md
@@ -1,24 +1,24 @@
|
||||
|
||||
# DSpace
|
||||
|
||||
[](https://travis-ci.org/DSpace/DSpace)
|
||||
[](https://travis-ci.com/DSpace/DSpace)
|
||||
|
||||
[DSpace Documentation](https://wiki.duraspace.org/display/DSDOC/) |
|
||||
[DSpace Documentation](https://wiki.lyrasis.org/display/DSDOC/) |
|
||||
[DSpace Releases](https://github.com/DSpace/DSpace/releases) |
|
||||
[DSpace Wiki](https://wiki.duraspace.org/display/DSPACE/Home) |
|
||||
[Support](https://wiki.duraspace.org/display/DSPACE/Support)
|
||||
[DSpace Wiki](https://wiki.lyrasis.org/display/DSPACE/Home) |
|
||||
[Support](https://wiki.lyrasis.org/display/DSPACE/Support)
|
||||
|
||||
DSpace open source software is a turnkey repository application used by more than
|
||||
2,000 organizations and institutions worldwide to provide durable access to digital resources.
|
||||
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:
|
||||
* DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-spring-rest) of this repository.
|
||||
* The REST Contract is being documented at https://github.com/DSpace/Rest7Contract
|
||||
:warning: **Work on DSpace 7 has begun on our `main` branch.** This means that there is NO user interface on this `main` 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 Working Group](https://wiki.lyrasis.org/display/DSPACE/DSpace+7+Working+Group) page. Additionally, the codebases can be found in the following places:
|
||||
* DSpace 7 REST API work is occurring on the [`main` branch](https://github.com/DSpace/DSpace/tree/main/dspace-server-webapp) of this repository.
|
||||
* The REST Contract is at https://github.com/DSpace/Rest7Contract
|
||||
* DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular
|
||||
|
||||
**If you would like to get involved in our DSpace 7 development effort, we welcome new contributors.** Just join one of our meetings or get in touch via Slack. See the [DSpace 7 UI Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) wiki page for more info.
|
||||
**If you would like to get involved in our DSpace 7 development effort, we welcome new contributors.** Just join one of our meetings or get in touch via Slack. See the [DSpace 7 Working Group](https://wiki.lyrasis.org/display/DSPACE/DSpace+7+Working+Group) wiki page for more info.
|
||||
|
||||
**If you are looking for the ongoing maintenance work for DSpace 6 (or prior releases)**, you can find that work on the corresponding maintenance branch (e.g. [`dspace-6_x`](https://github.com/DSpace/DSpace/tree/dspace-6_x)) in this repository.
|
||||
***
|
||||
@@ -31,17 +31,17 @@ Past releases are all available via GitHub at https://github.com/DSpace/DSpace/r
|
||||
|
||||
## Documentation / Installation
|
||||
|
||||
Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.duraspace.org/display/DSDOC/).
|
||||
Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.lyrasis.org/display/DSDOC/).
|
||||
|
||||
The latest DSpace Installation instructions are available at:
|
||||
https://wiki.duraspace.org/display/DSDOC6x/Installing+DSpace
|
||||
https://wiki.lyrasis.org/display/DSDOC6x/Installing+DSpace
|
||||
|
||||
Please be aware that, as a Java web application, DSpace requires a database (PostgreSQL or Oracle)
|
||||
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.
|
||||
|
||||
## Dockerfile Usage
|
||||
See the [DSpace Docker Tutorial](https://dspace-labs.github.io/DSpace-Docker-Images/).
|
||||
## Running DSpace 7 in Docker
|
||||
See [Running DSpace 7 with Docker Compose](dspace/src/main/docker-compose/README.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -49,14 +49,14 @@ DSpace is a community built and supported project. We do not have a centralized
|
||||
but have a dedicated group of volunteers who help us improve the software, documentation, resources, etc.
|
||||
|
||||
We welcome contributions of any type. Here's a few basic guides that provide suggestions for contributing to DSpace:
|
||||
* [How to Contribute to DSpace](https://wiki.duraspace.org/display/DSPACE/How+to+Contribute+to+DSpace): How to contribute in general (via code, documentation, bug reports, expertise, etc)
|
||||
* [Code Contribution Guidelines](https://wiki.duraspace.org/display/DSPACE/Code+Contribution+Guidelines): How to give back code or contribute features, bug fixes, etc.
|
||||
* [DSpace Community Advisory Team (DCAT)](https://wiki.duraspace.org/display/cmtygp/DSpace+Community+Advisory+Team): If you are not a developer, we also have an interest group specifically for repository managers. The DCAT group meets virtually, once a month, and sends open invitations to join their meetings via the [DCAT mailing list](https://groups.google.com/d/forum/DSpaceCommunityAdvisoryTeam).
|
||||
* [How to Contribute to DSpace](https://wiki.lyrasis.org/display/DSPACE/How+to+Contribute+to+DSpace): How to contribute in general (via code, documentation, bug reports, expertise, etc)
|
||||
* [Code Contribution Guidelines](https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines): How to give back code or contribute features, bug fixes, etc.
|
||||
* [DSpace Community Advisory Team (DCAT)](https://wiki.lyrasis.org/display/cmtygp/DSpace+Community+Advisory+Team): If you are not a developer, we also have an interest group specifically for repository managers. The DCAT group meets virtually, once a month, and sends open invitations to join their meetings via the [DCAT mailing list](https://groups.google.com/d/forum/DSpaceCommunityAdvisoryTeam).
|
||||
|
||||
We also encourage GitHub Pull Requests (PRs) at any time. Please see our [Development with Git](https://wiki.duraspace.org/display/DSPACE/Development+with+Git) guide for more info.
|
||||
We also encourage GitHub Pull Requests (PRs) at any time. Please see our [Development with Git](https://wiki.lyrasis.org/display/DSPACE/Development+with+Git) guide for more info.
|
||||
|
||||
In addition, a listing of all known contributors to DSpace software can be
|
||||
found online at: https://wiki.duraspace.org/display/DSPACE/DSpaceContributors
|
||||
found online at: https://wiki.lyrasis.org/display/DSPACE/DSpaceContributors
|
||||
|
||||
## Getting Help
|
||||
|
||||
@@ -64,12 +64,12 @@ DSpace provides public mailing lists where you can post questions or raise topic
|
||||
We welcome everyone to participate in these lists:
|
||||
|
||||
* [dspace-community@googlegroups.com](https://groups.google.com/d/forum/dspace-community) : General discussion about DSpace platform, announcements, sharing of best practices
|
||||
* [dspace-tech@googlegroups.com](https://groups.google.com/d/forum/dspace-tech) : Technical support mailing list. See also our guide for [How to troubleshoot an error](https://wiki.duraspace.org/display/DSPACE/Troubleshoot+an+error).
|
||||
* [dspace-tech@googlegroups.com](https://groups.google.com/d/forum/dspace-tech) : Technical support mailing list. See also our guide for [How to troubleshoot an error](https://wiki.lyrasis.org/display/DSPACE/Troubleshoot+an+error).
|
||||
* [dspace-devel@googlegroups.com](https://groups.google.com/d/forum/dspace-devel) : Developers / Development mailing list
|
||||
|
||||
Great Q&A is also available under the [DSpace tag on Stackoverflow](http://stackoverflow.com/questions/tagged/dspace)
|
||||
|
||||
Additional support options are listed at https://wiki.duraspace.org/display/DSPACE/Support
|
||||
Additional support options are at https://wiki.lyrasis.org/display/DSPACE/Support
|
||||
|
||||
DSpace also has an active service provider network. If you'd rather hire a service provider to
|
||||
install, upgrade, customize or host DSpace, then we recommend getting in touch with one of our
|
||||
@@ -77,9 +77,59 @@ install, upgrade, customize or host DSpace, then we recommend getting in touch w
|
||||
|
||||
## Issue Tracker
|
||||
|
||||
The DSpace Issue Tracker can be found at: https://jira.duraspace.org/projects/DS/summary
|
||||
DSpace uses GitHub to track issues:
|
||||
* Backend (REST API) issues: https://github.com/DSpace/DSpace/issues
|
||||
* Frontend (User Interface) issues: https://github.com/DSpace/dspace-angular/issues
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Tests
|
||||
|
||||
By default, in DSpace, Unit Tests and Integration Tests are disabled. However, they are
|
||||
run automatically by [Travis CI](https://travis-ci.com/DSpace/DSpace/) for all Pull Requests and code commits.
|
||||
|
||||
* How to run both Unit Tests (via `maven-surefire-plugin`) and Integration Tests (via `maven-failsafe-plugin`):
|
||||
```
|
||||
mvn clean test -DskipTests=false -DskipITs=false
|
||||
```
|
||||
* How to run just Unit Tests:
|
||||
```
|
||||
mvn test -DskipTests=false
|
||||
```
|
||||
* How to run a *single* Unit Test
|
||||
```
|
||||
# Run all tests in a specific test class
|
||||
# NOTE: failIfNoTests=false is required to skip tests in other modules
|
||||
mvn test -DskipTests=false -Dtest=[full.package.testClassName] -DfailIfNoTests=false
|
||||
|
||||
# Run one test method in a specific test class
|
||||
mvn test -DskipTests=false -Dtest=[full.package.testClassName]#[testMethodName] -DfailIfNoTests=false
|
||||
```
|
||||
* How to run Integration Tests (requires enabling Unit tests too)
|
||||
```
|
||||
mvn verify -DskipTests=false -DskipITs=false
|
||||
```
|
||||
* How to run a *single* Integration Test (requires enabling Unit tests too)
|
||||
```
|
||||
# Run all integration tests in a specific test class
|
||||
# NOTE: failIfNoTests=false is required to skip tests in other modules
|
||||
mvn test -DskipTests=false -DskipITs=false -Dtest=[full.package.testClassName] -DfailIfNoTests=false
|
||||
|
||||
# Run one test method in a specific test class
|
||||
mvn test -DskipTests=false -DskipITs=false -Dtest=[full.package.testClassName]#[testMethodName] -DfailIfNoTests=false
|
||||
```
|
||||
* How to run only tests of a specific DSpace module
|
||||
```
|
||||
# Before you can run only one module's tests, other modules may need installing into your ~/.m2
|
||||
cd [dspace-src]
|
||||
mvn clean install
|
||||
|
||||
# Then, move into a module subdirectory, and run the test command
|
||||
cd [dspace-src]/dspace-server-webapp
|
||||
# Choose your test command from the lists above
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
DSpace source code is freely available under a standard [BSD 3-Clause license](https://opensource.org/licenses/BSD-3-Clause).
|
||||
The full license is available at http://www.dspace.org/license/
|
||||
The full license is available in the [LICENSE](LICENSE) file or online at http://www.dspace.org/license/
|
||||
|
@@ -44,15 +44,16 @@ For more information on CheckStyle configurations below, see: http://checkstyle.
|
||||
with @SuppressWarnings. See also SuppressWarningsHolder below -->
|
||||
<module name="SuppressWarningsFilter" />
|
||||
|
||||
<!-- Check individual Java source files for specific rules -->
|
||||
<module name="TreeWalker">
|
||||
<!-- Maximum line length is 120 characters -->
|
||||
<module name="LineLength">
|
||||
<property name="fileExtensions" value="java"/>
|
||||
<property name="max" value="120"/>
|
||||
<!-- Only exceptions for packages, imports, URLs, and JavaDoc {@link} tags -->
|
||||
<property name="ignorePattern" value="^package.*|^import.*|http://|https://|@link"/>
|
||||
</module>
|
||||
|
||||
<!-- Check individual Java source files for specific rules -->
|
||||
<module name="TreeWalker">
|
||||
<!-- Highlight any TODO or FIXME comments in info messages -->
|
||||
<module name="TodoComment">
|
||||
<property name="severity" value="info"/>
|
||||
@@ -94,11 +95,8 @@ For more information on CheckStyle configurations below, see: http://checkstyle.
|
||||
<!-- <property name="scope" value="public"/> -->
|
||||
<!-- TODO: Above rule has been disabled because of large amount of missing public method Javadocs -->
|
||||
<property name="scope" value="nothing"/>
|
||||
<!-- Allow RuntimeExceptions to be undeclared -->
|
||||
<property name="allowUndeclaredRTE" value="true"/>
|
||||
<!-- Allow params, throws and return tags to be optional -->
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingThrowsTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
</module>
|
||||
|
||||
|
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
|
||||
#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:
|
69
docker-compose.yml
Normal file
69
docker-compose.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
version: '3.7'
|
||||
networks:
|
||||
dspacenet:
|
||||
services:
|
||||
dspace:
|
||||
container_name: dspace
|
||||
image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-test}"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.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
|
||||
# 1. While a TCP connection to dspacedb port 5432 is not available, continue to sleep
|
||||
# 2. Then, run database migration to init database tables
|
||||
# 3. Finally, start Tomcat
|
||||
entrypoint:
|
||||
- /bin/bash
|
||||
- '-c'
|
||||
- |
|
||||
while (!</dev/tcp/dspacedb/5432) > /dev/null 2>&1; do sleep 1; done;
|
||||
/dspace/bin/dspace database migrate
|
||||
catalina.sh run
|
||||
dspacedb:
|
||||
container_name: dspacedb
|
||||
environment:
|
||||
PGDATA: /pgdata
|
||||
image: dspace/dspace-postgres-pgcrypto
|
||||
networks:
|
||||
dspacenet:
|
||||
ports:
|
||||
- published: 5432
|
||||
target: 5432
|
||||
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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
@@ -13,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.0-SNAPSHOT</version>
|
||||
<version>7.0-beta4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -51,10 +50,33 @@
|
||||
<configuration>
|
||||
<debug>true</debug>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<compilerArguments>
|
||||
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
|
||||
</compilerArguments>
|
||||
|
||||
<annotationProcessorPaths>
|
||||
<!-- Enable Hibernate's Metamodel Generator to generate metadata model classes
|
||||
(ending in _ suffix) for more type-safe Criteria queries -->
|
||||
<path>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</path>
|
||||
<!-- Enable JAXB -->
|
||||
<path>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>${jaxb-api.version}</version>
|
||||
</path>
|
||||
<!-- Enable Commons Annotations -->
|
||||
<path>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>${javax-annotation.version}</version>
|
||||
</path>
|
||||
<!-- Enable http://errorprone.info -->
|
||||
<path>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<version>${errorprone.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -76,26 +98,11 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Verify OS license headers for all source code files -->
|
||||
<plugin>
|
||||
<groupId>com.mycila</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/src/test/resources/**</exclude>
|
||||
<exclude>**/src/test/data/**</exclude>
|
||||
<exclude>**/.gitignore</exclude>
|
||||
<exclude>**/src/main/resources/rebel.xml</exclude>
|
||||
<exclude>src/test/data/dspaceFolder/config/spiders/**</exclude>
|
||||
<exclude>src/main/java/org/apache/solr/handler/extraction/ExtractingParams.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.9.1</version>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
@@ -130,7 +137,7 @@
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
<!-- property>
|
||||
<name>maven.test.skip</name>
|
||||
<name>skipTests</name>
|
||||
<value>false</value>
|
||||
</property -->
|
||||
</activation>
|
||||
@@ -151,7 +158,7 @@
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
<property>
|
||||
<name>maven.test.skip</name>
|
||||
<name>skipTests</name>
|
||||
<value>false</value>
|
||||
</property>
|
||||
</activation>
|
||||
@@ -163,7 +170,6 @@
|
||||
install of DSpace, against which Tests can be run. -->
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/testing</outputDirectory>
|
||||
<artifactItems>
|
||||
@@ -198,7 +204,7 @@
|
||||
(see: http://gmaven.codehaus.org/Executing+Groovy+Code )
|
||||
We are generating a OS-agnostic version (agnostic.build.dir) of
|
||||
the ${project.build.directory} property (full path of target dir).
|
||||
This is needed by the FileWeaver & Surefire plugins (see below)
|
||||
This is needed by the Surefire & Failsafe plugins (see below)
|
||||
to initialize the Unit Test environment's dspace.cfg file.
|
||||
Otherwise, the Unit Test Framework will not work on Windows OS.
|
||||
This Groovy code was mostly borrowed from:
|
||||
@@ -207,19 +213,17 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmaven</groupId>
|
||||
<artifactId>groovy-maven-plugin</artifactId>
|
||||
<version>2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>setproperty</id>
|
||||
<phase>generate-test-resources
|
||||
</phase> <!-- XXX I think this should be 'initialize' - MHW -->
|
||||
<phase>initialize</phase>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<source>
|
||||
project.properties['agnostic.build.dir'] = project.build.directory.replace(File.separator, '/');
|
||||
println("Initializing Maven property 'agnostic.build.dir' to: " + project.properties['agnostic.build.dir']);
|
||||
log.info("Initializing Maven property 'agnostic.build.dir' to: {}", project.properties['agnostic.build.dir']);
|
||||
</source>
|
||||
</configuration>
|
||||
</execution>
|
||||
@@ -232,62 +236,27 @@
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<!-- Specify the dspace.dir to use for test environment -->
|
||||
<!-- ${agnostic.build.dir} is set dynamically by groovy-maven-plugin above -->
|
||||
<!-- This system property is loaded by AbstractDSpaceTest to initialize the test environment -->
|
||||
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||
<!-- Turn off any DSpace logging -->
|
||||
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>xml-maven-plugin</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate-ALL-xml-and-xsl</id>
|
||||
<phase>process-test-resources</phase>
|
||||
<goals>
|
||||
<goal>validate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<validationSets>
|
||||
<!-- validate ALL XML and XSL config files in the testing folder -->
|
||||
<validationSet>
|
||||
<dir>${agnostic.build.dir}/testing</dir>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.xsl</include>
|
||||
<include>**/*.xconf</include>
|
||||
</includes>
|
||||
</validationSet>
|
||||
<!-- validate ALL XML and XSL files throughout the project -->
|
||||
<validationSet>
|
||||
<dir>${root.basedir}</dir>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.xsl</include>
|
||||
<include>**/*.xmap</include>
|
||||
</includes>
|
||||
</validationSet>
|
||||
</validationSets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!-- Run Integration Testing! This plugin just kicks off the tests (when enabled). -->
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<!-- Specify the dspace.dir to use for test environment -->
|
||||
<!-- ${agnostic.build.dir} is set dynamically by groovy-maven-plugin above -->
|
||||
<dspace.dir>${agnostic.build.dir}/testing/dspace/</dspace.dir>
|
||||
<!-- Turn off any DSpace logging -->
|
||||
<dspace.log.init.disable>true</dspace.log.init.disable>
|
||||
<solr.install.dir>${agnostic.build.dir}/testing/dspace/solr/</solr.install.dir>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@@ -298,16 +267,7 @@
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-ehcache</artifactId>
|
||||
@@ -317,10 +277,11 @@
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator-cdi</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
@@ -332,9 +293,25 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<groupId>net.handle</groupId>
|
||||
<artifactId>handle</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.cnri</groupId>
|
||||
<artifactId>cnri-servlet-container</artifactId>
|
||||
<exclusions>
|
||||
<!-- Newer versions provided in our parent POM -->
|
||||
<exclusion>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-commons</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Jetty is needed to run Handle Server -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>jargon</artifactId>
|
||||
@@ -347,24 +324,6 @@
|
||||
<groupId>org.apache.jena</groupId>
|
||||
<artifactId>apache-jena-libs</artifactId>
|
||||
<type>pom</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
@@ -426,18 +385,6 @@
|
||||
<groupId>org.jdom</groupId>
|
||||
<artifactId>jdom</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-1.2-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>oro</groupId>
|
||||
<artifactId>oro</artifactId>
|
||||
@@ -450,18 +397,6 @@
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>fontbox</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcmail-jdk15</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
@@ -481,12 +416,6 @@
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>xml-apis</groupId>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xml-apis</groupId>
|
||||
@@ -508,11 +437,6 @@
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-services</artifactId>
|
||||
</dependency>
|
||||
<dependency> <!-- Keep jmockit before junit -->
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
@@ -533,77 +457,193 @@
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.rometools</groupId>
|
||||
<artifactId>rome-modules</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.ekt.bte</groupId>
|
||||
<artifactId>bte-core</artifactId>
|
||||
<version>0.9.3.5</version>
|
||||
<exclusions>
|
||||
<!-- A more recent version is retrieved from another dependency -->
|
||||
<exclusion>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.ekt.bte</groupId>
|
||||
<artifactId>bte-io</artifactId>
|
||||
<version>0.9.3.5</version>
|
||||
<exclusions>
|
||||
<!-- A more recent version is retrieved from another dependency -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</exclusion>
|
||||
<!-- A more recent version is retrieved from another dependency -->
|
||||
<exclusion>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
<version>${solr.client.version}</version>
|
||||
</dependency>
|
||||
<!-- Solr Core is needed for Integration Tests (to run a MockSolrServer) -->
|
||||
<!-- The following Solr / Lucene dependencies also support integration tests -->
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>${solr.client.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-xml</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-cell</artifactId>
|
||||
<exclusions>
|
||||
<!-- Newer versions provided in our parent POM -->
|
||||
<exclusion>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-commons</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-xml</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-core</artifactId>
|
||||
</dependency>
|
||||
<!-- Reminder: Keep icu4j (in Parent POM) synced with version used by lucene-analyzers-icu below,
|
||||
otherwise ICUFoldingFilterFactory may throw errors in tests. -->
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-icu</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-smartcn</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-analyzers-stempel</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlbeans</groupId>
|
||||
<artifactId>xmlbeans</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip2</groupId>
|
||||
<artifactId>geoip2</artifactId>
|
||||
@@ -619,12 +659,6 @@
|
||||
<version>2.1.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-core</artifactId>
|
||||
<version>4.10.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.coverity.security</groupId>
|
||||
<artifactId>coverity-escapers</artifactId>
|
||||
@@ -649,11 +683,6 @@
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jdbm</groupId>
|
||||
<artifactId>jdbm</artifactId>
|
||||
@@ -715,19 +744,44 @@
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
|
||||
<!-- JAXB API and implementation (no longer bundled as of Java 11) -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Axiom -->
|
||||
<dependency>
|
||||
<groupId>org.apache.ws.commons.axiom</groupId>
|
||||
<artifactId>axiom-impl</artifactId>
|
||||
<!-- NOTE: SWORDv2 needs 1.2.14, required by Abdera: https://abdera.apache.org/ -->
|
||||
<version>1.2.14</version>
|
||||
<version>${axiom.version}</version>
|
||||
<exclusions>
|
||||
<!-- Exclude Geronimo as it is NOT necessary when using javax.activation (which we use)
|
||||
See: https://ws.apache.org/axiom/userguide/ch04.html#d0e732 -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.ws.commons.axiom</groupId>
|
||||
<artifactId>axiom-api</artifactId>
|
||||
<!-- NOTE: SWORDv2 needs 1.2.14, required by Abdera: https://abdera.apache.org/ -->
|
||||
<version>1.2.14</version>
|
||||
<version>${axiom.version}</version>
|
||||
<exclusions>
|
||||
<!-- Exclude Geronimo as it is NOT necessary when using javax.activation (which we use)
|
||||
See: https://ws.apache.org/axiom/userguide/ch04.html#d0e732 -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
@@ -738,12 +792,6 @@
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
<version>1.10.50</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- For ORCID v2 integration -->
|
||||
@@ -757,6 +805,41 @@
|
||||
<artifactId>json</artifactId>
|
||||
<version>20180130</version>
|
||||
</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-core</artifactId>
|
||||
<version>2.6.3</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>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.bcel</groupId>
|
||||
<artifactId>bcel</artifactId>
|
||||
<version>6.4.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</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";
|
||||
}
|
@@ -180,14 +180,10 @@ public class CommunityFiliator {
|
||||
// second test - circularity: parent's parents can't include proposed
|
||||
// child
|
||||
List<Community> parentDads = parent.getParentCommunities();
|
||||
|
||||
for (int i = 0; i < parentDads.size(); i++) {
|
||||
if (parentDads.get(i).getID().equals(child.getID())) {
|
||||
System.out
|
||||
.println("Error, circular parentage - child is parent of parent");
|
||||
if (parentDads.contains(child)) {
|
||||
System.out.println("Error, circular parentage - child is parent of parent");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// everthing's OK
|
||||
communityService.addSubcommunity(c, parent, child);
|
||||
@@ -210,26 +206,15 @@ public class CommunityFiliator {
|
||||
throws SQLException, AuthorizeException, IOException {
|
||||
// verify that child is indeed a child of parent
|
||||
List<Community> parentKids = parent.getSubcommunities();
|
||||
boolean isChild = false;
|
||||
|
||||
for (int i = 0; i < parentKids.size(); i++) {
|
||||
if (parentKids.get(i).getID().equals(child.getID())) {
|
||||
isChild = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isChild) {
|
||||
System.out
|
||||
.println("Error, child community not a child of parent community");
|
||||
if (!parentKids.contains(child)) {
|
||||
System.out.println("Error, child community not a child of parent community");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// OK remove the mappings - but leave the community, which will become
|
||||
// top-level
|
||||
child.getParentCommunities().remove(parent);
|
||||
parent.getSubcommunities().remove(child);
|
||||
child.removeParentCommunity(parent);
|
||||
parent.removeSubCommunity(child);
|
||||
communityService.update(c, child);
|
||||
communityService.update(c, parent);
|
||||
|
||||
|
@@ -115,7 +115,7 @@ public final class CreateAdministrator {
|
||||
String lastName = null;
|
||||
char[] password1 = null;
|
||||
char[] password2 = null;
|
||||
String language = I18nUtil.DEFAULTLOCALE.getLanguage();
|
||||
String language = I18nUtil.getDefaultLocale().getLanguage();
|
||||
|
||||
while (!dataOK) {
|
||||
System.out.print("E-mail address: ");
|
||||
|
@@ -21,6 +21,7 @@ import org.apache.xpath.XPathAPI;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.NonUniqueMetadataException;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.MetadataFieldService;
|
||||
@@ -248,7 +249,7 @@ public class MetadataImporter {
|
||||
|
||||
// If the schema is not provided default to DC
|
||||
if (schema == null) {
|
||||
schema = MetadataSchema.DC_SCHEMA;
|
||||
schema = MetadataSchemaEnum.DC.getName();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -7,12 +7,16 @@
|
||||
*/
|
||||
package org.dspace.administer;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -21,12 +25,18 @@ import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.xpath.XPathAPI;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
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.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
@@ -34,6 +44,7 @@ import org.dspace.core.Context;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.output.Format;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -45,7 +56,7 @@ import org.xml.sax.SAXException;
|
||||
* an XML file.
|
||||
*
|
||||
* The XML file structure needs to be:
|
||||
* {@code
|
||||
* <pre>{@code
|
||||
* <import_structure>
|
||||
* <community>
|
||||
* <name>....</name>
|
||||
@@ -55,34 +66,41 @@ import org.xml.sax.SAXException;
|
||||
* </collection>
|
||||
* </community>
|
||||
* </import_structure>
|
||||
* }
|
||||
* it can be arbitrarily deep, and supports all the metadata elements
|
||||
* }</pre>
|
||||
* <p>
|
||||
* It can be arbitrarily deep, and supports all the metadata elements
|
||||
* that make up the community and collection metadata. See the system
|
||||
* documentation for more details
|
||||
* documentation for more details.
|
||||
*
|
||||
* @author Richard Jones
|
||||
*/
|
||||
|
||||
public class StructBuilder {
|
||||
/**
|
||||
* the output xml document which will contain updated information about the
|
||||
* imported structure
|
||||
/** Name of the root element for the document to be imported. */
|
||||
static final String INPUT_ROOT = "import_structure";
|
||||
|
||||
/*
|
||||
* Name of the root element for the document produced by importing.
|
||||
* Community and collection elements are annotated with their identifiers.
|
||||
*/
|
||||
private static org.jdom.Document xmlOutput = new org.jdom.Document(new Element("imported_structure"));
|
||||
static final String RESULT_ROOT = "imported_structure";
|
||||
|
||||
/**
|
||||
* a hashtable to hold metadata for the collection being worked on
|
||||
* A table to hold metadata for the collection being worked on.
|
||||
*/
|
||||
private static Map<String, String> collectionMap = new HashMap<String, String>();
|
||||
private static final Map<String, String> collectionMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* a hashtable to hold metadata for the community being worked on
|
||||
* A table to hold metadata for the community being worked on.
|
||||
*/
|
||||
private static Map<String, String> communityMap = new HashMap<String, String>();
|
||||
private static final Map<String, String> communityMap = new HashMap<>();
|
||||
|
||||
protected static CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||
protected static CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
protected static EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
protected static CommunityService communityService
|
||||
= ContentServiceFactory.getInstance().getCommunityService();
|
||||
protected static CollectionService collectionService
|
||||
= ContentServiceFactory.getInstance().getCollectionService();
|
||||
protected static EPersonService ePersonService
|
||||
= EPersonServiceFactory.getInstance().getEPersonService();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
@@ -91,63 +109,156 @@ public class StructBuilder {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* with the handle for each imported item added as an attribute.
|
||||
* <p>{@code StructBuilder -x -e [administrator email] -o [output file]}</p>
|
||||
*
|
||||
* @param argv the command line arguments given
|
||||
* @throws Exception if an error occurs
|
||||
* <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 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)
|
||||
throws Exception {
|
||||
CommandLineParser parser = new PosixParser();
|
||||
|
||||
throws ParserConfigurationException, SQLException,
|
||||
FileNotFoundException, IOException, TransformerException {
|
||||
// Define command line options.
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("f", "file", true, "file");
|
||||
options.addOption("e", "eperson", true, "eperson");
|
||||
options.addOption("o", "output", true, "output");
|
||||
options.addOption("h", "help", false, "Print this help message.");
|
||||
options.addOption("?", "help");
|
||||
options.addOption("x", "export", false, "Export the current structure as XML.");
|
||||
|
||||
CommandLine line = parser.parse(options, argv);
|
||||
options.addOption(Option.builder("e").longOpt("eperson")
|
||||
.desc("User who is manipulating the repository's structure.")
|
||||
.hasArg().argName("eperson").required().build());
|
||||
|
||||
String file = null;
|
||||
String eperson = null;
|
||||
String output = null;
|
||||
options.addOption(Option.builder("f").longOpt("file")
|
||||
.desc("File of new structure information.")
|
||||
.hasArg().argName("input").build());
|
||||
|
||||
if (line.hasOption('f')) {
|
||||
file = line.getOptionValue('f');
|
||||
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;
|
||||
try {
|
||||
line = parser.parse(options, argv);
|
||||
} catch (ParseException ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
usage(options);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (line.hasOption('e')) {
|
||||
eperson = line.getOptionValue('e');
|
||||
}
|
||||
|
||||
if (line.hasOption('o')) {
|
||||
output = line.getOptionValue('o');
|
||||
}
|
||||
|
||||
if (output == null || eperson == null || file == null) {
|
||||
usage();
|
||||
// If the user asked for help, give it and exit.
|
||||
if (line.hasOption('h') || line.hasOption('?')) {
|
||||
giveHelp(options);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
// Otherwise, analyze the command.
|
||||
// Must be import or export.
|
||||
if (!(line.hasOption('f') || line.hasOption('x'))) {
|
||||
giveHelp(options);
|
||||
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
|
||||
Context context = new Context();
|
||||
|
||||
// set the context
|
||||
// set the context.
|
||||
String eperson = line.getOptionValue('e');
|
||||
try {
|
||||
context.setCurrentUser(ePersonService.findByEmail(context, eperson));
|
||||
} catch (SQLException ex) {
|
||||
System.err.format("That user could not be found: %s%n", ex.getMessage());
|
||||
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);
|
||||
// save changes from import
|
||||
context.complete();
|
||||
}
|
||||
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
|
||||
Document document = loadXML(file);
|
||||
Document document = null;
|
||||
try {
|
||||
document = loadXML(input);
|
||||
} catch (IOException ex) {
|
||||
System.err.format("The input document could not be read: %s%n", ex.getMessage());
|
||||
System.exit(1);
|
||||
} catch (SAXException ex) {
|
||||
System.err.format("The input document could not be parsed: %s%n", ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// run the preliminary validation, to be sure that the the XML document
|
||||
// is properly structured
|
||||
// is properly structured.
|
||||
try {
|
||||
validate(document);
|
||||
} catch (TransformerException ex) {
|
||||
System.err.format("The input document is invalid: %s%n", ex.getMessage());
|
||||
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
|
||||
communityMap.put("name", "name");
|
||||
@@ -164,62 +275,190 @@ public class StructBuilder {
|
||||
collectionMap.put("license", "license");
|
||||
collectionMap.put("provenance", "provenance_description");
|
||||
|
||||
Element[] elements = new Element[]{};
|
||||
try {
|
||||
// get the top level community list
|
||||
NodeList first = XPathAPI.selectNodeList(document, "/import_structure/community");
|
||||
|
||||
// run the import starting with the top level communities
|
||||
Element[] elements = handleCommunities(context, first, null);
|
||||
elements = handleCommunities(context, first, null);
|
||||
} catch (TransformerException ex) {
|
||||
System.err.format("Input content not understood: %s%n", ex.getMessage());
|
||||
System.exit(1);
|
||||
} catch (AuthorizeException ex) {
|
||||
System.err.format("Not authorized: %s%n", ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// generate the output
|
||||
Element root = xmlOutput.getRootElement();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
root.addContent(elements[i]);
|
||||
final Element root = new Element(RESULT_ROOT);
|
||||
|
||||
for (Element element : elements) {
|
||||
root.addContent(element);
|
||||
}
|
||||
|
||||
// finally write the string into the output file
|
||||
// finally write the string into the output file.
|
||||
final org.jdom.Document xmlOutput = new org.jdom.Document(root);
|
||||
try {
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(output));
|
||||
out.write(new XMLOutputter().outputString(xmlOutput));
|
||||
out.close();
|
||||
new XMLOutputter().output(xmlOutput, output);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Unable to write to output file " + output);
|
||||
System.exit(0);
|
||||
System.out.printf("Unable to write to output file %s: %s%n",
|
||||
output, e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
context.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the usage information
|
||||
* Add a single community, and its children, to the Document.
|
||||
*
|
||||
* @param community
|
||||
* @return a fragment representing this Community.
|
||||
*/
|
||||
private static void usage() {
|
||||
System.out.println("Usage: java StructBuilder -f <source XML file> -o <output file> -e <eperson email>");
|
||||
System.out.println(
|
||||
"Communities will be created from the top level, and a map of communities to handles will be returned in " +
|
||||
"the output file");
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the XML document. This method does not return, but if validation
|
||||
* fails it generates an error and ceases execution
|
||||
* 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.
|
||||
*/
|
||||
private static void usage(Options options) {
|
||||
HelpFormatter helper = new HelpFormatter();
|
||||
try (PrintWriter writer = new PrintWriter(System.out);) {
|
||||
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,
|
||||
"When importing (-f), communities will be created from the "
|
||||
+ "top level, and a map of communities to handles will "
|
||||
+ "be returned in the output file. When exporting (-x),"
|
||||
+ "the current structure will be written to the map file.",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the XML document. This method returns if the document is valid.
|
||||
* If validation fails it generates an error and ceases execution.
|
||||
*
|
||||
* @param document the XML document object
|
||||
* @throws TransformerException if transformer error
|
||||
*/
|
||||
private static void validate(org.w3c.dom.Document document)
|
||||
throws TransformerException {
|
||||
StringBuffer err = new StringBuffer();
|
||||
StringBuilder err = new StringBuilder();
|
||||
boolean trip = false;
|
||||
|
||||
err.append("The following errors were encountered parsing the source XML\n");
|
||||
err.append("No changes have been made to the DSpace instance\n\n");
|
||||
err.append("The following errors were encountered parsing the source XML.\n");
|
||||
err.append("No changes have been made to the DSpace instance.\n\n");
|
||||
|
||||
NodeList first = XPathAPI.selectNodeList(document, "/import_structure/community");
|
||||
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.exit(0);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
String errs = validateCommunities(first, 1);
|
||||
@@ -230,13 +469,13 @@ public class StructBuilder {
|
||||
|
||||
if (trip) {
|
||||
System.out.println(err.toString());
|
||||
System.exit(0);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the communities section of the XML document. This returns a string
|
||||
* containing any errors encountered, or null if there were no errors
|
||||
* containing any errors encountered, or null if there were no errors.
|
||||
*
|
||||
* @param communities the NodeList of communities to validate
|
||||
* @param level the level in the XML document that we are at, for the purposes
|
||||
@@ -246,7 +485,7 @@ public class StructBuilder {
|
||||
*/
|
||||
private static String validateCommunities(NodeList communities, int level)
|
||||
throws TransformerException {
|
||||
StringBuffer err = new StringBuffer();
|
||||
StringBuilder err = new StringBuilder();
|
||||
boolean trip = false;
|
||||
String errs = null;
|
||||
|
||||
@@ -255,8 +494,9 @@ public class StructBuilder {
|
||||
NodeList name = XPathAPI.selectNodeList(n, "name");
|
||||
if (name.getLength() != 1) {
|
||||
String pos = Integer.toString(i + 1);
|
||||
err.append("-The level " + level + " community in position " + pos);
|
||||
err.append(" does not contain exactly one name field\n");
|
||||
err.append("-The level ").append(level)
|
||||
.append(" community in position ").append(pos)
|
||||
.append(" does not contain exactly one name field.\n");
|
||||
trip = true;
|
||||
}
|
||||
|
||||
@@ -286,7 +526,7 @@ public class StructBuilder {
|
||||
|
||||
/**
|
||||
* validate the collection section of the XML document. This generates a
|
||||
* string containing any errors encountered, or returns null if no errors
|
||||
* string containing any errors encountered, or returns null if no errors.
|
||||
*
|
||||
* @param collections a NodeList of collections to validate
|
||||
* @param level the level in the XML document for the purposes of error reporting
|
||||
@@ -294,7 +534,7 @@ public class StructBuilder {
|
||||
*/
|
||||
private static String validateCollections(NodeList collections, int level)
|
||||
throws TransformerException {
|
||||
StringBuffer err = new StringBuffer();
|
||||
StringBuilder err = new StringBuilder();
|
||||
boolean trip = false;
|
||||
String errs = null;
|
||||
|
||||
@@ -303,8 +543,9 @@ public class StructBuilder {
|
||||
NodeList name = XPathAPI.selectNodeList(n, "name");
|
||||
if (name.getLength() != 1) {
|
||||
String pos = Integer.toString(i + 1);
|
||||
err.append("-The level " + level + " collection in position " + pos);
|
||||
err.append(" does not contain exactly one name field\n");
|
||||
err.append("-The level ").append(level)
|
||||
.append(" collection in position ").append(pos)
|
||||
.append(" does not contain exactly one name field.\n");
|
||||
trip = true;
|
||||
}
|
||||
}
|
||||
@@ -317,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
|
||||
* @return the DOM representation of the XML file
|
||||
* @param input the filename to load from.
|
||||
* @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 {
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder();
|
||||
|
||||
org.w3c.dom.Document document = builder.parse(new File(filename));
|
||||
org.w3c.dom.Document document = builder.parse(input);
|
||||
|
||||
return document;
|
||||
}
|
||||
@@ -338,7 +579,7 @@ public class StructBuilder {
|
||||
* @param node the node from which we want to extract the string value
|
||||
* @return the string value of the node
|
||||
*/
|
||||
public static String getStringValue(Node node) {
|
||||
private static String getStringValue(Node node) {
|
||||
String value = node.getNodeValue();
|
||||
|
||||
if (node.hasChildNodes()) {
|
||||
@@ -363,7 +604,7 @@ public class StructBuilder {
|
||||
* created communities (e.g. the handles they have been assigned)
|
||||
*/
|
||||
private static Element[] handleCommunities(Context context, NodeList communities, Community parent)
|
||||
throws TransformerException, SQLException, Exception {
|
||||
throws TransformerException, SQLException, AuthorizeException {
|
||||
Element[] elements = new Element[communities.getLength()];
|
||||
|
||||
for (int i = 0; i < communities.getLength(); i++) {
|
||||
@@ -390,12 +631,10 @@ public class StructBuilder {
|
||||
}
|
||||
|
||||
// FIXME: at the moment, if the community already exists by name
|
||||
// then this will throw a PSQLException on a duplicate key
|
||||
// violation
|
||||
// Ideally we'd skip this row and continue to create sub
|
||||
// communities
|
||||
// and so forth where they don't exist, but it's proving
|
||||
// difficult
|
||||
// then this will throw an SQLException on a duplicate key
|
||||
// violation.
|
||||
// Ideally we'd skip this row and continue to create sub communities
|
||||
// and so forth where they don't exist, but it's proving difficult
|
||||
// to isolate the community that already exists without hitting
|
||||
// the database directly.
|
||||
communityService.update(context, community);
|
||||
@@ -470,7 +709,7 @@ public class StructBuilder {
|
||||
* created collections (e.g. the handle)
|
||||
*/
|
||||
private static Element[] handleCollections(Context context, NodeList collections, Community parent)
|
||||
throws TransformerException, SQLException, AuthorizeException, IOException, Exception {
|
||||
throws TransformerException, SQLException, AuthorizeException {
|
||||
Element[] elements = new Element[collections.getLength()];
|
||||
|
||||
for (int i = 0; i < collections.getLength(); i++) {
|
||||
|
@@ -19,6 +19,7 @@ import org.dspace.content.Item;
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class BulkEditChange {
|
||||
|
||||
/**
|
||||
* The item these changes relate to
|
||||
*/
|
||||
|
@@ -8,14 +8,10 @@
|
||||
package org.dspace.app.bulkedit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -27,6 +23,8 @@ import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.authority.AuthorityValue;
|
||||
import org.dspace.authority.factory.AuthorityServiceFactory;
|
||||
import org.dspace.authority.service.AuthorityValueService;
|
||||
@@ -34,6 +32,7 @@ import org.dspace.content.Collection;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.authority.Choices;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
@@ -139,18 +138,18 @@ public class DSpaceCSV implements Serializable {
|
||||
/**
|
||||
* Create a new instance, reading the lines in from file
|
||||
*
|
||||
* @param f The file to read from
|
||||
* @param inputStream the inputstream to read from
|
||||
* @param c The DSpace Context
|
||||
* @throws Exception thrown if there is an error reading or processing the file
|
||||
*/
|
||||
public DSpaceCSV(File f, Context c) throws Exception {
|
||||
public DSpaceCSV(InputStream inputStream, Context c) throws Exception {
|
||||
// Initialise the class
|
||||
init();
|
||||
|
||||
// Open the CSV file
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
input = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
|
||||
input = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
|
||||
// Read the heading line
|
||||
String head = input.readLine();
|
||||
@@ -168,6 +167,9 @@ public class DSpaceCSV implements Serializable {
|
||||
if ("collection".equals(element)) {
|
||||
// Store the heading
|
||||
headings.add(element);
|
||||
} else if ("rowName".equals(element)) {
|
||||
// Store the heading
|
||||
headings.add(element);
|
||||
} else if ("action".equals(element)) { // Store the action
|
||||
// Store the heading
|
||||
headings.add(element);
|
||||
@@ -198,10 +200,12 @@ public class DSpaceCSV implements Serializable {
|
||||
}
|
||||
|
||||
// Check that the scheme exists
|
||||
if (!StringUtils.equals(metadataSchema, MetadataSchemaEnum.RELATION.getName())) {
|
||||
MetadataSchema foundSchema = metadataSchemaService.find(c, metadataSchema);
|
||||
if (foundSchema == null) {
|
||||
throw new MetadataImportInvalidHeadingException(clean[0],
|
||||
MetadataImportInvalidHeadingException.SCHEMA,
|
||||
MetadataImportInvalidHeadingException
|
||||
.SCHEMA,
|
||||
columnCounter);
|
||||
}
|
||||
|
||||
@@ -210,9 +214,11 @@ public class DSpaceCSV implements Serializable {
|
||||
.findByElement(c, foundSchema, metadataElement, metadataQualifier);
|
||||
if (foundField == null) {
|
||||
throw new MetadataImportInvalidHeadingException(clean[0],
|
||||
MetadataImportInvalidHeadingException.ELEMENT,
|
||||
MetadataImportInvalidHeadingException
|
||||
.ELEMENT,
|
||||
columnCounter);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the heading
|
||||
headings.add(authorityPrefix + element);
|
||||
@@ -614,21 +620,15 @@ public class DSpaceCSV implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the CSV file to the given filename
|
||||
*
|
||||
* @param filename The filename to save the CSV file to
|
||||
* @throws IOException Thrown if an error occurs when writing the file
|
||||
* Creates and returns an InputStream from the CSV Lines in this DSpaceCSV
|
||||
* @return The InputStream created from the CSVLines in this DSpaceCSV
|
||||
*/
|
||||
public final void save(String filename) throws IOException {
|
||||
// Save the file
|
||||
BufferedWriter out = new BufferedWriter(
|
||||
new OutputStreamWriter(
|
||||
new FileOutputStream(filename), "UTF-8"));
|
||||
public InputStream getInputStream() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String csvLine : getCSVLinesAsStringArray()) {
|
||||
out.write(csvLine + "\n");
|
||||
stringBuilder.append(csvLine + "\n");
|
||||
}
|
||||
out.flush();
|
||||
out.close();
|
||||
return IOUtils.toInputStream(stringBuilder.toString(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -8,271 +8,84 @@
|
||||
package org.dspace.app.bulkedit;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
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.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.content.service.MetadataDSpaceCsvExportService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
* Metadata exporter to allow the batch export of metadata into a file
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class MetadataExport {
|
||||
/**
|
||||
* The items to export
|
||||
*/
|
||||
protected Iterator<Item> toExport;
|
||||
public class MetadataExport extends DSpaceRunnable<MetadataExportScriptConfiguration> {
|
||||
|
||||
protected ItemService itemService;
|
||||
private boolean help = false;
|
||||
private String filename = null;
|
||||
private String handle = null;
|
||||
private boolean exportAllMetadata = false;
|
||||
private boolean exportAllItems = false;
|
||||
|
||||
protected Context context;
|
||||
private static final String EXPORT_CSV = "exportCSV";
|
||||
|
||||
/**
|
||||
* Whether to export all metadata, or just normally edited metadata
|
||||
*/
|
||||
protected boolean exportAll;
|
||||
private MetadataDSpaceCsvExportService metadataDSpaceCsvExportService = new DSpace().getServiceManager()
|
||||
.getServicesByType(MetadataDSpaceCsvExportService.class).get(0);
|
||||
|
||||
protected MetadataExport() {
|
||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
|
||||
@Override
|
||||
public void internalRun() throws Exception {
|
||||
|
||||
if (help) {
|
||||
handler.logInfo("\nfull export: metadata-export -f filename");
|
||||
handler.logInfo("partial export: metadata-export -i handle -f filename");
|
||||
printHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a new metadata export
|
||||
*
|
||||
* @param c The Context
|
||||
* @param toExport The ItemIterator of items to export
|
||||
* @param exportAll whether to export all metadata or not (include handle, provenance etc)
|
||||
*/
|
||||
public MetadataExport(Context c, Iterator<Item> toExport, boolean exportAll) {
|
||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
|
||||
// Store the export settings
|
||||
this.toExport = toExport;
|
||||
this.exportAll = exportAll;
|
||||
this.context = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to export a community (and sub-communities and collections)
|
||||
*
|
||||
* @param c The Context
|
||||
* @param toExport The Community to export
|
||||
* @param exportAll whether to export all metadata or not (include handle, provenance etc)
|
||||
*/
|
||||
public MetadataExport(Context c, Community toExport, boolean exportAll) {
|
||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
|
||||
Context context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
try {
|
||||
// Try to export the community
|
||||
this.toExport = buildFromCommunity(c, toExport, 0);
|
||||
this.exportAll = exportAll;
|
||||
this.context = c;
|
||||
} catch (SQLException sqle) {
|
||||
// Something went wrong...
|
||||
System.err.println("Error running exporter:");
|
||||
sqle.printStackTrace(System.err);
|
||||
System.exit(1);
|
||||
context.setCurrentUser(ePersonService.find(context, this.getEpersonIdentifier()));
|
||||
} catch (SQLException e) {
|
||||
handler.handleException(e);
|
||||
}
|
||||
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService
|
||||
.handleExport(context, exportAllItems, exportAllMetadata, handle,
|
||||
handler);
|
||||
handler.writeFilestream(context, filename, dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||
context.restoreAuthSystemState();
|
||||
context.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an array list of item ids that are in a community (include sub-communities and collections)
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param community The community to build from
|
||||
* @param indent How many spaces to use when writing out the names of items added
|
||||
* @return The list of item ids
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
protected Iterator<Item> buildFromCommunity(Context context, Community community, int indent)
|
||||
throws SQLException {
|
||||
// Add all the collections
|
||||
List<Collection> collections = community.getCollections();
|
||||
Iterator<Item> result = null;
|
||||
for (Collection collection : collections) {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
System.out.print(" ");
|
||||
@Override
|
||||
public MetadataExportScriptConfiguration getScriptConfiguration() {
|
||||
return new DSpace().getServiceManager().getServiceByName("metadata-export",
|
||||
MetadataExportScriptConfiguration.class);
|
||||
}
|
||||
|
||||
Iterator<Item> items = itemService.findByCollection(context, collection);
|
||||
result = addItemsToResult(result, items);
|
||||
@Override
|
||||
public void setup() throws ParseException {
|
||||
|
||||
}
|
||||
// Add all the sub-communities
|
||||
List<Community> communities = community.getSubcommunities();
|
||||
for (Community subCommunity : communities) {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
Iterator<Item> items = buildFromCommunity(context, subCommunity, indent + 1);
|
||||
result = addItemsToResult(result, items);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterator<Item> addItemsToResult(Iterator<Item> result, Iterator<Item> items) {
|
||||
if (result == null) {
|
||||
result = items;
|
||||
} else {
|
||||
result = Iterators.concat(result, items);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the export
|
||||
*
|
||||
* @return the exported CSV lines
|
||||
*/
|
||||
public DSpaceCSV export() {
|
||||
try {
|
||||
Context.Mode originalMode = context.getCurrentMode();
|
||||
context.setMode(Context.Mode.READ_ONLY);
|
||||
|
||||
// Process each item
|
||||
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
||||
while (toExport.hasNext()) {
|
||||
Item item = toExport.next();
|
||||
csv.addItem(item);
|
||||
context.uncacheEntity(item);
|
||||
}
|
||||
|
||||
context.setMode(originalMode);
|
||||
// Return the results
|
||||
return csv;
|
||||
} catch (Exception e) {
|
||||
// Something went wrong...
|
||||
System.err.println("Error exporting to CSV:");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the help message
|
||||
*
|
||||
* @param options The command line options the user gave
|
||||
* @param exitCode the system exit code to use
|
||||
*/
|
||||
private static void printHelp(Options options, int exitCode) {
|
||||
// print the help message
|
||||
HelpFormatter myhelp = new HelpFormatter();
|
||||
myhelp.printHelp("MetadataExport\n", options);
|
||||
System.out.println("\nfull export: metadataexport -f filename");
|
||||
System.out.println("partial export: metadataexport -i handle -f filename");
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* main method to run the metadata exporter
|
||||
*
|
||||
* @param argv the command line arguments given
|
||||
* @throws Exception if error occurs
|
||||
*/
|
||||
public static void main(String[] argv) throws Exception {
|
||||
// Create an options object and populate it
|
||||
CommandLineParser parser = new PosixParser();
|
||||
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("i", "id", true, "ID or handle of thing to export (item, collection, or community)");
|
||||
options.addOption("f", "file", true, "destination where you want file written");
|
||||
options.addOption("a", "all", false,
|
||||
"include all metadata fields that are not normally changed (e.g. provenance)");
|
||||
options.addOption("h", "help", false, "help");
|
||||
|
||||
CommandLine line = null;
|
||||
|
||||
try {
|
||||
line = parser.parse(options, argv);
|
||||
} catch (ParseException pe) {
|
||||
System.err.println("Error with commands.");
|
||||
printHelp(options, 1);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if (line.hasOption('h')) {
|
||||
printHelp(options, 0);
|
||||
if (commandLine.hasOption('h')) {
|
||||
help = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check a filename is given
|
||||
if (!line.hasOption('f')) {
|
||||
System.err.println("Required parameter -f missing!");
|
||||
printHelp(options, 1);
|
||||
if (!commandLine.hasOption('f')) {
|
||||
throw new ParseException("Required parameter -f missing!");
|
||||
}
|
||||
String filename = line.getOptionValue('f');
|
||||
filename = commandLine.getOptionValue('f');
|
||||
|
||||
// Create a context
|
||||
Context c = new Context(Context.Mode.READ_ONLY);
|
||||
c.turnOffAuthorisationSystem();
|
||||
exportAllMetadata = commandLine.hasOption('a');
|
||||
|
||||
// The things we'll export
|
||||
Iterator<Item> toExport = null;
|
||||
MetadataExport exporter = null;
|
||||
|
||||
// Export everything?
|
||||
boolean exportAll = line.hasOption('a');
|
||||
|
||||
ContentServiceFactory contentServiceFactory = ContentServiceFactory.getInstance();
|
||||
// Check we have an item OK
|
||||
ItemService itemService = contentServiceFactory.getItemService();
|
||||
if (!line.hasOption('i')) {
|
||||
System.out.println("Exporting whole repository WARNING: May take some time!");
|
||||
exporter = new MetadataExport(c, itemService.findAll(c), exportAll);
|
||||
} else {
|
||||
String handle = line.getOptionValue('i');
|
||||
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService().resolveToObject(c, handle);
|
||||
if (dso == null) {
|
||||
System.err.println("Item '" + handle + "' does not resolve to an item in your repository!");
|
||||
printHelp(options, 1);
|
||||
if (!commandLine.hasOption('i')) {
|
||||
exportAllItems = true;
|
||||
}
|
||||
|
||||
if (dso.getType() == Constants.ITEM) {
|
||||
System.out.println("Exporting item '" + dso.getName() + "' (" + handle + ")");
|
||||
List<Item> item = new ArrayList<>();
|
||||
item.add((Item) dso);
|
||||
exporter = new MetadataExport(c, item.iterator(), exportAll);
|
||||
} else if (dso.getType() == Constants.COLLECTION) {
|
||||
System.out.println("Exporting collection '" + dso.getName() + "' (" + handle + ")");
|
||||
Collection collection = (Collection) dso;
|
||||
toExport = itemService.findByCollection(c, collection);
|
||||
exporter = new MetadataExport(c, toExport, exportAll);
|
||||
} else if (dso.getType() == Constants.COMMUNITY) {
|
||||
System.out.println("Exporting community '" + dso.getName() + "' (" + handle + ")");
|
||||
exporter = new MetadataExport(c, (Community) dso, exportAll);
|
||||
} else {
|
||||
System.err.println("Error identifying '" + handle + "'");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the export
|
||||
DSpaceCSV csv = exporter.export();
|
||||
|
||||
// Save the files to the file
|
||||
csv.save(filename);
|
||||
|
||||
// Finish off and tidy up
|
||||
c.restoreAuthSystemState();
|
||||
c.complete();
|
||||
handle = commandLine.getOptionValue('i');
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 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.bulkedit;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The {@link ScriptConfiguration} for the {@link MetadataExport} script
|
||||
*/
|
||||
public class MetadataExportScriptConfiguration<T extends MetadataExport> extends ScriptConfiguration<T> {
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
|
||||
private Class<T> dspaceRunnableClass;
|
||||
|
||||
@Override
|
||||
public Class<T> getDspaceRunnableClass() {
|
||||
return dspaceRunnableClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic setter for the dspaceRunnableClass
|
||||
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this MetadataExportScriptConfiguration
|
||||
*/
|
||||
@Override
|
||||
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToExecute(Context context) {
|
||||
try {
|
||||
return authorizeService.isAdmin(context);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
if (options == null) {
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("i", "id", true, "ID or handle of thing to export (item, collection, or community)");
|
||||
options.getOption("i").setType(String.class);
|
||||
options.addOption("f", "file", true, "destination where you want file written");
|
||||
options.getOption("f").setType(OutputStream.class);
|
||||
options.getOption("f").setRequired(true);
|
||||
options.addOption("a", "all", false,
|
||||
"include all metadata fields that are not normally changed (e.g. provenance)");
|
||||
options.getOption("a").setType(boolean.class);
|
||||
options.addOption("h", "help", false, "help");
|
||||
options.getOption("h").setType(boolean.class);
|
||||
|
||||
|
||||
super.options = options;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -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.app.bulkedit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
|
||||
/**
|
||||
* CLI variant for the {@link MetadataImport} class
|
||||
* This has been made so that we can specify the behaviour of the determineChanges method to be specific for the CLI
|
||||
*/
|
||||
public class MetadataImportCLI extends MetadataImport {
|
||||
|
||||
@Override
|
||||
protected boolean determineChange(DSpaceRunnableHandler handler) throws IOException {
|
||||
handler.logInfo("Do you want to make these changes? [y/n] ");
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
|
||||
String yn = bufferedReader.readLine();
|
||||
if ("y".equalsIgnoreCase(yn)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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.bulkedit;
|
||||
|
||||
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||
|
||||
/**
|
||||
* The {@link ScriptConfiguration} for the {@link org.dspace.app.bulkedit.MetadataImportCLI} CLI script
|
||||
*/
|
||||
public class MetadataImportCliScriptConfiguration extends MetadataImportScriptConfiguration<MetadataImportCLI> {
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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.bulkedit;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The {@link ScriptConfiguration} for the {@link MetadataImport} script
|
||||
*/
|
||||
public class MetadataImportScriptConfiguration<T extends MetadataImport> extends ScriptConfiguration<T> {
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
|
||||
private Class<T> dspaceRunnableClass;
|
||||
|
||||
@Override
|
||||
public Class<T> getDspaceRunnableClass() {
|
||||
return dspaceRunnableClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic setter for the dspaceRunnableClass
|
||||
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this MetadataImportScriptConfiguration
|
||||
*/
|
||||
@Override
|
||||
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToExecute(Context context) {
|
||||
try {
|
||||
return authorizeService.isAdmin(context);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
if (options == null) {
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("f", "file", true, "source file");
|
||||
options.getOption("f").setType(InputStream.class);
|
||||
options.getOption("f").setRequired(true);
|
||||
options.addOption("e", "email", true, "email address or user id of user (required if adding new items)");
|
||||
options.getOption("e").setType(String.class);
|
||||
options.getOption("e").setRequired(true);
|
||||
options.addOption("s", "silent", false,
|
||||
"silent operation - doesn't request confirmation of changes USE WITH CAUTION");
|
||||
options.getOption("s").setType(boolean.class);
|
||||
options.addOption("w", "workflow", false, "workflow - when adding new items, use collection workflow");
|
||||
options.getOption("w").setType(boolean.class);
|
||||
options.addOption("n", "notify", false,
|
||||
"notify - when adding new items using a workflow, send notification emails");
|
||||
options.getOption("n").setType(boolean.class);
|
||||
options.addOption("v", "validate-only", false,
|
||||
"validate - just validate the csv, don't run the import");
|
||||
options.getOption("v").setType(boolean.class);
|
||||
options.addOption("t", "template", false,
|
||||
"template - when adding new items, use the collection template (if it exists)");
|
||||
options.getOption("t").setType(boolean.class);
|
||||
options.addOption("h", "help", false, "help");
|
||||
options.getOption("h").setType(boolean.class);
|
||||
|
||||
super.options = options;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
@@ -272,9 +272,8 @@ public class Harvest {
|
||||
targetCollection = (Collection) dso;
|
||||
}
|
||||
} else {
|
||||
// not a handle, try and treat it as an integer collection database ID
|
||||
System.out.println("Looking up by id: " + collectionID + ", parsed as '" + Integer
|
||||
.parseInt(collectionID) + "', " + "in context: " + context);
|
||||
// not a handle, try and treat it as an collection database UUID
|
||||
System.out.println("Looking up by UUID: " + collectionID + ", " + "in context: " + context);
|
||||
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
||||
}
|
||||
}
|
||||
@@ -460,7 +459,7 @@ public class Harvest {
|
||||
List<String> errors;
|
||||
|
||||
System.out.print("Testing basic PMH access: ");
|
||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
||||
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||
(null != metadataFormat) ? metadataFormat : "dc", false);
|
||||
if (errors.isEmpty()) {
|
||||
System.out.println("OK");
|
||||
@@ -471,7 +470,7 @@ public class Harvest {
|
||||
}
|
||||
|
||||
System.out.print("Testing ORE support: ");
|
||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
||||
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||
(null != metadataFormat) ? metadataFormat : "dc", true);
|
||||
if (errors.isEmpty()) {
|
||||
System.out.println("OK");
|
||||
|
@@ -42,7 +42,7 @@ import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
@@ -214,7 +214,7 @@ public class ItemExportServiceImpl implements ItemExportService {
|
||||
protected void writeMetadata(Context c, String schema, Item i,
|
||||
File destDir, boolean migrate) throws Exception {
|
||||
String filename;
|
||||
if (schema.equals(MetadataSchema.DC_SCHEMA)) {
|
||||
if (schema.equals(MetadataSchemaEnum.DC.getName())) {
|
||||
filename = "dublin_core.xml";
|
||||
} else {
|
||||
filename = "metadata_" + schema + ".xml";
|
||||
@@ -929,7 +929,7 @@ public class ItemExportServiceImpl implements ItemExportService {
|
||||
Locale supportedLocale = I18nUtil.getEPersonLocale(eperson);
|
||||
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "export_success"));
|
||||
email.addRecipient(eperson.getEmail());
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.url") + "/exportdownload/" + fileName);
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.ui.url") + "/exportdownload/" + fileName);
|
||||
email.addArgument(ConfigurationManager.getProperty("org.dspace.app.itemexport.life.span.hours"));
|
||||
|
||||
email.send();
|
||||
@@ -947,7 +947,7 @@ public class ItemExportServiceImpl implements ItemExportService {
|
||||
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "export_error"));
|
||||
email.addRecipient(eperson.getEmail());
|
||||
email.addArgument(error);
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.url") + "/feedback");
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.ui.url") + "/feedback");
|
||||
|
||||
email.send();
|
||||
} catch (Exception e) {
|
||||
|
@@ -74,6 +74,7 @@ import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.service.BitstreamFormatService;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
@@ -677,7 +678,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem(
|
||||
"schema");
|
||||
if (schemaAttr == null) {
|
||||
schema = MetadataSchema.DC_SCHEMA;
|
||||
schema = MetadataSchemaEnum.DC.getName();
|
||||
} else {
|
||||
schema = schemaAttr.getNodeValue();
|
||||
}
|
||||
@@ -1518,6 +1519,12 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
log.error("Unable to create directory: " + dir.getAbsolutePath());
|
||||
}
|
||||
// Verify that the directory the entry is using is a subpath of zipDir (and not somewhere else!)
|
||||
if (!dir.toPath().normalize().startsWith(zipDir)) {
|
||||
throw new IOException("Bad zip entry: '" + entry.getName()
|
||||
+ "' in file '" + zipfile.getAbsolutePath() + "'!"
|
||||
+ " Cannot process this file.");
|
||||
}
|
||||
|
||||
//Entries could have too many directories, and we need to adjust the sourcedir
|
||||
// file1.zip (SimpleArchiveFormat / item1 / contents|dublin_core|...
|
||||
@@ -1538,9 +1545,16 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
}
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
File outFile = new File(zipDir + entry.getName());
|
||||
// Verify that this file will be created in our zipDir (and not somewhere else!)
|
||||
if (!outFile.toPath().normalize().startsWith(zipDir)) {
|
||||
throw new IOException("Bad zip entry: '" + entry.getName()
|
||||
+ "' in file '" + zipfile.getAbsolutePath() + "'!"
|
||||
+ " Cannot process this file.");
|
||||
}
|
||||
InputStream in = zf.getInputStream(entry);
|
||||
BufferedOutputStream out = new BufferedOutputStream(
|
||||
new FileOutputStream(zipDir + entry.getName()));
|
||||
new FileOutputStream(outFile));
|
||||
while ((len = in.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
@@ -1796,7 +1810,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "bte_batch_import_error"));
|
||||
email.addRecipient(eperson.getEmail());
|
||||
email.addArgument(error);
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.url") + "/feedback");
|
||||
email.addArgument(ConfigurationManager.getProperty("dspace.ui.url") + "/feedback");
|
||||
|
||||
email.send();
|
||||
} catch (Exception e) {
|
||||
|
@@ -34,6 +34,7 @@ import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.ItemService;
|
||||
@@ -189,7 +190,7 @@ public class MetadataUtilities {
|
||||
NodeList metadata = XPathAPI.selectNodeList(document, "/dublin_core");
|
||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem("schema");
|
||||
if (schemaAttr == null) {
|
||||
schema = MetadataSchema.DC_SCHEMA;
|
||||
schema = MetadataSchemaEnum.DC.getName();
|
||||
} else {
|
||||
schema = schemaAttr.getNodeValue();
|
||||
}
|
||||
|
@@ -13,6 +13,14 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||
import org.dspace.scripts.service.ScriptService;
|
||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||
import org.dspace.services.RequestService;
|
||||
@@ -27,6 +35,9 @@ import org.jdom.input.SAXBuilder;
|
||||
* @author Mark Diggory
|
||||
*/
|
||||
public class ScriptLauncher {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ScriptLauncher.class);
|
||||
|
||||
/**
|
||||
* The service manager kernel
|
||||
*/
|
||||
@@ -35,7 +46,8 @@ public class ScriptLauncher {
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
private ScriptLauncher() { }
|
||||
private ScriptLauncher() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the DSpace script launcher
|
||||
@@ -45,7 +57,7 @@ public class ScriptLauncher {
|
||||
* @throws FileNotFoundException if file doesn't exist
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
throws FileNotFoundException, IOException {
|
||||
throws FileNotFoundException, IOException, IllegalAccessException, InstantiationException {
|
||||
// Initialise the service manager kernel
|
||||
try {
|
||||
kernelImpl = DSpaceKernelInit.getKernel(null);
|
||||
@@ -76,8 +88,9 @@ public class ScriptLauncher {
|
||||
}
|
||||
|
||||
// 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
|
||||
if (kernelImpl != null) {
|
||||
@@ -86,6 +99,55 @@ public class ScriptLauncher {
|
||||
}
|
||||
|
||||
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) throws InstantiationException, IllegalAccessException {
|
||||
int status;
|
||||
ScriptService scriptService = ScriptServiceFactory.getInstance().getScriptService();
|
||||
ScriptConfiguration scriptConfiguration = scriptService.getScriptConfiguration(args[0]);
|
||||
DSpaceRunnable script = null;
|
||||
if (scriptConfiguration != null) {
|
||||
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
|
||||
}
|
||||
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, null);
|
||||
script.run();
|
||||
return 0;
|
||||
} catch (ParseException e) {
|
||||
script.printHelp();
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected static int runOneCommand(Document commandConfigs, String[] args) {
|
||||
@@ -98,7 +160,7 @@ public class ScriptLauncher {
|
||||
* @param commandConfigs Document
|
||||
* @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];
|
||||
Element root = commandConfigs.getRootElement();
|
||||
List<Element> commands = root.getChildren("command");
|
||||
|
@@ -11,7 +11,9 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.InputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.dspace.content.Item;
|
||||
|
||||
@@ -26,6 +28,8 @@ import org.dspace.content.Item;
|
||||
* @author Jason Sherman jsherman@usao.edu
|
||||
*/
|
||||
public class PDFBoxThumbnail extends MediaFilter implements SelfRegisterInputFormats {
|
||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(PDFBoxThumbnail.class);
|
||||
|
||||
@Override
|
||||
public String getFilteredName(String oldFilename) {
|
||||
return oldFilename + ".jpg";
|
||||
@@ -65,12 +69,19 @@ public class PDFBoxThumbnail extends MediaFilter implements SelfRegisterInputFor
|
||||
@Override
|
||||
public InputStream getDestinationStream(Item currentItem, InputStream source, boolean verbose)
|
||||
throws Exception {
|
||||
PDDocument doc = PDDocument.load(source);
|
||||
PDFRenderer renderer = new PDFRenderer(doc);
|
||||
BufferedImage buf = renderer.renderImage(0);
|
||||
// ImageIO.write(buf, "PNG", new File("custom-render.png"));
|
||||
doc.close();
|
||||
BufferedImage buf;
|
||||
|
||||
// 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();
|
||||
return jpegFilter.getThumb(currentItem, buf, verbose);
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ import java.io.Writer;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
@@ -95,6 +96,10 @@ public class PDFFilter extends MediaFilter {
|
||||
try {
|
||||
pdfDoc = PDDocument.load(source);
|
||||
pts.writeText(pdfDoc, writer);
|
||||
} catch (InvalidPasswordException ex) {
|
||||
log.error("PDF is encrypted. Cannot extract text (item: {})",
|
||||
() -> currentItem.getHandle());
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (pdfDoc != null) {
|
||||
|
@@ -78,7 +78,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
||||
private Date request_date = null;
|
||||
|
||||
@Column(name = "accept_request")
|
||||
private Boolean accept_request = null;
|
||||
private boolean accept_request;
|
||||
|
||||
/**
|
||||
* Protected constructor, create object using:
|
||||
@@ -88,6 +88,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
||||
protected RequestItem() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getID() {
|
||||
return requestitem_id;
|
||||
}
|
||||
|
@@ -15,6 +15,9 @@ import java.util.List;
|
||||
* @author Andrea Bollini
|
||||
*/
|
||||
public class SHERPAPublisher {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String alias;
|
||||
@@ -49,7 +52,7 @@ public class SHERPAPublisher {
|
||||
|
||||
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 postarchiving, List<String> postrestriction,
|
||||
String pubarchiving, List<String> pubrestriction,
|
||||
@@ -57,6 +60,8 @@ public class SHERPAPublisher {
|
||||
String paidaccessname, String paidaccessnotes,
|
||||
List<String[]> copyright, String romeocolour, String datedded,
|
||||
String dateupdated) {
|
||||
this.id = id;
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.alias = alias;
|
||||
@@ -160,4 +165,11 @@ public class SHERPAPublisher {
|
||||
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 org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.util.XMLUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -24,7 +25,9 @@ import org.w3c.dom.Element;
|
||||
* @author Andrea Bollini
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -45,6 +48,9 @@ public class SHERPAResponse {
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
// disallow DTD parsing to ensure no XXE attacks can occur.
|
||||
// See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
|
||||
DocumentBuilder db = factory.newDocumentBuilder();
|
||||
Document inDoc = db.parse(xmlData);
|
||||
@@ -57,12 +63,13 @@ public class SHERPAResponse {
|
||||
Element publishersElement = XMLUtils.getSingleElement(xmlRoot,
|
||||
"publishers");
|
||||
|
||||
message = XMLUtils.getElementValue(headersElement, "message");
|
||||
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
error = true;
|
||||
return;
|
||||
String numhitsString = XMLUtils.getElementValue(headersElement, "numhits");
|
||||
if (StringUtils.isNotBlank(numhitsString)) {
|
||||
numHits = Integer.parseInt(numhitsString);
|
||||
} else {
|
||||
numHits = 0;
|
||||
}
|
||||
message = XMLUtils.getElementValue(headersElement, "message");
|
||||
|
||||
license = XMLUtils.getElementValue(headersElement, "license");
|
||||
licenseURL = XMLUtils.getElementValue(headersElement, "licenseurl");
|
||||
@@ -112,9 +119,8 @@ public class SHERPAResponse {
|
||||
|
||||
Element copyrightlinksElement = XMLUtils.getSingleElement(
|
||||
publisherElement, "copyrightlinks");
|
||||
|
||||
publishers
|
||||
.add(new SHERPAPublisher(XMLUtils.getElementValue(
|
||||
.add(new SHERPAPublisher(publisherElement.getAttribute("id"), XMLUtils.getElementValue(
|
||||
publisherElement, "name"),
|
||||
XMLUtils.getElementValue(publisherElement,
|
||||
"alias"), XMLUtils.getElementValue(
|
||||
@@ -162,17 +168,12 @@ public class SHERPAResponse {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error = true;
|
||||
log.error("Error parsing SHERPA API Response", e);
|
||||
}
|
||||
}
|
||||
|
||||
public SHERPAResponse(String message) {
|
||||
this.message = message;
|
||||
this.error = true;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
@@ -198,4 +199,8 @@ public class SHERPAResponse {
|
||||
public List<SHERPAPublisher> getPublishers() {
|
||||
return publishers;
|
||||
}
|
||||
|
||||
public int getNumHits() {
|
||||
return numHits;
|
||||
}
|
||||
}
|
||||
|
@@ -152,11 +152,11 @@ public class GenerateSitemaps {
|
||||
*/
|
||||
public static void generateSitemaps(boolean makeHTMLMap,
|
||||
boolean makeSitemapOrg) throws SQLException, IOException {
|
||||
String sitemapStem = configurationService.getProperty("dspace.url")
|
||||
String sitemapStem = configurationService.getProperty("dspace.ui.url")
|
||||
+ "/sitemap";
|
||||
String htmlMapStem = configurationService.getProperty("dspace.url")
|
||||
String htmlMapStem = configurationService.getProperty("dspace.ui.url")
|
||||
+ "/htmlmap";
|
||||
String handleURLStem = configurationService.getProperty("dspace.url")
|
||||
String handleURLStem = configurationService.getProperty("dspace.ui.url")
|
||||
+ "/handle/";
|
||||
|
||||
File outputDir = new File(configurationService.getProperty("sitemap.dir"));
|
||||
@@ -293,7 +293,7 @@ public class GenerateSitemaps {
|
||||
.getProperty("http.proxy.port"));
|
||||
}
|
||||
|
||||
String sitemapURL = configurationService.getProperty("dspace.url")
|
||||
String sitemapURL = configurationService.getProperty("dspace.ui.url")
|
||||
+ "/sitemap";
|
||||
|
||||
URL url = new URL(engineURL + URLEncoder.encode(sitemapURL, "UTF-8"));
|
||||
|
@@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.SearchUtils;
|
||||
@@ -581,9 +582,9 @@ public class LogAnalyser {
|
||||
}
|
||||
|
||||
// now do the host name and url lookup
|
||||
hostName = ConfigurationManager.getProperty("dspace.hostname").trim();
|
||||
hostName = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
|
||||
name = ConfigurationManager.getProperty("dspace.name").trim();
|
||||
url = ConfigurationManager.getProperty("dspace.url").trim();
|
||||
url = ConfigurationManager.getProperty("dspace.ui.url").trim();
|
||||
if ((url != null) && (!url.endsWith("/"))) {
|
||||
url = url + "/";
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.ItemService;
|
||||
@@ -763,9 +763,10 @@ public class ReportGenerator {
|
||||
// build the referece
|
||||
// FIXME: here we have blurred the line between content and presentation
|
||||
// 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
|
||||
.getMetadata(item, MetadataSchema.DC_SCHEMA, "contributor", "author", Item.ANY);
|
||||
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "contributor", "author", Item.ANY);
|
||||
|
||||
StringBuffer authors = new StringBuffer();
|
||||
if (author.size() > 0) {
|
||||
|
@@ -15,7 +15,7 @@ package org.dspace.app.statistics;
|
||||
*
|
||||
* @author Richard Jones
|
||||
*/
|
||||
public class Stat implements Comparable {
|
||||
public class Stat implements Comparable<Stat> {
|
||||
// FIXME: this class is functional but a bit messy, and should be neatened
|
||||
// up and completed
|
||||
|
||||
@@ -132,17 +132,17 @@ public class Stat implements Comparable {
|
||||
|
||||
|
||||
/**
|
||||
* compare the current object to the given object returning -1 if o is less
|
||||
* than the current object, 0 if they are the same, and +1 if o is greater
|
||||
* than the current object.
|
||||
* Compare the current Stat to the given Stat returning -1 if o is less
|
||||
* than the current Stat, 0 if they are the same, and +1 if o is greater
|
||||
* than the current Stat.
|
||||
*
|
||||
* @param o the object to compare to the current one
|
||||
* @param stat the Stat object to compare to the current one
|
||||
* @return +1, 0, -1 if o is less than, equal to, or greater than the
|
||||
* current object value.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
int objectValue = ((Stat) o).getValue();
|
||||
public int compareTo(Stat stat) {
|
||||
int objectValue = stat.getValue();
|
||||
|
||||
if (objectValue < this.getValue()) {
|
||||
return -1;
|
||||
|
@@ -50,16 +50,16 @@ abstract public class AbstractDSpaceWebapp
|
||||
/**
|
||||
* Construct a particular kind of DSpace application.
|
||||
*
|
||||
* @param kind what kind of application is this? (XMLUI, JSPUI, etc.)
|
||||
* @param kind what kind of application is this?
|
||||
*/
|
||||
public AbstractDSpaceWebapp(String kind) {
|
||||
this.kind = kind;
|
||||
|
||||
started = new Date();
|
||||
|
||||
url = ConfigurationManager.getProperty("dspace.url");
|
||||
url = ConfigurationManager.getProperty("dspace.ui.url");
|
||||
if (null == url) {
|
||||
throw new IllegalStateException("dspace.url is undefined");
|
||||
throw new IllegalStateException("dspace.ui.url is undefined");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,10 @@ package org.dspace.app.util;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authenticate.factory.AuthenticateServiceFactory;
|
||||
import org.dspace.authorize.AuthorizeConfiguration;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
@@ -19,12 +22,22 @@ import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.storedcomponents.CollectionRole;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService;
|
||||
|
||||
/**
|
||||
* This class is an addition to the AuthorizeManager that perform authorization
|
||||
@@ -34,12 +47,7 @@ import org.dspace.core.Context;
|
||||
*/
|
||||
public class AuthorizeUtil {
|
||||
|
||||
private static final AuthorizeService authorizeService =
|
||||
AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
private static final ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
private static final CollectionService collectionService =
|
||||
ContentServiceFactory.getInstance().getCollectionService();
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(AuthorizeUtil.class);
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
@@ -95,8 +103,9 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageItemPolicy(Context context, Item item)
|
||||
throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canItemAdminManagePolicies()) {
|
||||
authorizeService.authorizeAction(context, item, Constants.ADMIN);
|
||||
AuthorizeServiceFactory.getInstance().getAuthorizeService().authorizeAction(context, item, Constants.ADMIN);
|
||||
} else if (AuthorizeConfiguration.canCollectionAdminManageItemPolicies()) {
|
||||
authorizeService.authorizeAction(context, item
|
||||
.getOwningCollection(), Constants.ADMIN);
|
||||
@@ -124,6 +133,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageCollectionPolicy(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()) {
|
||||
authorizeService.authorizeAction(context, collection,
|
||||
Constants.ADMIN);
|
||||
@@ -151,6 +161,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageCommunityPolicy(Context context,
|
||||
Community community) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCommunityAdminManagePolicies()) {
|
||||
authorizeService.authorizeAction(context, community,
|
||||
Constants.ADMIN);
|
||||
@@ -171,6 +182,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void requireAdminRole(Context context)
|
||||
throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (!authorizeService.isAdmin(context)) {
|
||||
throw new AuthorizeException(
|
||||
"Only system admin are allowed to perform this action");
|
||||
@@ -191,9 +203,12 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageCCLicense(Context context, Item item)
|
||||
throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
try {
|
||||
authorizeService.authorizeAction(context, item, Constants.ADD);
|
||||
authorizeService.authorizeAction(context, item, Constants.REMOVE);
|
||||
authorizeService.authorizeAction(context, item, Constants.ADD, false);
|
||||
authorizeService.authorizeAction(context, item, Constants.REMOVE, false);
|
||||
} catch (AuthorizeException authex) {
|
||||
if (AuthorizeConfiguration.canItemAdminManageCCLicense()) {
|
||||
authorizeService
|
||||
@@ -202,8 +217,10 @@ public class AuthorizeUtil {
|
||||
authorizeService.authorizeAction(context, itemService
|
||||
.getParentObject(context, item), Constants.ADMIN);
|
||||
} else if (AuthorizeConfiguration.canCommunityAdminManageCCLicense()) {
|
||||
authorizeService.authorizeAction(context, itemService
|
||||
.getParentObject(context, item), Constants.ADMIN);
|
||||
Collection collection = (Collection) itemService
|
||||
.getParentObject(context, item);
|
||||
authorizeService.authorizeAction(context, collectionService.getParentObject(context, collection),
|
||||
Constants.ADMIN);
|
||||
} else {
|
||||
requireAdminRole(context);
|
||||
}
|
||||
@@ -224,6 +241,8 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageTemplateItem(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
boolean isAuthorized = collectionService.canEditBoolean(context, collection, false);
|
||||
|
||||
if (!isAuthorized
|
||||
@@ -258,6 +277,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageSubmittersGroup(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCollectionAdminManageSubmitters()) {
|
||||
authorizeService.authorizeAction(context, collection,
|
||||
Constants.ADMIN);
|
||||
@@ -285,6 +305,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageWorkflowsGroup(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCollectionAdminManageWorkflows()) {
|
||||
authorizeService.authorizeAction(context, collection,
|
||||
Constants.ADMIN);
|
||||
@@ -313,6 +334,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageAdminGroup(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) {
|
||||
authorizeService.authorizeAction(context, collection,
|
||||
Constants.ADMIN);
|
||||
@@ -341,6 +363,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeRemoveAdminGroup(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
List<Community> parentCommunities = collection.getCommunities();
|
||||
if (AuthorizeConfiguration
|
||||
.canCommunityAdminManageCollectionAdminGroup()
|
||||
@@ -368,6 +391,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeManageAdminGroup(Context context,
|
||||
Community community) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) {
|
||||
authorizeService.authorizeAction(context, community,
|
||||
Constants.ADMIN);
|
||||
@@ -392,6 +416,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeRemoveAdminGroup(Context context,
|
||||
Community community) throws SQLException, AuthorizeException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
List<Community> parentCommunities = community.getParentCommunities();
|
||||
Community parentCommunity = null;
|
||||
if (0 < parentCommunities.size()) {
|
||||
@@ -458,6 +483,7 @@ public class AuthorizeUtil {
|
||||
public static void authorizeWithdrawItem(Context context, Item item)
|
||||
throws SQLException, AuthorizeException {
|
||||
boolean authorized = false;
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
if (AuthorizeConfiguration.canCollectionAdminPerformItemWithdrawn()) {
|
||||
authorized = authorizeService.authorizeActionBoolean(context, item
|
||||
.getOwningCollection(), Constants.ADMIN);
|
||||
@@ -492,6 +518,7 @@ public class AuthorizeUtil {
|
||||
*/
|
||||
public static void authorizeReinstateItem(Context context, Item item)
|
||||
throws SQLException, AuthorizeException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
List<Collection> colls = item.getCollections();
|
||||
|
||||
for (Collection coll : colls) {
|
||||
@@ -512,4 +539,154 @@ public class AuthorizeUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will check whether the current user is authorized to manage the default read group
|
||||
* @param context The relevant DSpace context
|
||||
* @param collection The collection for which this will be checked
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public static void authorizeManageDefaultReadGroup(Context context,
|
||||
Collection collection) throws AuthorizeException, SQLException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
authorizeService.authorizeAction(context, collection, Constants.ADMIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks whether the current user has sufficient rights to modify the group.
|
||||
* Depending on the kind of group and due to delegated administration, separate checks need to be done to verify
|
||||
* whether the user is allowed to modify the group.
|
||||
*
|
||||
* @param context the context of which the user will be checked
|
||||
* @param group the group to be checked
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
public static void authorizeManageGroup(Context context, Group group) throws SQLException, AuthorizeException {
|
||||
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
|
||||
CollectionRoleService collectionRoleService = XmlWorkflowServiceFactory.getInstance()
|
||||
.getCollectionRoleService();
|
||||
if (authorizeService.isAdmin(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DSpaceObject parentObject = groupService.getParentObject(context, group);
|
||||
if (parentObject == null) {
|
||||
throw new AuthorizeException("not authorized to manage this group");
|
||||
}
|
||||
if (parentObject.getType() == Constants.COLLECTION) {
|
||||
Collection collection = (Collection) parentObject;
|
||||
|
||||
if (group.equals(collection.getSubmitters())) {
|
||||
authorizeManageSubmittersGroup(context, collection);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
List<CollectionRole> collectionRoles = collectionRoleService.findByCollection(context, collection);
|
||||
for (CollectionRole role : collectionRoles) {
|
||||
if (group.equals(role.getGroup())) {
|
||||
authorizeManageWorkflowsGroup(context, collection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (group.equals(collection.getAdministrators())) {
|
||||
authorizeManageAdminGroup(context, collection);
|
||||
return;
|
||||
}
|
||||
// if we reach this point, it means that the group is related
|
||||
// to a collection but as it is not the submitters, nor the administrators,
|
||||
// nor a workflow groups it must be a default item/bitstream groups
|
||||
authorizeManageDefaultReadGroup(context, collection);
|
||||
return;
|
||||
}
|
||||
if (parentObject.getType() == Constants.COMMUNITY) {
|
||||
Community community = (Community) parentObject;
|
||||
authorizeManageAdminGroup(context, community);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new AuthorizeException("not authorized to manage this group");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a boolean indicating whether the current user is allowed to register a new
|
||||
* account or not
|
||||
* @param context The relevant DSpace context
|
||||
* @param request The current request
|
||||
* @return A boolean indicating whether the current user can register a new account or not
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public static boolean authorizeNewAccountRegistration(Context context, HttpServletRequest request)
|
||||
throws SQLException {
|
||||
if (DSpaceServicesFactory.getInstance().getConfigurationService()
|
||||
.getBooleanProperty("user.registration", true)) {
|
||||
// This allowSetPassword is currently the only mthod that would return true only when it's
|
||||
// actually expected to be returning true.
|
||||
// For example the LDAP canSelfRegister will return true due to auto-register, while that
|
||||
// does not imply a new user can register explicitly
|
||||
return AuthenticateServiceFactory.getInstance().getAuthenticationService()
|
||||
.allowSetPassword(context, request, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a boolean indicating whether it's allowed to update the password for the EPerson
|
||||
* with the given email and canLogin property
|
||||
* @param context The relevant DSpace context
|
||||
* @param email The email to be checked
|
||||
* @return A boolean indicating if the password can be updated or not
|
||||
*/
|
||||
public static boolean authorizeUpdatePassword(Context context, String email) {
|
||||
try {
|
||||
EPerson eperson = EPersonServiceFactory.getInstance().getEPersonService().findByEmail(context, email);
|
||||
if (eperson != null && eperson.canLogIn()) {
|
||||
HttpServletRequest request = new DSpace().getRequestService().getCurrentRequest()
|
||||
.getHttpServletRequest();
|
||||
return AuthenticateServiceFactory.getInstance().getAuthenticationService()
|
||||
.allowSetPassword(context, request, null);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Something went wrong trying to retrieve EPerson for email: " + email, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if the community Admin can manage accounts
|
||||
*
|
||||
* @return true if is able
|
||||
*/
|
||||
public static boolean canCommunityAdminManageAccounts() {
|
||||
boolean isAble = false;
|
||||
if (AuthorizeConfiguration.canCommunityAdminManagePolicies()
|
||||
|| AuthorizeConfiguration.canCommunityAdminManageAdminGroup()
|
||||
|| AuthorizeConfiguration.canCommunityAdminManageCollectionPolicies()
|
||||
|| AuthorizeConfiguration.canCommunityAdminManageCollectionSubmitters()
|
||||
|| AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()
|
||||
|| AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup()) {
|
||||
isAble = true;
|
||||
}
|
||||
return isAble;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if the Collection Admin can manage accounts
|
||||
*
|
||||
* @return true if is able
|
||||
*/
|
||||
public static boolean canCollectionAdminManageAccounts() {
|
||||
boolean isAble = false;
|
||||
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()
|
||||
|| AuthorizeConfiguration.canCollectionAdminManageSubmitters()
|
||||
|| AuthorizeConfiguration.canCollectionAdminManageWorkflows()
|
||||
|| AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) {
|
||||
isAble = true;
|
||||
}
|
||||
return isAble;
|
||||
}
|
||||
}
|
||||
|
@@ -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 org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.core.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -89,6 +89,11 @@ public class DCInput {
|
||||
*/
|
||||
private boolean repeatable = false;
|
||||
|
||||
/**
|
||||
* should name-variants be used?
|
||||
*/
|
||||
private boolean nameVariants = false;
|
||||
|
||||
/**
|
||||
* 'hint' text to display
|
||||
*/
|
||||
@@ -134,6 +139,12 @@ public class DCInput {
|
||||
*/
|
||||
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
|
||||
* view during workflow processing.
|
||||
@@ -160,7 +171,7 @@ public class DCInput {
|
||||
// Default the schema to dublin core
|
||||
dcSchema = fieldMap.get("dc-schema");
|
||||
if (dcSchema == null) {
|
||||
dcSchema = MetadataSchema.DC_SCHEMA;
|
||||
dcSchema = MetadataSchemaEnum.DC.getName();
|
||||
}
|
||||
|
||||
//check if the input have a language tag
|
||||
@@ -177,6 +188,9 @@ public class DCInput {
|
||||
String repStr = fieldMap.get("repeatable");
|
||||
repeatable = "true".equalsIgnoreCase(repStr)
|
||||
|| "yes".equalsIgnoreCase(repStr);
|
||||
String nameVariantsString = fieldMap.get("name-variants");
|
||||
nameVariants = (StringUtils.isNotBlank(nameVariantsString)) ?
|
||||
nameVariantsString.equalsIgnoreCase("true") : false;
|
||||
label = fieldMap.get("label");
|
||||
inputType = fieldMap.get("input-type");
|
||||
// these types are list-controlled
|
||||
@@ -206,6 +220,11 @@ public class DCInput {
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nameVariants flag for this row
|
||||
*
|
||||
* @return the nameVariants flag
|
||||
*/
|
||||
public boolean areNameVariantsAllowed() {
|
||||
return nameVariants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input type for this row
|
||||
*
|
||||
@@ -481,6 +509,18 @@ public class DCInput {
|
||||
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() {
|
||||
if ("qualdrop_value".equals(getInputType())) {
|
||||
return true;
|
||||
@@ -505,4 +545,22 @@ public class DCInput {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.util;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dspace.core.Utils;
|
||||
/**
|
||||
* Class representing all DC inputs required for a submission, organized into pages
|
||||
*
|
||||
@@ -107,12 +108,24 @@ public class DCInputSet {
|
||||
for (int i = 0; i < inputs.length; i++) {
|
||||
for (int j = 0; j < inputs[i].length; j++) {
|
||||
DCInput field = inputs[i][j];
|
||||
// If this is a "qualdrop_value" field, then the full field name is the field + dropdown qualifier
|
||||
if (field.getInputType().equals("qualdrop_value")) {
|
||||
List<String> pairs = field.getPairs();
|
||||
for (int k = 0; k < pairs.size(); k += 2) {
|
||||
String qualifier = pairs.get(k + 1);
|
||||
String fullName = Utils.standardize(field.getSchema(), field.getElement(), qualifier, ".");
|
||||
if (fullName.equals(fieldName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String fullName = field.getFieldName();
|
||||
if (fullName.equals(fieldName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import javax.xml.parsers.FactoryConfigurationError;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.w3c.dom.Document;
|
||||
@@ -366,11 +366,15 @@ public class DCInputsReader {
|
||||
metadataField += "." + qualifier;
|
||||
}
|
||||
}
|
||||
|
||||
// we omit the duplicate validation, allowing multiple
|
||||
// fields definition for
|
||||
// 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
|
||||
if (fields.size() < 1) {
|
||||
@@ -396,19 +400,7 @@ public class DCInputsReader {
|
||||
String value = getValue(nd);
|
||||
field.put(tagName, value);
|
||||
if (tagName.equals("input-type")) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
handleInputTypeTagName(formName, field, nd, value);
|
||||
} else if (tagName.equals("vocabulary")) {
|
||||
String closedVocabularyString = getAttribute(nd, "closed");
|
||||
field.put("closedVocabulary", closedVocabularyString);
|
||||
@@ -424,17 +416,30 @@ public class DCInputsReader {
|
||||
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;
|
||||
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";
|
||||
}
|
||||
if (field.get("label") == null) {
|
||||
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";
|
||||
}
|
||||
if (missing != null) {
|
||||
@@ -442,7 +447,7 @@ public class DCInputsReader {
|
||||
throw new SAXException(msg);
|
||||
}
|
||||
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");
|
||||
if ((rpt == null) ||
|
||||
((!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
|
||||
* 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 qual = field.get("dc-qualifier");
|
||||
if ((schema == null) || (schema.equals(""))) {
|
||||
schema = MetadataSchema.DC_SCHEMA;
|
||||
schema = MetadataSchemaEnum.DC.getName();
|
||||
}
|
||||
String schemaTest;
|
||||
|
||||
@@ -474,7 +496,7 @@ public class DCInputsReader {
|
||||
Map<String, String> fld = pg.get(j);
|
||||
if ((fld.get("dc-schema") == null) ||
|
||||
((fld.get("dc-schema")).equals(""))) {
|
||||
schemaTest = MetadataSchema.DC_SCHEMA;
|
||||
schemaTest = MetadataSchemaEnum.DC.getName();
|
||||
} else {
|
||||
schemaTest = fld.get("dc-schema");
|
||||
}
|
||||
@@ -584,9 +606,9 @@ public class DCInputsReader {
|
||||
Map<String, String> fld = fields.get(i);
|
||||
// verify reference in certain input types
|
||||
String type = fld.get("input-type");
|
||||
if (type.equals("dropdown")
|
||||
if (StringUtils.isNotBlank(type) && (type.equals("dropdown")
|
||||
|| type.equals("qualdrop_value")
|
||||
|| type.equals("list")) {
|
||||
|| type.equals("list"))) {
|
||||
String pairsName = fld.get(PAIR_TYPE_NAME);
|
||||
List<String> v = valuePairs.get(pairsName);
|
||||
if (v == null) {
|
||||
|
@@ -889,7 +889,7 @@ public class GoogleMetadata {
|
||||
Bitstream bitstream = findLinkableFulltext(item);
|
||||
if (bitstream != null) {
|
||||
StringBuilder path = new StringBuilder();
|
||||
path.append(ConfigurationManager.getProperty("dspace.url"));
|
||||
path.append(ConfigurationManager.getProperty("dspace.ui.url"));
|
||||
|
||||
if (item.getHandle() != null) {
|
||||
path.append("/bitstream/");
|
||||
|
@@ -121,20 +121,24 @@ public class IndexVersion {
|
||||
}
|
||||
|
||||
// Open this index directory in Lucene
|
||||
Directory indexDir = FSDirectory.open(dir);
|
||||
Directory indexDir = FSDirectory.open(dir.toPath());
|
||||
|
||||
// Get info on the Lucene segment file(s) in index directory
|
||||
SegmentInfos sis = new SegmentInfos();
|
||||
SegmentInfos sis;
|
||||
try {
|
||||
sis.read(indexDir);
|
||||
sis = SegmentInfos.readLatestCommit(indexDir);
|
||||
} catch (IOException ie) {
|
||||
// Wrap default IOException, providing more info about which directory cannot be read
|
||||
throw new IOException("Could not read Lucene segments files in " + dir.getAbsolutePath(), ie);
|
||||
}
|
||||
|
||||
if (null == sis) {
|
||||
throw new IOException("Could not read Lucene segments files in " + dir.getAbsolutePath());
|
||||
}
|
||||
|
||||
// If we have a valid Solr index dir, but it has no existing segments
|
||||
// then just return an empty string. It's a valid but empty index.
|
||||
if (sis != null && sis.size() == 0) {
|
||||
if (sis.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -246,12 +250,8 @@ public class IndexVersion {
|
||||
} else if (firstMinor > secondMinor) {
|
||||
// If we get here, major versions must be EQUAL. Now, time to check our minor versions
|
||||
return GREATER_THAN;
|
||||
} else if (firstMinor < secondMinor) {
|
||||
return LESS_THAN;
|
||||
} else {
|
||||
// This is an impossible scenario.
|
||||
// This 'else' should never be triggered since we've checked for equality above already
|
||||
return EQUAL;
|
||||
return LESS_THAN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* 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();
|
||||
Node copyToLeftNode = eElement.getElementsByTagName("copyToLeft").item(0);
|
||||
Boolean copyToLeft;
|
||||
if (copyToLeftNode == null) {
|
||||
copyToLeft = false;
|
||||
} else {
|
||||
copyToLeft = Boolean.valueOf(copyToLeftNode.getTextContent());
|
||||
|
||||
}
|
||||
Node copyToRightNode = eElement.getElementsByTagName("copyToRight").item(0);
|
||||
Boolean copyToRight;
|
||||
if (copyToRightNode == null) {
|
||||
copyToRight = false;
|
||||
} else {
|
||||
copyToRight = Boolean.valueOf(copyToRightNode.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, copyToLeft, copyToRight);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} 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,
|
||||
Boolean copyToLeft, Boolean copyToRight)
|
||||
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,
|
||||
copyToLeft, copyToRight);
|
||||
} else {
|
||||
relationshipType.setCopyToLeft(copyToLeft);
|
||||
relationshipType.setCopyToRight(copyToRight);
|
||||
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
||||
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
||||
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
||||
relationshipType.setRightMaxCardinality(rightCardinalityMaxInteger);
|
||||
relationshipTypeService.update(context, relationshipType);
|
||||
}
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@ import org.dspace.app.util.service.OpenSearchService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
@@ -33,7 +34,6 @@ import org.jdom.JDOMException;
|
||||
import org.jdom.Namespace;
|
||||
import org.jdom.output.DOMOutputter;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
@@ -53,20 +53,14 @@ import org.w3c.dom.Document;
|
||||
*
|
||||
* @author Richard Rodgers
|
||||
*/
|
||||
public class OpenSearchServiceImpl implements OpenSearchService, InitializingBean {
|
||||
public class OpenSearchServiceImpl implements OpenSearchService {
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenSearchServiceImpl.class);
|
||||
|
||||
// are open search queries enabled?
|
||||
protected boolean enabled = false;
|
||||
// supported results formats
|
||||
protected List<String> formats = null;
|
||||
// Namespaces used
|
||||
protected final String osNs = "http://a9.com/-/spec/opensearch/1.1/";
|
||||
|
||||
// base search UI URL
|
||||
protected String uiUrl = null;
|
||||
// base search service URL
|
||||
protected String svcUrl = null;
|
||||
@Autowired(required = true)
|
||||
protected ConfigurationService configurationService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected HandleService handleService;
|
||||
@@ -75,25 +69,35 @@ public class OpenSearchServiceImpl implements OpenSearchService, InitializingBea
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
enabled = config.getBooleanProperty("websvc.opensearch.enable");
|
||||
svcUrl = config.getProperty("dspace.url") + "/" +
|
||||
config.getProperty("websvc.opensearch.svccontext");
|
||||
uiUrl = config.getProperty("dspace.url") + "/" +
|
||||
config.getProperty("websvc.opensearch.uicontext");
|
||||
|
||||
// read rest of config info if enabled
|
||||
formats = new ArrayList<String>();
|
||||
if (enabled) {
|
||||
String[] fmts = config.getArrayProperty("websvc.opensearch.formats");
|
||||
public List<String> getFormats() {
|
||||
List<String> formats = new ArrayList<>();
|
||||
// read formats only if enabled
|
||||
if (isEnabled()) {
|
||||
String[] fmts = configurationService.getArrayProperty("websvc.opensearch.formats");
|
||||
formats = Arrays.asList(fmts);
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFormats() {
|
||||
return formats;
|
||||
public boolean isEnabled() {
|
||||
return configurationService.getBooleanProperty("websvc.opensearch.enable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base search service URL (websvc.opensearch.svccontext)
|
||||
*/
|
||||
protected String getBaseSearchServiceURL() {
|
||||
return configurationService.getProperty("dspace.server.url") + "/" +
|
||||
configurationService.getProperty("websvc.opensearch.svccontext");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base search UI URL (websvc.opensearch.uicontext)
|
||||
*/
|
||||
protected String getBaseSearchUIURL() {
|
||||
return configurationService.getProperty("dspace.server.url") + "/" +
|
||||
configurationService.getProperty("websvc.opensearch.uicontext");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,7 +119,7 @@ public class OpenSearchServiceImpl implements OpenSearchService, InitializingBea
|
||||
@Override
|
||||
public String getResultsString(Context context, String format, String query, int totalResults, int start,
|
||||
int pageSize,
|
||||
DSpaceObject scope, List<DSpaceObject> results,
|
||||
IndexableObject scope, List<IndexableObject> results,
|
||||
Map<String, String> labels) throws IOException {
|
||||
try {
|
||||
return getResults(context, format, query, totalResults, start, pageSize, scope, results, labels)
|
||||
@@ -129,7 +133,7 @@ public class OpenSearchServiceImpl implements OpenSearchService, InitializingBea
|
||||
@Override
|
||||
public Document getResultsDoc(Context context, String format, String query, int totalResults, int start,
|
||||
int pageSize,
|
||||
DSpaceObject scope, List<DSpaceObject> results, Map<String, String> labels)
|
||||
IndexableObject scope, List<IndexableObject> results, Map<String, String> labels)
|
||||
throws IOException {
|
||||
try {
|
||||
return getResults(context, format, query, totalResults, start, pageSize, scope, results, labels)
|
||||
@@ -141,8 +145,8 @@ public class OpenSearchServiceImpl implements OpenSearchService, InitializingBea
|
||||
}
|
||||
|
||||
protected SyndicationFeed getResults(Context context, String format, String query, int totalResults, int start,
|
||||
int pageSize,
|
||||
DSpaceObject scope, List<DSpaceObject> results, Map<String, String> labels) {
|
||||
int pageSize, IndexableObject scope,
|
||||
List<IndexableObject> results, Map<String, String> labels) {
|
||||
// Encode results in requested format
|
||||
if ("rss".equals(format)) {
|
||||
format = "rss_2.0";
|
||||
@@ -221,13 +225,13 @@ public class OpenSearchServiceImpl implements OpenSearchService, InitializingBea
|
||||
root.addContent(fav);
|
||||
}
|
||||
// service URLs
|
||||
for (String format : formats) {
|
||||
for (String format : getFormats()) {
|
||||
Element url = new Element("Url", ns).setAttribute("type", getContentType(format));
|
||||
StringBuilder template = new StringBuilder();
|
||||
if ("html".equals(format)) {
|
||||
template.append(uiUrl);
|
||||
template.append(getBaseSearchUIURL());
|
||||
} else {
|
||||
template.append(svcUrl);
|
||||
template.append(getBaseSearchServiceURL());
|
||||
}
|
||||
template.append("?query={searchTerms}");
|
||||
if (!"html".equals(format)) {
|
||||
|
@@ -50,8 +50,11 @@ import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||
import org.dspace.discovery.indexobject.IndexableCommunity;
|
||||
import org.dspace.discovery.indexobject.IndexableItem;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
@@ -179,12 +182,12 @@ public class SyndicationFeed {
|
||||
*
|
||||
* @param request request
|
||||
* @param context context
|
||||
* @param dso DSpaceObject
|
||||
* @param dso the scope
|
||||
* @param items array of objects
|
||||
* @param labels label map
|
||||
*/
|
||||
public void populate(HttpServletRequest request, Context context, DSpaceObject dso,
|
||||
List<? extends DSpaceObject> items, Map<String, String> labels) {
|
||||
public void populate(HttpServletRequest request, Context context, IndexableObject dso,
|
||||
List<IndexableObject> items, Map<String, String> labels) {
|
||||
String logoURL = null;
|
||||
String objectURL = null;
|
||||
String defaultTitle = null;
|
||||
@@ -199,8 +202,8 @@ public class SyndicationFeed {
|
||||
logoURL = ConfigurationManager.getProperty("webui.feed.logo.url");
|
||||
} else {
|
||||
Bitstream logo = null;
|
||||
if (dso.getType() == Constants.COLLECTION) {
|
||||
Collection col = (Collection) dso;
|
||||
if (dso instanceof IndexableCollection) {
|
||||
Collection col = ((IndexableCollection) dso).getIndexedObject();
|
||||
defaultTitle = col.getName();
|
||||
feed.setDescription(collectionService.getMetadata(col, "short_description"));
|
||||
logo = col.getLogo();
|
||||
@@ -208,8 +211,9 @@ public class SyndicationFeed {
|
||||
if (cols != null && cols.length() > 1 && cols.contains(col.getHandle())) {
|
||||
podcastFeed = true;
|
||||
}
|
||||
} else if (dso.getType() == Constants.COMMUNITY) {
|
||||
Community comm = (Community) dso;
|
||||
objectURL = resolveURL(request, col);
|
||||
} else if (dso instanceof IndexableCommunity) {
|
||||
Community comm = ((IndexableCommunity) dso).getIndexedObject();
|
||||
defaultTitle = comm.getName();
|
||||
feed.setDescription(communityService.getMetadata(comm, "short_description"));
|
||||
logo = comm.getLogo();
|
||||
@@ -217,8 +221,9 @@ public class SyndicationFeed {
|
||||
if (comms != null && comms.length() > 1 && comms.contains(comm.getHandle())) {
|
||||
podcastFeed = true;
|
||||
}
|
||||
objectURL = resolveURL(request, comm);
|
||||
}
|
||||
objectURL = resolveURL(request, dso);
|
||||
|
||||
if (logo != null) {
|
||||
logoURL = urlOfBitstream(request, logo);
|
||||
}
|
||||
@@ -247,11 +252,11 @@ public class SyndicationFeed {
|
||||
// add entries for items
|
||||
if (items != null) {
|
||||
List<SyndEntry> entries = new ArrayList<SyndEntry>();
|
||||
for (DSpaceObject itemDSO : items) {
|
||||
if (itemDSO.getType() != Constants.ITEM) {
|
||||
for (IndexableObject idxObj : items) {
|
||||
if (!(idxObj instanceof IndexableItem)) {
|
||||
continue;
|
||||
}
|
||||
Item item = (Item) itemDSO;
|
||||
Item item = ((IndexableItem) idxObj).getIndexedObject();
|
||||
boolean hasDate = false;
|
||||
SyndEntry entry = new SyndEntryImpl();
|
||||
entries.add(entry);
|
||||
@@ -526,11 +531,9 @@ public class SyndicationFeed {
|
||||
if (dso == null) {
|
||||
if (baseURL == null) {
|
||||
if (request == null) {
|
||||
baseURL = ConfigurationManager.getProperty("dspace.url");
|
||||
baseURL = ConfigurationManager.getProperty("dspace.ui.url");
|
||||
} else {
|
||||
baseURL = (request.isSecure()) ? "https://" : "http://";
|
||||
baseURL += ConfigurationManager.getProperty("dspace.hostname");
|
||||
baseURL += ":" + request.getServerPort();
|
||||
baseURL = ConfigurationManager.getProperty("dspace.ui.url");
|
||||
baseURL += request.getContextPath();
|
||||
}
|
||||
}
|
||||
|
@@ -360,9 +360,13 @@ public class Util {
|
||||
InputStream cis = null;
|
||||
try {
|
||||
cis = Util.class.getResourceAsStream("/META-INF/maven/org.dspace/dspace-api/pom.properties");
|
||||
if (cis == null) {
|
||||
// pom.properties will not exist when running tests
|
||||
return "unknown";
|
||||
}
|
||||
constants.load(cis);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error("Could not open dspace-api's pom.properties", e);
|
||||
} finally {
|
||||
if (cis != null) {
|
||||
try {
|
||||
@@ -473,6 +477,26 @@ public class Util {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a list in an array of i sub-lists uniformly sized
|
||||
*
|
||||
* @param idsList the list to split
|
||||
* @param i the number of sublists to return
|
||||
*
|
||||
* @return an array of sub-lists of fixed size
|
||||
*/
|
||||
public static <T> List<T>[] splitList(List<T> idsList, int i) {
|
||||
int setmin = idsList.size() / i;
|
||||
List<T>[] result = new List[i];
|
||||
int offset = 0;
|
||||
for (int idx = 0; idx < i - 1; idx++) {
|
||||
result[idx] = idsList.subList(offset, offset + setmin);
|
||||
offset += setmin;
|
||||
}
|
||||
result[i - 1] = idsList.subList(offset, idsList.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> differenceInSubmissionFields(Collection fromCollection, Collection toCollection)
|
||||
throws DCInputsReaderException {
|
||||
DCInputsReader reader = new DCInputsReader();
|
||||
|
@@ -14,6 +14,7 @@ import java.util.Map;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
@@ -41,6 +42,13 @@ public interface OpenSearchService {
|
||||
*/
|
||||
public List<String> getFormats();
|
||||
|
||||
/**
|
||||
* Determine if the module is active
|
||||
*
|
||||
* @return boolean indicator if the OpenSearch module is enabled or not
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Returns a mime-type associated with passed format
|
||||
*
|
||||
@@ -76,7 +84,7 @@ public interface OpenSearchService {
|
||||
* @param totalResults - the hit count
|
||||
* @param start - start result index
|
||||
* @param pageSize - page size
|
||||
* @param scope - search scope, null or community/collection handle
|
||||
* @param scope - search scope, null or the community/collection
|
||||
* @param results the retreived DSpace objects satisfying search
|
||||
* @param labels labels to apply - format specific
|
||||
* @return formatted search results
|
||||
@@ -84,7 +92,7 @@ public interface OpenSearchService {
|
||||
*/
|
||||
public String getResultsString(Context context, String format, String query, int totalResults, int start,
|
||||
int pageSize,
|
||||
DSpaceObject scope, List<DSpaceObject> results,
|
||||
IndexableObject scope, List<IndexableObject> results,
|
||||
Map<String, String> labels) throws IOException;
|
||||
|
||||
/**
|
||||
@@ -96,7 +104,7 @@ public interface OpenSearchService {
|
||||
* @param totalResults - the hit count
|
||||
* @param start - start result index
|
||||
* @param pageSize - page size
|
||||
* @param scope - search scope, null or community/collection handle
|
||||
* @param scope - search scope, null or the community/collection
|
||||
* @param results the retreived DSpace objects satisfying search
|
||||
* @param labels labels to apply - format specific
|
||||
* @return formatted search results
|
||||
@@ -104,7 +112,7 @@ public interface OpenSearchService {
|
||||
*/
|
||||
public Document getResultsDoc(Context context, String format, String query, int totalResults, int start,
|
||||
int pageSize,
|
||||
DSpaceObject scope, List<DSpaceObject> results, Map<String, String> labels)
|
||||
IndexableObject scope, List<IndexableObject> results, Map<String, String> labels)
|
||||
throws IOException;
|
||||
|
||||
public DSpaceObject resolveScope(Context context, String scope) throws SQLException;
|
||||
|
@@ -87,13 +87,16 @@ public class IPMatcher {
|
||||
+ ipSpec);
|
||||
}
|
||||
|
||||
int maskBytes = maskBits / 8;
|
||||
for (int i = 0; i < maskBytes; i++) {
|
||||
netmask[i] = (byte) 0Xff;
|
||||
}
|
||||
netmask[maskBytes] = (byte) ((byte) 0Xff << 8 - (maskBits % 8)); // FIXME test!
|
||||
for (int i = maskBytes + 1; i < (128 / 8); i++) {
|
||||
for (int i = 0; i < netmask.length; i++) {
|
||||
if (maskBits <= 0) {
|
||||
netmask[i] = 0;
|
||||
} else if (maskBits > 8) {
|
||||
netmask[i] = (byte) 0Xff;
|
||||
} else {
|
||||
netmask[i] = (byte) ((byte) 0Xff << 8 - maskBits);
|
||||
}
|
||||
|
||||
maskBits = maskBits - 8;
|
||||
}
|
||||
break;
|
||||
case 1: // No explicit mask: fill the mask with 1s
|
||||
|
@@ -34,6 +34,7 @@ import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.MetadataFieldService;
|
||||
import org.dspace.content.service.MetadataSchemaService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
@@ -492,35 +493,22 @@ public class ShibAuthentication implements AuthenticationMethod {
|
||||
boolean lazySession = configurationService.getBooleanProperty("authentication-shibboleth.lazysession", false);
|
||||
|
||||
if ( lazySession ) {
|
||||
String shibURL = configurationService.getProperty("authentication-shibboleth.lazysession.loginurl");
|
||||
boolean forceHTTPS =
|
||||
configurationService.getBooleanProperty("authentication-shibboleth.lazysession.secure",true);
|
||||
String shibURL = getShibURL(request);
|
||||
|
||||
// Shibboleth authentication initiator
|
||||
if (shibURL == null || shibURL.length() == 0) {
|
||||
shibURL = "/Shibboleth.sso/Login";
|
||||
// Determine the client redirect URL, where to redirect after authenticating.
|
||||
String redirectUrl = null;
|
||||
if (request.getHeader("Referer") != null && StringUtils.isNotBlank(request.getHeader("Referer"))) {
|
||||
redirectUrl = request.getHeader("Referer");
|
||||
} else if (request.getHeader("X-Requested-With") != null
|
||||
&& StringUtils.isNotBlank(request.getHeader("X-Requested-With"))) {
|
||||
redirectUrl = request.getHeader("X-Requested-With");
|
||||
}
|
||||
shibURL = shibURL.trim();
|
||||
|
||||
// Determine the return URL, where shib will send the user after authenticating. We need it to go back
|
||||
// to DSpace's shibboleth-login url so the we will extract the user's information and locally
|
||||
// authenticate them.
|
||||
String host = request.getServerName();
|
||||
int port = request.getServerPort();
|
||||
String contextPath = request.getContextPath();
|
||||
|
||||
String returnURL = request.getHeader("Referer");
|
||||
if (returnURL == null) {
|
||||
if (request.isSecure() || forceHTTPS) {
|
||||
returnURL = "https://";
|
||||
} else {
|
||||
returnURL = "http://";
|
||||
}
|
||||
returnURL += host;
|
||||
if (!(port == 443 || port == 80)) {
|
||||
returnURL += ":" + port;
|
||||
}
|
||||
}
|
||||
// Determine the server return URL, where shib will send the user after authenticating.
|
||||
// We need it to go back to DSpace's shibboleth-login url so we will extract the user's information
|
||||
// and locally authenticate them.
|
||||
String returnURL = configurationService.getProperty("dspace.server.url") + "/api/authn/shibboleth"
|
||||
+ ((redirectUrl != null) ? "?redirectUrl=" + redirectUrl : "");
|
||||
|
||||
try {
|
||||
shibURL += "?target=" + URLEncoder.encode(returnURL, "UTF-8");
|
||||
@@ -1258,6 +1246,23 @@ public class ShibAuthentication implements AuthenticationMethod {
|
||||
return valueList;
|
||||
}
|
||||
|
||||
private String getShibURL(HttpServletRequest request) {
|
||||
String shibURL = configurationService.getProperty("authentication-shibboleth.lazysession.loginurl",
|
||||
"/Shibboleth.sso/Login");
|
||||
boolean forceHTTPS =
|
||||
configurationService.getBooleanProperty("authentication-shibboleth.lazysession.secure", true);
|
||||
|
||||
// Shibboleth url must be absolute
|
||||
if (shibURL.startsWith("/")) {
|
||||
String serverUrl = Utils.getBaseUrl(configurationService.getProperty("dspace.server.url"));
|
||||
shibURL = serverUrl + shibURL;
|
||||
if ((request.isSecure() || forceHTTPS) && shibURL.startsWith("http://")) {
|
||||
shibURL = shibURL.replace("http://", "https://");
|
||||
}
|
||||
}
|
||||
return shibURL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
package org.dspace.authority;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.List;
|
||||
|
||||
@@ -22,7 +23,8 @@ import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
*/
|
||||
public interface AuthoritySearchService {
|
||||
|
||||
public QueryResponse search(SolrQuery query) throws SolrServerException, MalformedURLException;
|
||||
public QueryResponse search(SolrQuery query)
|
||||
throws SolrServerException, MalformedURLException, IOException;
|
||||
|
||||
public List<String> getAllIndexedMetadataFields() throws Exception;
|
||||
|
||||
|
@@ -13,9 +13,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
import org.apache.solr.client.solrj.response.FacetField;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
@@ -39,21 +40,24 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
||||
/**
|
||||
* Non-Static CommonsHttpSolrServer for processing indexing events.
|
||||
*/
|
||||
protected HttpSolrServer solr = null;
|
||||
protected SolrClient solr = null;
|
||||
|
||||
protected HttpSolrServer getSolr() throws MalformedURLException, SolrServerException {
|
||||
protected SolrClient getSolr()
|
||||
throws MalformedURLException, SolrServerException, IOException {
|
||||
if (solr == null) {
|
||||
|
||||
String solrService = ConfigurationManager.getProperty("solr.authority.server");
|
||||
|
||||
log.debug("Solr authority URL: " + solrService);
|
||||
|
||||
solr = new HttpSolrServer(solrService);
|
||||
solr.setBaseURL(solrService);
|
||||
HttpSolrClient solrServer = new HttpSolrClient.Builder(solrService).build();
|
||||
solrServer.setBaseURL(solrService);
|
||||
|
||||
SolrQuery solrQuery = new SolrQuery().setQuery("*:*");
|
||||
|
||||
solr.query(solrQuery);
|
||||
solrServer.query(solrQuery);
|
||||
|
||||
solr = solrServer;
|
||||
}
|
||||
|
||||
return solr;
|
||||
@@ -129,7 +133,8 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResponse search(SolrQuery query) throws SolrServerException, MalformedURLException {
|
||||
public QueryResponse search(SolrQuery query)
|
||||
throws SolrServerException, MalformedURLException, IOException {
|
||||
return getSolr().query(query);
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package org.dspace.authority;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -23,6 +24,7 @@ import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.util.SolrUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
@@ -34,8 +36,6 @@ import org.joda.time.format.ISODateTimeFormat;
|
||||
* @author Mark Diggory (markd at atmire dot com)
|
||||
*/
|
||||
public class AuthorityValue {
|
||||
|
||||
|
||||
/**
|
||||
* The id of the record in solr
|
||||
*/
|
||||
@@ -150,12 +150,13 @@ public class AuthorityValue {
|
||||
public SolrInputDocument getSolrInputDocument() {
|
||||
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
DateFormat solrDateFormatter = SolrUtils.getDateFormatter();
|
||||
doc.addField("id", getId());
|
||||
doc.addField("field", getField());
|
||||
doc.addField("value", getValue());
|
||||
doc.addField("deleted", isDeleted());
|
||||
doc.addField("creation_date", getCreationDate());
|
||||
doc.addField("last_modified_date", getLastModified());
|
||||
doc.addField("creation_date", solrDateFormatter.format(getCreationDate()));
|
||||
doc.addField("last_modified_date", solrDateFormatter.format(getLastModified()));
|
||||
doc.addField("authority_type", getAuthorityType());
|
||||
return doc;
|
||||
}
|
||||
@@ -196,12 +197,12 @@ public class AuthorityValue {
|
||||
* @return map
|
||||
*/
|
||||
public Map<String, String> choiceSelectMap() {
|
||||
return new HashMap<String, String>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
public List<DateTimeFormatter> getDateFormatters() {
|
||||
List<DateTimeFormatter> list = new ArrayList<DateTimeFormatter>();
|
||||
List<DateTimeFormatter> list = new ArrayList<>();
|
||||
list.add(ISODateTimeFormat.dateTime());
|
||||
list.add(ISODateTimeFormat.dateTimeNoMillis());
|
||||
return list;
|
||||
|
@@ -153,7 +153,7 @@ public class AuthorityValueServiceImpl implements AuthorityValueService {
|
||||
public List<AuthorityValue> findByValue(Context context, String schema, String element, String qualifier,
|
||||
String value) {
|
||||
String field = fieldParameter(schema, element, qualifier);
|
||||
return findByValue(context, field, qualifier);
|
||||
return findByValue(context, field, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -11,8 +11,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
@@ -140,8 +140,8 @@ public class PersonAuthorityValue extends AuthorityValue {
|
||||
@Override
|
||||
public void setValues(SolrDocument document) {
|
||||
super.setValues(document);
|
||||
this.firstName = ObjectUtils.toString(document.getFieldValue("first_name"));
|
||||
this.lastName = ObjectUtils.toString(document.getFieldValue("last_name"));
|
||||
this.firstName = Objects.toString(document.getFieldValue("first_name"), "");
|
||||
this.lastName = Objects.toString(document.getFieldValue("last_name"), "");
|
||||
nameVariants = new ArrayList<String>();
|
||||
Collection<Object> document_name_variant = document.getFieldValues("name_variant");
|
||||
if (document_name_variant != null) {
|
||||
|
@@ -35,6 +35,7 @@ public abstract class AuthorityServiceFactory {
|
||||
|
||||
public abstract AuthorityService getAuthorityService();
|
||||
|
||||
|
||||
public abstract List<AuthorityIndexerInterface> getAuthorityIndexers();
|
||||
|
||||
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;
|
||||
|
||||
import org.dspace.authority.SolrAuthorityInterface;
|
||||
import org.dspace.external.OrcidRestConnector;
|
||||
|
||||
/**
|
||||
* @author Antoine Snyers (antoine at atmire.com)
|
||||
@@ -17,9 +18,9 @@ import org.dspace.authority.SolrAuthorityInterface;
|
||||
*/
|
||||
public abstract class RestSource implements SolrAuthorityInterface {
|
||||
|
||||
protected RESTConnector restConnector;
|
||||
protected OrcidRestConnector restConnector;
|
||||
|
||||
public RestSource(String url) {
|
||||
this.restConnector = new RESTConnector(url);
|
||||
this.restConnector = new OrcidRestConnector(url);
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,8 @@
|
||||
*/
|
||||
package org.dspace.authorize;
|
||||
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
* This class is responsible to provide access to the configuration of the
|
||||
@@ -16,164 +17,26 @@ import org.dspace.core.ConfigurationManager;
|
||||
* @author bollini
|
||||
*/
|
||||
public class AuthorizeConfiguration {
|
||||
|
||||
private static boolean can_communityAdmin_group = ConfigurationManager
|
||||
.getBooleanProperty("core.authorization.community-admin.group",
|
||||
true);
|
||||
|
||||
// subcommunities and collections
|
||||
private static boolean can_communityAdmin_createSubelement = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.create-subelement",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_deleteSubelement = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.delete-subelement",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_policies = ConfigurationManager
|
||||
.getBooleanProperty("core.authorization.community-admin.policies",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_adminGroup = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.admin-group", true);
|
||||
|
||||
private static boolean can_communityAdmin_collectionPolicies = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.collection.policies",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_collectionTemplateItem = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.collection.template-item",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_collectionSubmitters = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.collection.submitters",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_collectionWorkflows = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.collection.workflows",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_collectionAdminGroup = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.collection.admin-group",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_itemDelete = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.delete", true);
|
||||
|
||||
private static boolean can_communityAdmin_itemWithdraw = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.withdraw", true);
|
||||
|
||||
private static boolean can_communityAdmin_itemReinstatiate = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.reinstatiate",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_itemPolicies = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.policies", true);
|
||||
|
||||
// # also bundle
|
||||
private static boolean can_communityAdmin_itemCreateBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.create-bitstream",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_itemDeleteBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item.delete-bitstream",
|
||||
true);
|
||||
|
||||
private static boolean can_communityAdmin_itemAdminccLicense = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.community-admin.item-admin.cc-license",
|
||||
true);
|
||||
|
||||
// # COLLECTION ADMIN
|
||||
private static boolean can_collectionAdmin_policies = ConfigurationManager
|
||||
.getBooleanProperty("core.authorization.collection-admin.policies",
|
||||
true);
|
||||
|
||||
private static boolean can_collectionAdmin_templateItem = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.template-item", true);
|
||||
|
||||
private static boolean can_collectionAdmin_submitters = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.submitters", true);
|
||||
|
||||
private static boolean can_collectionAdmin_workflows = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.workflows", true);
|
||||
|
||||
private static boolean can_collectionAdmin_adminGroup = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.admin-group", true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemDelete = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.delete", true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemWithdraw = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.withdraw", true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemReinstatiate = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.reinstatiate",
|
||||
true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemPolicies = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.policies", true);
|
||||
|
||||
// # also bundle
|
||||
private static boolean can_collectionAdmin_itemCreateBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.create-bitstream",
|
||||
true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemDeleteBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item.delete-bitstream",
|
||||
true);
|
||||
|
||||
private static boolean can_collectionAdmin_itemAdminccLicense = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.collection-admin.item-admin.cc-license",
|
||||
true);
|
||||
|
||||
// # ITEM ADMIN
|
||||
private static boolean can_itemAdmin_policies = ConfigurationManager
|
||||
.getBooleanProperty("core.authorization.item-admin.policies", true);
|
||||
|
||||
// # also bundle
|
||||
private static boolean can_itemAdmin_createBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.item-admin.create-bitstream", true);
|
||||
|
||||
private static boolean can_itemAdmin_deleteBitstream = ConfigurationManager
|
||||
.getBooleanProperty(
|
||||
"core.authorization.item-admin.delete-bitstream", true);
|
||||
|
||||
private static boolean can_itemAdmin_ccLicense = ConfigurationManager
|
||||
.getBooleanProperty("core.authorization.item-admin.cc-license",
|
||||
true);
|
||||
/**
|
||||
* A static reference to the {@link ConfigurationService} see the init method for initialization
|
||||
*/
|
||||
private static ConfigurationService configurationService;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
private AuthorizeConfiguration() { }
|
||||
|
||||
/**
|
||||
* Complete the initialization of the class retrieving a reference to the {@link ConfigurationService}. MUST be
|
||||
* called at the start of each method
|
||||
*/
|
||||
private synchronized static void init() {
|
||||
if (configurationService != null) {
|
||||
return;
|
||||
}
|
||||
configurationService = new DSpace().getConfigurationService();
|
||||
}
|
||||
/**
|
||||
* Are community admins allowed to create new, not strictly community
|
||||
* related, group?
|
||||
@@ -181,7 +44,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformGroupCreation() {
|
||||
return can_communityAdmin_group;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.group", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +54,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformSubelementCreation() {
|
||||
return can_communityAdmin_createSubelement;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.create-subelement", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,7 +64,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformSubelementDeletion() {
|
||||
return can_communityAdmin_deleteSubelement;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.delete-subelement", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +75,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManagePolicies() {
|
||||
return can_communityAdmin_policies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,7 +86,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageAdminGroup() {
|
||||
return can_communityAdmin_adminGroup;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.admin-group", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,7 +97,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCollectionPolicies() {
|
||||
return can_communityAdmin_collectionPolicies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.collection.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,7 +108,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCollectionTemplateItem() {
|
||||
return can_communityAdmin_collectionTemplateItem;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.collection.template-item",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +120,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCollectionSubmitters() {
|
||||
return can_communityAdmin_collectionSubmitters;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.collection.submitters",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,7 +132,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCollectionWorkflows() {
|
||||
return can_communityAdmin_collectionWorkflows;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.collection.workflows", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,7 +143,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCollectionAdminGroup() {
|
||||
return can_communityAdmin_collectionAdminGroup;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.collection.admin-group",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,7 +154,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformItemDeletion() {
|
||||
return can_communityAdmin_itemDelete;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.delete", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,7 +164,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformItemWithdrawn() {
|
||||
return can_communityAdmin_itemWithdraw;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.withdraw", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,7 +175,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformItemReinstatiate() {
|
||||
return can_communityAdmin_itemReinstatiate;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.reinstatiate", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,7 +186,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageItemPolicies() {
|
||||
return can_communityAdmin_itemPolicies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +197,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformBitstreamCreation() {
|
||||
return can_communityAdmin_itemCreateBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.create-bitstream",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,7 +209,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminPerformBitstreamDeletion() {
|
||||
return can_communityAdmin_itemDeleteBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item.delete-bitstream",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +221,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCommunityAdminManageCCLicense() {
|
||||
return can_communityAdmin_itemAdminccLicense;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.community-admin.item-admin.cc-license",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,7 +232,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManagePolicies() {
|
||||
return can_collectionAdmin_policies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,7 +243,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageTemplateItem() {
|
||||
return can_collectionAdmin_templateItem;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.template-item", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,7 +254,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageSubmitters() {
|
||||
return can_collectionAdmin_submitters;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.submitters", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +265,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageWorkflows() {
|
||||
return can_collectionAdmin_workflows;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.workflows", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,7 +276,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageAdminGroup() {
|
||||
return can_collectionAdmin_adminGroup;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.admin-group", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,7 +286,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminPerformItemDeletion() {
|
||||
return can_collectionAdmin_itemDelete;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.delete", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,7 +296,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminPerformItemWithdrawn() {
|
||||
return can_collectionAdmin_itemWithdraw;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.withdraw", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -414,7 +307,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminPerformItemReinstatiate() {
|
||||
return can_collectionAdmin_itemReinstatiate;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.reinstatiate", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,7 +318,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageItemPolicies() {
|
||||
return can_collectionAdmin_itemPolicies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,7 +329,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminPerformBitstreamCreation() {
|
||||
return can_collectionAdmin_itemCreateBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.create-bitstream",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,7 +341,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminPerformBitstreamDeletion() {
|
||||
return can_collectionAdmin_itemDeleteBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item.delete-bitstream",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,7 +353,9 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canCollectionAdminManageCCLicense() {
|
||||
return can_collectionAdmin_itemAdminccLicense;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.collection-admin.item-admin.cc-license",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,7 +364,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canItemAdminManagePolicies() {
|
||||
return can_itemAdmin_policies;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.item-admin.policies", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,7 +374,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canItemAdminPerformBitstreamCreation() {
|
||||
return can_itemAdmin_createBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.item-admin.create-bitstream", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,7 +384,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canItemAdminPerformBitstreamDeletion() {
|
||||
return can_itemAdmin_deleteBitstream;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.item-admin.delete-bitstream", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,7 +394,8 @@ public class AuthorizeConfiguration {
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean canItemAdminManageCCLicense() {
|
||||
return can_itemAdmin_ccLicense;
|
||||
init();
|
||||
return configurationService.getBooleanProperty("core.authorization.item-admin.cc-license", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -430,7 +430,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
||||
|
||||
public boolean isCommunityAdmin(Context c) throws SQLException {
|
||||
EPerson e = c.getCurrentUser();
|
||||
return isCommunityAdmin(c, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException {
|
||||
if (e != null) {
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
||||
groupService.allMemberGroups(c, e),
|
||||
@@ -446,7 +450,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
||||
|
||||
public boolean isCollectionAdmin(Context c) throws SQLException {
|
||||
EPerson e = c.getCurrentUser();
|
||||
return isCollectionAdmin(c, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException {
|
||||
if (e != null) {
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
||||
groupService.allMemberGroups(c, e),
|
||||
@@ -773,4 +781,10 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
||||
return policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> getPoliciesActionFilterExceptRpType(Context c, DSpaceObject o, int actionID,
|
||||
String rpType) throws SQLException {
|
||||
return resourcePolicyService.findExceptRpType(c, o, actionID, rpType);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package org.dspace.authorize;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@@ -23,7 +24,6 @@ import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.ReloadableEntity;
|
||||
@@ -123,16 +123,16 @@ public class ResourcePolicy implements ReloadableEntity<Integer> {
|
||||
if (getAction() != other.getAction()) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.equals(getEPerson(), other.getEPerson())) {
|
||||
if (!Objects.equals(getEPerson(), other.getEPerson())) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.equals(getGroup(), other.getGroup())) {
|
||||
if (!Objects.equals(getGroup(), other.getGroup())) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.equals(getStartDate(), other.getStartDate())) {
|
||||
if (!Objects.equals(getStartDate(), other.getStartDate())) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.equals(getEndDate(), other.getEndDate())) {
|
||||
if (!Objects.equals(getEndDate(), other.getEndDate())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -185,7 +185,7 @@ public class ResourcePolicy implements ReloadableEntity<Integer> {
|
||||
/**
|
||||
* set the action this policy authorizes
|
||||
*
|
||||
* @param myid action ID from {@link org.dspace.core.Constants#Constants Constants}
|
||||
* @param myid action ID from {@link org.dspace.core.Constants Constants}
|
||||
*/
|
||||
public void setAction(int myid) {
|
||||
this.actionId = myid;
|
||||
|
@@ -13,6 +13,7 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
@@ -25,6 +26,7 @@ import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
@@ -46,6 +48,9 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
||||
@Autowired(required = true)
|
||||
protected ResourcePolicyDAO resourcePolicyDAO;
|
||||
|
||||
@Autowired
|
||||
private GroupService groupService;
|
||||
|
||||
protected ResourcePolicyServiceImpl() {
|
||||
}
|
||||
|
||||
@@ -317,4 +322,91 @@ public class ResourcePolicyServiceImpl implements ResourcePolicyService {
|
||||
context.restoreAuthSystemState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findExceptRpType(Context c, DSpaceObject o, int actionID, String rpType)
|
||||
throws SQLException {
|
||||
return resourcePolicyDAO.findByDSoAndActionExceptRpType(c, o, actionID, rpType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByEPerson(Context context, EPerson ePerson, int offset, int limit)
|
||||
throws SQLException {
|
||||
return resourcePolicyDAO.findByEPerson(context, ePerson, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByEPerson(Context context, EPerson eperson) throws SQLException {
|
||||
return resourcePolicyDAO.countByEPerson(context, eperson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByEPersonAndResourceUuid(Context context, EPerson eperson, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException {
|
||||
return resourcePolicyDAO.findByEPersonAndResourceUuid(context, eperson, resourceUuid, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countResourcePoliciesByEPersonAndResourceUuid(Context context, EPerson eperson, UUID resourceUuid)
|
||||
throws SQLException {
|
||||
return resourcePolicyDAO.countByEPersonAndResourceUuid(context, eperson, resourceUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId,
|
||||
int offset, int limit) throws SQLException {
|
||||
return resourcePolicyDAO.findByResouceUuidAndActionId(context, resourceUuid, actionId, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId) throws SQLException {
|
||||
return resourcePolicyDAO.countByResouceUuidAndActionId(context, resourceUuid, actionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByResouceUuid(Context context, UUID resourceUuid, int offset, int limit)
|
||||
throws SQLException {
|
||||
return resourcePolicyDAO.findByResouceUuid(context, resourceUuid, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByResourceUuid(Context context, UUID resourceUuid) throws SQLException {
|
||||
return resourcePolicyDAO.countByResourceUuid(context, resourceUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByGroup(Context context, Group group, int offset, int limit) throws SQLException {
|
||||
return resourcePolicyDAO.findByGroup(context, group, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countResourcePolicyByGroup(Context context, Group group) throws SQLException {
|
||||
return resourcePolicyDAO.countResourcePolicyByGroup(context, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException {
|
||||
return resourcePolicyDAO.findByGroupAndResourceUuid(context, group, resourceUuid, offset, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid) throws SQLException {
|
||||
return resourcePolicyDAO.countByGroupAndResourceUuid(context, group, resourceUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMyResourcePolicy(Context context, EPerson eperson, Integer id) throws SQLException {
|
||||
boolean isMy = false;
|
||||
|
||||
ResourcePolicy resourcePolicy = resourcePolicyDAO.findOneById(context, id);
|
||||
Group group = resourcePolicy.getGroup();
|
||||
|
||||
if (resourcePolicy.getEPerson() != null && resourcePolicy.getEPerson().getID() == eperson.getID()) {
|
||||
isMy = true;
|
||||
} else if (group != null && groupService.isMember(context, eperson, group)) {
|
||||
isMy = true;
|
||||
}
|
||||
return isMy;
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ package org.dspace.authorize.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
@@ -70,4 +71,166 @@ public interface ResourcePolicyDAO extends GenericDAO<ResourcePolicy> {
|
||||
public void deleteAllEPersonPolicies(Context context, EPerson ePerson) throws SQLException;
|
||||
|
||||
public void deleteByDsoAndTypeNotEqualsTo(Context c, DSpaceObject o, String type) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a list of policies for an object that match the action except the record labeled with the rpType
|
||||
*
|
||||
* @param c context
|
||||
* @param o DSpaceObject policies relate to
|
||||
* @param actionID action (defined in class Constants)
|
||||
* @param rpType the resource policy type
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if there's a database problem
|
||||
*/
|
||||
public List<ResourcePolicy> findByDSoAndActionExceptRpType(Context c, DSpaceObject o, int actionID,
|
||||
String rpType) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies that belong to an EPerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByEPerson(Context context, EPerson ePerson, int offset, int limit)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to count
|
||||
* @return total resource policies of the ePerson
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByEPerson(Context context, EPerson eperson) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a resourceUuid belong to an ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByEPersonAndResourceUuid(Context context, EPerson ePerson, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies related to a resourceUuid belong to an ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByEPersonAndResourceUuid(Context context, EPerson ePerson, UUID resourceUuid)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a DSpace resource filter by actionId
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param actionId id relative to action as READ, WRITE, DELITE etc.
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies related to a resourceUuid and actionId
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param actionId id relative to action as READ, WRITE, DELITE etc.
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a DSpace resource
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByResouceUuid(Context context, UUID resourceUuid, int offset, int limit)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies by resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByResourceUuid(Context context, UUID resourceUuid) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a group
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByGroup(Context context, Group group, int offset, int limit)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the group
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countResourcePolicyByGroup(Context context, Group group) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a group and related to a resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the group and of the resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid) throws SQLException;
|
||||
|
||||
public ResourcePolicy findOneById(Context context, Integer id) throws SQLException;
|
||||
|
||||
|
||||
}
|
||||
|
@@ -9,15 +9,18 @@ package org.dspace.authorize.dao.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.ResourcePolicy_;
|
||||
import org.dspace.authorize.dao.ResourcePolicyDAO;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.DSpaceObject_;
|
||||
import org.dspace.core.AbstractHibernateDAO;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
@@ -141,8 +144,7 @@ public class ResourcePolicyDAOImpl extends AbstractHibernateDAO<ResourcePolicy>
|
||||
criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.actionId), action),
|
||||
criteriaBuilder
|
||||
.or(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.eperson), e),
|
||||
criteriaBuilder
|
||||
.in(resourcePolicyRoot.get(ResourcePolicy_.epersonGroup).in(groups)))
|
||||
(resourcePolicyRoot.get(ResourcePolicy_.epersonGroup).in(groups)))
|
||||
)
|
||||
);
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, 1, -1);
|
||||
@@ -220,4 +222,167 @@ public class ResourcePolicyDAOImpl extends AbstractHibernateDAO<ResourcePolicy>
|
||||
query.setParameter("rptype", type);
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByDSoAndActionExceptRpType(Context context, DSpaceObject dso, int action,
|
||||
String rpType) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
criteriaQuery.select(resourcePolicyRoot);
|
||||
if (rpType != null) {
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.dSpaceObject), dso),
|
||||
criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.actionId), action),
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.notEqual(resourcePolicyRoot.get(ResourcePolicy_.rptype),
|
||||
rpType),
|
||||
criteriaBuilder.isNull(resourcePolicyRoot.get(ResourcePolicy_.rptype))
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.dSpaceObject), dso),
|
||||
criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.actionId), action),
|
||||
criteriaBuilder.isNotNull(resourcePolicyRoot.get(ResourcePolicy_.rptype))
|
||||
)
|
||||
);
|
||||
}
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByEPerson(Context context, EPerson ePerson, int offset, int limit)
|
||||
throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
criteriaQuery.select(resourcePolicyRoot);
|
||||
criteriaQuery.where(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.eperson), ePerson));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByEPerson(Context context, EPerson eperson) throws SQLException {
|
||||
Query query = createQuery(context,
|
||||
"SELECT count(*) FROM " + ResourcePolicy.class.getSimpleName() + " WHERE eperson_id = (:epersonUuid) ");
|
||||
query.setParameter("epersonUuid", eperson.getID());
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByEPersonAndResourceUuid(Context context, EPerson ePerson, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
Join<ResourcePolicy, DSpaceObject> join = resourcePolicyRoot.join(ResourcePolicy_.dSpaceObject);
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.eperson), ePerson),
|
||||
criteriaBuilder.equal(join.get(DSpaceObject_.id), resourceUuid)));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByEPersonAndResourceUuid(Context context, EPerson eperson, UUID resourceUuid) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(*) FROM " + ResourcePolicy.class.getSimpleName()
|
||||
+ " WHERE eperson_id = (:epersonUuid) AND dspace_object = (:resourceUuid) ");
|
||||
query.setParameter("resourceUuid", resourceUuid);
|
||||
query.setParameter("epersonUuid", eperson.getID());
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId,
|
||||
int offset, int limit) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
Join<ResourcePolicy, DSpaceObject> join = resourcePolicyRoot.join(ResourcePolicy_.dSpaceObject);
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.actionId), actionId),
|
||||
criteriaBuilder.equal(join.get(DSpaceObject_.id), resourceUuid)));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(*) FROM " + ResourcePolicy.class.getSimpleName()
|
||||
+ " WHERE dspace_object = (:resourceUuid) AND action_id = (:actionId) ");
|
||||
query.setParameter("resourceUuid", resourceUuid);
|
||||
query.setParameter("actionId", actionId);
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByResouceUuid(Context context, UUID resourceUuid, int offset, int limit)
|
||||
throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
Join<ResourcePolicy, DSpaceObject> join = resourcePolicyRoot.join(ResourcePolicy_.dSpaceObject);
|
||||
criteriaQuery.where(criteriaBuilder.equal(join.get(DSpaceObject_.id), resourceUuid));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByResourceUuid(Context context, UUID resourceUuid) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(*) FROM " + ResourcePolicy.class.getSimpleName()
|
||||
+ " WHERE dspace_object = (:resourceUuid) ");
|
||||
query.setParameter("resourceUuid", resourceUuid);
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByGroup(Context context, Group group, int offset, int limit) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
criteriaQuery.select(resourcePolicyRoot);
|
||||
criteriaQuery.where(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.epersonGroup), group));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countResourcePolicyByGroup(Context context, Group group) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(*) " + "FROM " + ResourcePolicy.class.getSimpleName()
|
||||
+ " WHERE epersongroup_id = (:groupUuid) ");
|
||||
query.setParameter("groupUuid", group.getID());
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePolicy> findByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
Join<ResourcePolicy, DSpaceObject> join = resourcePolicyRoot.join(ResourcePolicy_.dSpaceObject);
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.epersonGroup), group),
|
||||
criteriaBuilder.equal(join.get(DSpaceObject_.id), resourceUuid)));
|
||||
return list(context, criteriaQuery, false, ResourcePolicy.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid) throws SQLException {
|
||||
Query query = createQuery(context, "SELECT count(*) FROM " + ResourcePolicy.class.getSimpleName()
|
||||
+ " WHERE dspace_object = (:resourceUuid) AND epersongroup_id = (:groupUuid) ");
|
||||
query.setParameter("resourceUuid", resourceUuid);
|
||||
query.setParameter("groupUuid", group.getID());
|
||||
return count(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourcePolicy findOneById(Context context, Integer id) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ResourcePolicy.class);
|
||||
Root<ResourcePolicy> resourcePolicyRoot = criteriaQuery.from(ResourcePolicy.class);
|
||||
criteriaQuery.select(resourcePolicyRoot);
|
||||
criteriaQuery.where(criteriaBuilder.equal(resourcePolicyRoot.get(ResourcePolicy_.id), id));
|
||||
return singleResult(context, criteriaQuery);
|
||||
}
|
||||
}
|
||||
|
@@ -213,6 +213,26 @@ public interface AuthorizeService {
|
||||
|
||||
public boolean isCollectionAdmin(Context c) throws SQLException;
|
||||
|
||||
/**
|
||||
* Check to see if a specific user is Community admin
|
||||
*
|
||||
* @param c current context
|
||||
* @param e the user to check
|
||||
* @return true if user is an admin of some community
|
||||
* @throws SQLException
|
||||
*/
|
||||
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException;
|
||||
|
||||
/**
|
||||
* Check to see if a specific user is Collection admin
|
||||
*
|
||||
* @param c current context
|
||||
* @param e the user to check
|
||||
* @return true if user is an admin of some collection
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// policy manipulation methods
|
||||
///////////////////////////////////////////////
|
||||
@@ -312,6 +332,18 @@ public interface AuthorizeService {
|
||||
*/
|
||||
public List<ResourcePolicy> getPoliciesActionFilter(Context c, DSpaceObject o, int actionID) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a list of policies for an object that match the action except the record labeled with the rpType
|
||||
*
|
||||
* @param c context
|
||||
* @param o DSpaceObject policies relate to
|
||||
* @param actionID action (defined in class Constants)
|
||||
* @param rpType the resource policy type
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if there's a database problem
|
||||
*/
|
||||
public List<ResourcePolicy> getPoliciesActionFilterExceptRpType(Context c, DSpaceObject o, int actionID,
|
||||
String rpType) throws SQLException;
|
||||
/**
|
||||
* Add policies to an object to match those from a previous object
|
||||
*
|
||||
|
@@ -9,6 +9,7 @@ package org.dspace.authorize.service;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
@@ -80,4 +81,171 @@ public interface ResourcePolicyService extends DSpaceCRUDService<ResourcePolicy>
|
||||
public void removeDsoAndTypeNotEqualsToPolicies(Context c, DSpaceObject o, String type)
|
||||
throws SQLException, AuthorizeException;
|
||||
|
||||
/**
|
||||
* Return a list of policies for an object that match the action except the record labeled with the rpType
|
||||
*
|
||||
* @param c context
|
||||
* @param o DSpaceObject policies relate to
|
||||
* @param actionID action (defined in class Constants)
|
||||
* @param rpType the resource policy type
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if there's a database problem
|
||||
*/
|
||||
public List<ResourcePolicy> findExceptRpType(Context c, DSpaceObject o, int actionID, String rpType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies that belong to an EPerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByEPerson(Context context, EPerson ePerson, int offset, int limit)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to count
|
||||
* @return total resource policies of the ePerson
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByEPerson(Context context, EPerson ePerson) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a resourceUuid belong to an ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByEPersonAndResourceUuid(Context context, EPerson ePerson, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies related to a resourceUuid belong to an ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param ePerson ePerson whose policies want to find
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countResourcePoliciesByEPersonAndResourceUuid(Context context, EPerson ePerson, UUID resourceUuid)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a DSpace resource filter by actionId
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param actionId id relative to action as READ, WRITE, DELITE etc.
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies related to a resourceUuid and actionId
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param actionId id relative to action as READ, WRITE, DELITE etc.
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByResouceUuidAndActionId(Context context, UUID resourceUuid, int actionId) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a DSpace resource
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByResouceUuid(Context context, UUID resourceUuid, int offset, int limit)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the policies by resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByResourceUuid(Context context, UUID resourceUuid) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a group
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByGroup(Context context, Group group, int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the group
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countResourcePolicyByGroup(Context context, Group group) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a paginated list of policies related to a group and related to a resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @param offset the position of the first result to return
|
||||
* @param limit paging limit
|
||||
* @return list of resource policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public List<ResourcePolicy> findByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid,
|
||||
int offset, int limit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count all the resource policies of the group and of the resourceUuid
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param group DSpace group
|
||||
* @param resourceUuid the uuid of an DSpace resource
|
||||
* @return total policies
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public int countByGroupAndResourceUuid(Context context, Group group, UUID resourceUuid) throws SQLException;
|
||||
|
||||
/**
|
||||
* Check if the resource policy identified with (id) belong to ePerson
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @param eperson ePerson
|
||||
* @param id id of resource policy
|
||||
* @return
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public boolean isMyResourcePolicy(Context context, EPerson eperson, Integer id) throws SQLException;
|
||||
|
||||
}
|
||||
|
@@ -11,6 +11,9 @@ import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||
import org.dspace.discovery.indexobject.IndexableCommunity;
|
||||
import org.dspace.sort.SortException;
|
||||
import org.dspace.sort.SortOption;
|
||||
|
||||
@@ -114,6 +117,8 @@ public class BrowserScope {
|
||||
|
||||
private String authority = null;
|
||||
|
||||
private String userLocale = null;
|
||||
|
||||
/**
|
||||
* Construct a new BrowserScope using the given Context
|
||||
*
|
||||
@@ -131,12 +136,12 @@ public class BrowserScope {
|
||||
* @param dso the container object; a Community or Collection
|
||||
* @throws BrowseException if browse error
|
||||
*/
|
||||
public void setBrowseContainer(DSpaceObject dso)
|
||||
public void setBrowseContainer(IndexableObject dso)
|
||||
throws BrowseException {
|
||||
if (dso instanceof Collection) {
|
||||
this.collection = (Collection) dso;
|
||||
} else if (dso instanceof Community) {
|
||||
this.community = (Community) dso;
|
||||
if (dso instanceof IndexableCollection) {
|
||||
this.collection = ((IndexableCollection) dso).getIndexedObject();
|
||||
} else if (dso instanceof IndexableCommunity) {
|
||||
this.community = ((IndexableCommunity) dso).getIndexedObject();
|
||||
} else {
|
||||
throw new BrowseException("The container must be a community or a collection");
|
||||
}
|
||||
@@ -582,4 +587,12 @@ public class BrowserScope {
|
||||
public void setAuthorityValue(String value) {
|
||||
authority = value;
|
||||
}
|
||||
|
||||
public void setUserLocale(String userLocale) {
|
||||
this.userLocale = userLocale;
|
||||
}
|
||||
|
||||
public String getUserLocale() {
|
||||
return userLocale;
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import org.dspace.discovery.DiscoverResult.FacetResult;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||
import org.dspace.discovery.indexobject.IndexableItem;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
/**
|
||||
@@ -122,13 +123,13 @@ public class ItemCountDAOSolr implements ItemCountDAO {
|
||||
query.addFacetField(new DiscoverFacetField("location.coll",
|
||||
DiscoveryConfigurationParameters.TYPE_STANDARD, -1,
|
||||
DiscoveryConfigurationParameters.SORT.COUNT));
|
||||
query.addFilterQueries("search.resourcetype:2"); // count only items
|
||||
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE); // count only items
|
||||
query.addFilterQueries("NOT(discoverable:false)"); // only discoverable
|
||||
query.setMaxResults(0);
|
||||
|
||||
DiscoverResult sResponse = null;
|
||||
try {
|
||||
sResponse = searcher.search(context, query, false);
|
||||
sResponse = searcher.search(context, query);
|
||||
List<FacetResult> commCount = sResponse.getFacetResult("location.comm");
|
||||
List<FacetResult> collCount = sResponse.getFacetResult("location.coll");
|
||||
for (FacetResult c : commCount) {
|
||||
|
@@ -19,9 +19,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverFacetField;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
@@ -29,9 +27,11 @@ import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.DiscoverResult.FacetResult;
|
||||
import org.dspace.discovery.DiscoverResult.SearchDocument;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||
import org.dspace.discovery.indexobject.IndexableItem;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
/**
|
||||
@@ -169,9 +169,6 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
|
||||
private DiscoverResult sResponse = null;
|
||||
|
||||
private boolean itemsWithdrawn = false;
|
||||
private boolean itemsDiscoverable = true;
|
||||
|
||||
private boolean showFrequencies;
|
||||
|
||||
private DiscoverResult getSolrResponse() throws BrowseException {
|
||||
@@ -210,15 +207,14 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
}
|
||||
// filter on item to be sure to don't include any other object
|
||||
// indexed in the Discovery Search core
|
||||
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
|
||||
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE);
|
||||
if (orderField != null) {
|
||||
query.setSortField("bi_" + orderField + "_sort",
|
||||
ascending ? SORT_ORDER.asc : SORT_ORDER.desc);
|
||||
}
|
||||
}
|
||||
try {
|
||||
sResponse = searcher.search(context, query, itemsWithdrawn
|
||||
|| !itemsDiscoverable);
|
||||
sResponse = searcher.search(context, query);
|
||||
} catch (SearchServiceException e) {
|
||||
throw new BrowseException(e);
|
||||
}
|
||||
@@ -227,12 +223,6 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
}
|
||||
|
||||
private void addStatusFilter(DiscoverQuery query) {
|
||||
if (itemsWithdrawn) {
|
||||
query.addFilterQueries("withdrawn:true");
|
||||
} else if (!itemsDiscoverable) {
|
||||
query.addFilterQueries("discoverable:false");
|
||||
// TODO
|
||||
|
||||
try {
|
||||
if (!authorizeService.isAdmin(context)
|
||||
&& (authorizeService.isCommunityAdmin(context)
|
||||
@@ -240,8 +230,7 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
query.addFilterQueries(searcher.createLocationQueryForAdministrableItems(context));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
log.error(ex);
|
||||
}
|
||||
log.error("Error looking up authorization rights of current user", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,10 +297,10 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
|
||||
List<Item> bitems = new ArrayList<>();
|
||||
for (DSpaceObject solrDoc : resp.getDspaceObjects()) {
|
||||
for (IndexableObject solrDoc : resp.getIndexableObjects()) {
|
||||
// FIXME introduce project, don't retrieve Item immediately when
|
||||
// processing the query...
|
||||
Item item = (Item) solrDoc;
|
||||
Item item = ((IndexableItem) solrDoc).getIndexedObject();
|
||||
bitems.add(item);
|
||||
}
|
||||
return bitems;
|
||||
@@ -322,7 +311,7 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
throws BrowseException {
|
||||
DiscoverQuery query = new DiscoverQuery();
|
||||
query.setQuery("search.resourceid:" + itemID
|
||||
+ " AND search.resourcetype:" + Constants.ITEM);
|
||||
+ " AND search.resourcetype:" + IndexableItem.TYPE);
|
||||
query.setMaxResults(1);
|
||||
DiscoverResult resp = null;
|
||||
try {
|
||||
@@ -332,7 +321,7 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
}
|
||||
if (resp.getTotalSearchResults() > 0) {
|
||||
SearchDocument doc = resp.getSearchDocument(
|
||||
resp.getDspaceObjects().get(0)).get(0);
|
||||
resp.getIndexableObjects().get(0)).get(0);
|
||||
return (String) doc.getSearchFieldValues(column).get(0);
|
||||
}
|
||||
return null;
|
||||
@@ -345,7 +334,7 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
addLocationScopeFilter(query);
|
||||
addStatusFilter(query);
|
||||
query.setMaxResults(0);
|
||||
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
|
||||
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE);
|
||||
|
||||
// We need to take into account the fact that we may be in a subset of the items
|
||||
if (authority != null) {
|
||||
@@ -363,10 +352,9 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
query.setQuery("bi_" + column + "_sort" + ": {\"" + value + "\" TO *]");
|
||||
query.addFilterQueries("-(bi_" + column + "_sort" + ":" + value + "*)");
|
||||
}
|
||||
boolean includeUnDiscoverable = itemsWithdrawn || !itemsDiscoverable;
|
||||
DiscoverResult resp = null;
|
||||
try {
|
||||
resp = searcher.search(context, query, includeUnDiscoverable);
|
||||
resp = searcher.search(context, query);
|
||||
} catch (SearchServiceException e) {
|
||||
throw new BrowseException(e);
|
||||
}
|
||||
@@ -693,11 +681,6 @@ public class SolrBrowseDAO implements BrowseDAO {
|
||||
*/
|
||||
@Override
|
||||
public void setTable(String table) {
|
||||
if (table.equals(BrowseIndex.getWithdrawnBrowseIndex().getTableName())) {
|
||||
itemsWithdrawn = true;
|
||||
} else if (table.equals(BrowseIndex.getPrivateBrowseIndex().getTableName())) {
|
||||
itemsDiscoverable = false;
|
||||
}
|
||||
facetField = table;
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ import org.dspace.checker.service.SimpleReporterService;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Email;
|
||||
import org.dspace.core.Utils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -62,12 +63,12 @@ public class DailyReportEmailer {
|
||||
public void sendReport(File attachment, int numberOfBitstreams)
|
||||
throws IOException, javax.mail.MessagingException {
|
||||
if (numberOfBitstreams > 0) {
|
||||
String hostname = ConfigurationManager.getProperty("dspace.hostname");
|
||||
String hostname = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
|
||||
Email email = new Email();
|
||||
email.setSubject(
|
||||
"Checksum checker Report - " + numberOfBitstreams + " Bitstreams found with POSSIBLE issues on " +
|
||||
hostname);
|
||||
email.setContent("report is attached ...");
|
||||
email.setContent("Checker Report", "report is attached ...");
|
||||
email.addAttachment(attachment, "checksum_checker_report.txt");
|
||||
email.addRecipient(ConfigurationManager.getProperty("mail.admin"));
|
||||
email.send();
|
||||
|
@@ -21,6 +21,7 @@ import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
import org.dspace.core.Constants;
|
||||
@@ -40,6 +41,12 @@ import org.hibernate.proxy.HibernateProxyHelper;
|
||||
@Entity
|
||||
@Table(name = "bitstream")
|
||||
public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport {
|
||||
|
||||
/**
|
||||
* log4j logger
|
||||
*/
|
||||
private static Logger log = Logger.getLogger(Bitstream.class);
|
||||
|
||||
@Column(name = "bitstream_id", insertable = false, updatable = false)
|
||||
private Integer legacyId;
|
||||
|
||||
@@ -91,8 +98,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
|
||||
*/
|
||||
public int getSequenceID() {
|
||||
@@ -104,8 +115,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
|
||||
*/
|
||||
public void setSequenceID(int sid) {
|
||||
@@ -122,7 +137,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
*/
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +149,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +161,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
* @return the source of the bitstream
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +173,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +185,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
*/
|
||||
public String getDescription() {
|
||||
return getBitstreamService()
|
||||
.getMetadataFirstValue(this, MetadataSchema.DC_SCHEMA, "description", null, Item.ANY);
|
||||
.getMetadataFirstValue(this, MetadataSchemaEnum.DC.getName(), "description",
|
||||
null, Item.ANY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +198,7 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
*/
|
||||
public void setDescription(Context context, String n) throws SQLException {
|
||||
getBitstreamService()
|
||||
.setMetadataSingleValue(context, this, MetadataSchema.DC_SCHEMA, "description", null, null, n);
|
||||
.setMetadataSingleValue(context, this, MetadataSchemaEnum.DC.getName(), "description", null, null, n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +247,8 @@ public class Bitstream extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
* @return the user's format description.
|
||||
*/
|
||||
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() {
|
||||
|
@@ -71,7 +71,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity<Integer>
|
||||
@Column(name = "internal")
|
||||
private boolean internal = false;
|
||||
|
||||
@ElementCollection(fetch = FetchType.LAZY)
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(name = "fileextension", joinColumns = @JoinColumn(name = "bitstream_format_id"))
|
||||
@CollectionId(
|
||||
columns = @Column(name = "file_extension_id"),
|
||||
@@ -275,7 +275,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity<Integer>
|
||||
return false;
|
||||
}
|
||||
final BitstreamFormat otherBitstreamFormat = (BitstreamFormat) other;
|
||||
if (this.getID() != otherBitstreamFormat.getID()) {
|
||||
if (!this.getID().equals(otherBitstreamFormat.getID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -153,7 +153,7 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService {
|
||||
// If the exception was thrown, unknown will == null so goahead and
|
||||
// load s. If not, check that the unknown's registry's name is not
|
||||
// being reset.
|
||||
if (unknown == null || unknown.getID() != bitstreamFormat.getID()) {
|
||||
if (unknown == null || !unknown.getID().equals(bitstreamFormat.getID())) {
|
||||
bitstreamFormat.setShortDescriptionInternal(shortDescription);
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,7 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService {
|
||||
// Find "unknown" type
|
||||
BitstreamFormat unknown = findUnknown(context);
|
||||
|
||||
if (unknown.getID() == bitstreamFormat.getID()) {
|
||||
if (unknown.getID().equals(bitstreamFormat.getID())) {
|
||||
throw new IllegalArgumentException("The Unknown bitstream format may not be deleted.");
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -205,7 +206,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
|
||||
@Override
|
||||
public void setUserFormatDescription(Context context, Bitstream bitstream, String desc) throws SQLException {
|
||||
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
|
||||
@@ -235,7 +236,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
|
||||
}
|
||||
|
||||
// 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
|
||||
bitstream.setFormat(bitstreamFormat);
|
||||
@@ -462,7 +463,9 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
|
||||
return bitstreamDAO.getNotReferencedBitstreams(context);
|
||||
}
|
||||
|
||||
public Long getLastModified(Bitstream bitstream) {
|
||||
@Nullable
|
||||
@Override
|
||||
public Long getLastModified(Bitstream bitstream) throws IOException {
|
||||
return bitstreamStorageService.getLastModified(bitstream);
|
||||
}
|
||||
}
|
||||
|
@@ -88,7 +88,7 @@ public class Bundle extends DSpaceObject implements DSpaceObjectLegacySupport {
|
||||
*/
|
||||
@Override
|
||||
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
|
||||
*/
|
||||
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;
|
||||
|
||||
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.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
@@ -268,6 +272,81 @@ public class BundleServiceImpl extends DSpaceObjectServiceImpl<Bundle> implement
|
||||
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
|
||||
public void setOrder(Context context, Bundle bundle, UUID[] bitstreamIds) throws AuthorizeException, SQLException {
|
||||
authorizeService.authorizeAction(context, bundle, Constants.WRITE);
|
||||
|
@@ -71,23 +71,6 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
|
||||
@JoinColumn(name = "template_item_id")
|
||||
private Item template;
|
||||
|
||||
/**
|
||||
* Groups corresponding to workflow steps - NOTE these start from one, so
|
||||
* workflowGroups[0] corresponds to workflow_step_1.
|
||||
*/
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "workflow_step_1")
|
||||
private Group workflowStep1;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "workflow_step_2")
|
||||
private Group workflowStep2;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "workflow_step_3")
|
||||
private Group workflowStep3;
|
||||
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "submitter")
|
||||
/** The default group of administrators */
|
||||
@@ -134,7 +117,7 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
|
||||
@Override
|
||||
public String getName() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -202,31 +185,22 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
|
||||
setModified();
|
||||
}
|
||||
|
||||
public Group getWorkflowStep1() {
|
||||
return workflowStep1;
|
||||
// FIXME this should be moved to the collectionService or completely removed, see also
|
||||
// https://jira.duraspace.org/browse/DS-3041
|
||||
public Group getWorkflowStep1(Context context) {
|
||||
return getCollectionService().getWorkflowGroup(context, this, 1);
|
||||
}
|
||||
|
||||
public Group getWorkflowStep2() {
|
||||
return workflowStep2;
|
||||
// FIXME this should be moved to the collectionService or completely removed, see also
|
||||
// https://jira.duraspace.org/browse/DS-3041
|
||||
public Group getWorkflowStep2(Context context) {
|
||||
return getCollectionService().getWorkflowGroup(context, this, 2);
|
||||
}
|
||||
|
||||
public Group getWorkflowStep3() {
|
||||
return workflowStep3;
|
||||
}
|
||||
|
||||
void setWorkflowStep1(Group workflowStep1) {
|
||||
this.workflowStep1 = workflowStep1;
|
||||
setModified();
|
||||
}
|
||||
|
||||
void setWorkflowStep2(Group workflowStep2) {
|
||||
this.workflowStep2 = workflowStep2;
|
||||
setModified();
|
||||
}
|
||||
|
||||
void setWorkflowStep3(Group workflowStep3) {
|
||||
this.workflowStep3 = workflowStep3;
|
||||
setModified();
|
||||
// FIXME this should be moved to the collectionService or completely removed, see also
|
||||
// https://jira.duraspace.org/browse/DS-3041
|
||||
public Group getWorkflowStep3(Context context) {
|
||||
return getCollectionService().getWorkflowGroup(context, this, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,4 +327,5 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
|
||||
}
|
||||
return collectionService;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -17,11 +17,13 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
import org.dspace.app.util.AuthorizeUtil;
|
||||
import org.dspace.authorize.AuthorizeConfiguration;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
@@ -40,6 +42,13 @@ import org.dspace.core.Context;
|
||||
import org.dspace.core.I18nUtil;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.core.service.LicenseService;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.eperson.service.SubscribeService;
|
||||
@@ -47,6 +56,12 @@ import org.dspace.event.Event;
|
||||
import org.dspace.harvest.HarvestedCollection;
|
||||
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.XmlWorkflowFactoryImpl;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.storedcomponents.CollectionRole;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
@@ -88,6 +103,14 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
@Autowired(required = true)
|
||||
protected HarvestedCollectionService harvestedCollectionService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected XmlWorkflowFactory workflowFactory;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected CollectionRoleService collectionRoleService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected SearchService searchService;
|
||||
|
||||
protected CollectionServiceImpl() {
|
||||
super();
|
||||
@@ -143,10 +166,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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);
|
||||
@@ -154,10 +178,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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);
|
||||
@@ -338,91 +363,95 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
// Check authorisation - Must be an Admin to create Workflow Group
|
||||
AuthorizeUtil.authorizeManageWorkflowsGroup(context, collection);
|
||||
|
||||
if (getWorkflowGroup(collection, step) == null) {
|
||||
if (getWorkflowGroup(context, collection, step) == null) {
|
||||
//turn off authorization so that Collection Admins can create Collection Workflow Groups
|
||||
context.turnOffAuthorisationSystem();
|
||||
Group g = groupService.create(context);
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
groupService.setName(g,
|
||||
"COLLECTION_" + collection.getID() + "_WORKFLOW_STEP_" + step);
|
||||
groupService.update(context, g);
|
||||
context.restoreAuthSystemState();
|
||||
setWorkflowGroup(context, collection, step, g);
|
||||
|
||||
}
|
||||
|
||||
return getWorkflowGroup(collection, step);
|
||||
return getWorkflowGroup(context, collection, step);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorkflowGroup(Context context, Collection collection, int step, Group group)
|
||||
throws SQLException, AuthorizeException {
|
||||
// we need to store the old group to be able to revoke permissions if granted before
|
||||
Group oldGroup = null;
|
||||
int action;
|
||||
throws SQLException {
|
||||
Workflow workflow = null;
|
||||
try {
|
||||
workflow = workflowFactory.getWorkflow(collection);
|
||||
} catch (WorkflowConfigurationException e) {
|
||||
log.error(LogManager.getHeader(context, "setWorkflowGroup",
|
||||
"collection_id=" + collection.getID() + " " + e.getMessage()), e);
|
||||
}
|
||||
if (!StringUtils.equals(XmlWorkflowFactoryImpl.LEGACY_WORKFLOW_NAME, workflow.getID())) {
|
||||
throw new IllegalArgumentException(
|
||||
"setWorkflowGroup can be used only on collection with the default basic dspace workflow. "
|
||||
+ "Instead, the collection: "
|
||||
+ collection.getID() + " has the workflow: " + workflow.getID());
|
||||
}
|
||||
String roleId;
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
oldGroup = collection.getWorkflowStep1();
|
||||
action = Constants.WORKFLOW_STEP_1;
|
||||
collection.setWorkflowStep1(group);
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP1_NAME;
|
||||
break;
|
||||
case 2:
|
||||
oldGroup = collection.getWorkflowStep2();
|
||||
action = Constants.WORKFLOW_STEP_2;
|
||||
collection.setWorkflowStep2(group);
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP2_NAME;
|
||||
break;
|
||||
case 3:
|
||||
oldGroup = collection.getWorkflowStep3();
|
||||
action = Constants.WORKFLOW_STEP_3;
|
||||
collection.setWorkflowStep3(group);
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP3_NAME;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal step count: " + step);
|
||||
}
|
||||
|
||||
// deal with permissions.
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
// remove the policies for the old group
|
||||
if (oldGroup != null) {
|
||||
Iterator<ResourcePolicy> oldPolicies =
|
||||
resourcePolicyService.find(context, collection, oldGroup, action).iterator();
|
||||
while (oldPolicies.hasNext()) {
|
||||
resourcePolicyService.delete(context, oldPolicies.next());
|
||||
}
|
||||
oldPolicies = resourcePolicyService.find(context, collection, oldGroup, Constants.ADD).iterator();
|
||||
while (oldPolicies.hasNext()) {
|
||||
ResourcePolicy rp = oldPolicies.next();
|
||||
if (rp.getRpType() == ResourcePolicy.TYPE_WORKFLOW) {
|
||||
resourcePolicyService.delete(context, rp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// group can be null to delete workflow step.
|
||||
// we need to grant permissions if group is not null
|
||||
CollectionRole colRole = collectionRoleService.find(context, collection, roleId);
|
||||
if (colRole == null) {
|
||||
if (group != null) {
|
||||
authorizeService.addPolicy(context, collection, action, group, ResourcePolicy.TYPE_WORKFLOW);
|
||||
authorizeService.addPolicy(context, collection, Constants.ADD, group, ResourcePolicy.TYPE_WORKFLOW);
|
||||
colRole = collectionRoleService.create(context, collection, roleId, group);
|
||||
}
|
||||
} else {
|
||||
if (group != null) {
|
||||
colRole.setGroup(group);
|
||||
collectionRoleService.update(context, colRole);
|
||||
} else {
|
||||
collectionRoleService.delete(context, colRole);
|
||||
}
|
||||
} finally {
|
||||
context.restoreAuthSystemState();
|
||||
}
|
||||
collection.setModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getWorkflowGroup(Collection collection, int step) {
|
||||
public Group getWorkflowGroup(Context context, Collection collection, int step) {
|
||||
String roleId;
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
return collection.getWorkflowStep1();
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP1_NAME;
|
||||
break;
|
||||
case 2:
|
||||
return collection.getWorkflowStep2();
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP2_NAME;
|
||||
break;
|
||||
case 3:
|
||||
return collection.getWorkflowStep3();
|
||||
roleId = CollectionRoleService.LEGACY_WORKFLOW_STEP3_NAME;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Illegal step count: " + step);
|
||||
throw new IllegalArgumentException("Illegal step count: " + step);
|
||||
}
|
||||
|
||||
CollectionRole colRole;
|
||||
try {
|
||||
colRole = collectionRoleService.find(context, collection, roleId);
|
||||
if (colRole != null) {
|
||||
return colRole.getGroup();
|
||||
}
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,29 +762,13 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
// Remove any Handle
|
||||
handleService.unbindHandle(context, collection);
|
||||
|
||||
// Remove any workflow groups - must happen after deleting collection
|
||||
Group g = collection.getWorkflowStep1();
|
||||
if (g != null) {
|
||||
collection.setWorkflowStep1(null);
|
||||
groupService.delete(context, g);
|
||||
}
|
||||
// Remove any workflow roles
|
||||
collectionRoleService.deleteByCollection(context, collection);
|
||||
|
||||
g = collection.getWorkflowStep2();
|
||||
|
||||
if (g != null) {
|
||||
collection.setWorkflowStep2(null);
|
||||
groupService.delete(context, g);
|
||||
}
|
||||
|
||||
g = collection.getWorkflowStep3();
|
||||
|
||||
if (g != null) {
|
||||
collection.setWorkflowStep3(null);
|
||||
groupService.delete(context, g);
|
||||
}
|
||||
collection.getResourcePolicies().clear();
|
||||
|
||||
// Remove default administrators group
|
||||
g = collection.getAdministrators();
|
||||
Group g = collection.getAdministrators();
|
||||
|
||||
if (g != null) {
|
||||
collection.setAdmins(null);
|
||||
@@ -888,4 +901,95 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
throws SQLException {
|
||||
return collectionDAO.getCollectionsWithBitstreamSizesTotal(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group createDefaultReadGroup(Context context, Collection collection, String typeOfGroupString,
|
||||
int defaultRead)
|
||||
throws SQLException, AuthorizeException {
|
||||
Group role = groupService.create(context);
|
||||
groupService.setName(role, "COLLECTION_" + collection.getID().toString() + "_" + typeOfGroupString +
|
||||
"_DEFAULT_READ");
|
||||
|
||||
// Remove existing privileges from the anonymous group.
|
||||
authorizeService.removePoliciesActionFilter(context, collection, defaultRead);
|
||||
|
||||
// Grant our new role the default privileges.
|
||||
authorizeService.addPolicy(context, collection, defaultRead, role);
|
||||
groupService.update(context, role);
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Collection> findCollectionsWithSubmit(String q, Context context, Community community,
|
||||
int offset, int limit) throws SQLException, SearchServiceException {
|
||||
|
||||
List<Collection> collections = new ArrayList<Collection>();
|
||||
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||
discoverQuery.setStart(offset);
|
||||
discoverQuery.setMaxResults(limit);
|
||||
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community, q);
|
||||
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
||||
Collection c = ((IndexableCollection) solrCollections).getIndexedObject();
|
||||
collections.add(c);
|
||||
}
|
||||
return collections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countCollectionsWithSubmit(String q, Context context, Community community)
|
||||
throws SQLException, SearchServiceException {
|
||||
|
||||
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||
discoverQuery.setMaxResults(0);
|
||||
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community,q);
|
||||
return (int)resp.getTotalSearchResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all Indexed Collections where the current user has submit rights. If the user is an Admin,
|
||||
* this is all Indexed Collections. Otherwise, it includes those collections where
|
||||
* an indexed "submit" policy lists either the eperson or one of the eperson's groups
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param discoverQuery
|
||||
* @param community parent community, could be null
|
||||
* @param q limit the returned collection to those with metadata values matching the query
|
||||
* terms. The terms are used to make also a prefix query on SOLR
|
||||
* so it can be used to implement an autosuggest feature over the collection name
|
||||
* @return discovery search result objects
|
||||
* @throws SQLException if something goes wrong
|
||||
* @throws SearchServiceException if search error
|
||||
*/
|
||||
private DiscoverResult retrieveCollectionsWithSubmit(Context context, DiscoverQuery discoverQuery,
|
||||
Community community, String q) throws SQLException, SearchServiceException {
|
||||
|
||||
StringBuilder query = new StringBuilder();
|
||||
EPerson currentUser = context.getCurrentUser();
|
||||
if (!authorizeService.isAdmin(context)) {
|
||||
String userId = "";
|
||||
if (currentUser != null) {
|
||||
userId = currentUser.getID().toString();
|
||||
}
|
||||
query.append("submit:(e").append(userId);
|
||||
Set<Group> groups = groupService.allMemberGroupsSet(context, currentUser);
|
||||
for (Group group : groups) {
|
||||
query.append(" OR g").append(group.getID());
|
||||
}
|
||||
query.append(")");
|
||||
discoverQuery.addFilterQueries(query.toString());
|
||||
}
|
||||
if (community != null) {
|
||||
discoverQuery.addFilterQueries("location.comm:" + community.getID().toString());
|
||||
}
|
||||
if (StringUtils.isNotBlank(q)) {
|
||||
StringBuilder buildQuery = new StringBuilder();
|
||||
String escapedQuery = ClientUtils.escapeQueryChars(q);
|
||||
buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*");
|
||||
discoverQuery.setQuery(buildQuery.toString());
|
||||
}
|
||||
DiscoverResult resp = searchService.search(context, discoverQuery);
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ public class Community extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
setModified();
|
||||
}
|
||||
|
||||
void removeSubCommunity(Community subCommunity) {
|
||||
public void removeSubCommunity(Community subCommunity) {
|
||||
subCommunities.remove(subCommunity);
|
||||
setModified();
|
||||
}
|
||||
@@ -254,7 +254,7 @@ public class Community extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
@Override
|
||||
public String getName() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -269,4 +269,5 @@ public class Community extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
}
|
||||
return communityService;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -139,10 +139,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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);
|
||||
@@ -150,10 +151,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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);
|
||||
@@ -162,10 +164,11 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
@Override
|
||||
public List<Community> findAllTop(Context context) throws SQLException {
|
||||
// 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) {
|
||||
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);
|
||||
@@ -508,7 +511,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
return Constants.COMMUNITY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal method to remove the community and all its children from the
|
||||
* database, and perform any pre/post-cleanup
|
||||
|
@@ -10,8 +10,10 @@ package org.dspace.content;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.MetadataFieldService;
|
||||
import org.dspace.content.service.MetadataValueService;
|
||||
import org.dspace.content.service.RelationshipService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
@@ -60,6 +63,8 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
protected MetadataFieldService metadataFieldService;
|
||||
@Autowired(required = true)
|
||||
protected MetadataAuthorityService metadataAuthorityService;
|
||||
@Autowired(required = true)
|
||||
protected RelationshipService relationshipService;
|
||||
|
||||
public DSpaceObjectServiceImpl() {
|
||||
|
||||
@@ -67,7 +72,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -231,15 +236,26 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
|
||||
@Override
|
||||
public void addMetadata(Context context, T dso, MetadataField metadataField, String lang, List<String> values,
|
||||
List<String> authorities, List<Integer> confidences) throws SQLException {
|
||||
List<String> authorities, List<Integer> confidences)
|
||||
throws SQLException {
|
||||
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
|
||||
boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField);
|
||||
|
||||
// We will not verify that they are valid entries in the registry
|
||||
// until update() is called.
|
||||
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);
|
||||
//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());
|
||||
|
||||
// Logic to set Authority and Confidence:
|
||||
@@ -542,11 +558,50 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
*/
|
||||
// A map created to store the latest place for each metadata field
|
||||
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) {
|
||||
//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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -556,7 +611,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
*
|
||||
* @param fieldToLastPlace the map containing the latest place of each metadata field
|
||||
* @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) {
|
||||
MetadataField metadataField = metadataValue.getMetadataField();
|
||||
@@ -572,23 +627,23 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
protected String[] getMDValueByLegacyField(String field) {
|
||||
switch (field) {
|
||||
case "introductory_text":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "description", null};
|
||||
case "short_description":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", "abstract"};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "description", "abstract"};
|
||||
case "side_bar_text":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "description", "tableofcontents"};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "description", "tableofcontents"};
|
||||
case "copyright_text":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "rights", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "rights", null};
|
||||
case "name":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "title", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "title", null};
|
||||
case "provenance_description":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "provenance", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "provenance", null};
|
||||
case "license":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "rights", "license"};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "rights", "license"};
|
||||
case "user_format_description":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "format", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "format", null};
|
||||
case "source":
|
||||
return new String[] {MetadataSchema.DC_SCHEMA, "source", null};
|
||||
return new String[] {MetadataSchemaEnum.DC.getName(), "source", null};
|
||||
case "firstname":
|
||||
return new String[] {"eperson", "firstname", null};
|
||||
case "lastname":
|
||||
@@ -639,9 +694,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
|
||||
List<MetadataValue> list = getMetadata(dso, schema, element, qualifier);
|
||||
|
||||
if (from >= list.size()) {
|
||||
if (from >= list.size() || to >= list.size() || to < 0 || from < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"The \"from\" location MUST exist for the operation to be successful. Idx:" + from);
|
||||
"The \"from\" and \"to\" locations MUST exist for the operation to be successful." +
|
||||
"\n To and from indices must be between 0 and " + (list.size() - 1) +
|
||||
"\n Idx from:" + from + " Idx to: " + to);
|
||||
}
|
||||
|
||||
clearMetadata(context, dso, schema, element, qualifier, Item.ANY);
|
||||
@@ -701,4 +758,10 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadataModified(T dso) {
|
||||
dso.setMetadataModified();
|
||||
}
|
||||
|
||||
}
|
||||
|
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, false);
|
||||
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);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user