mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-19 16:03:07 +00:00
Merge remote-tracking branch 'dspace/master' into w2p-65568_bugs-place-management-creating-relationships
Conflicts: dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java
This commit is contained in:
@@ -3,4 +3,9 @@
|
|||||||
.settings/
|
.settings/
|
||||||
*/target/
|
*/target/
|
||||||
dspace/modules/*/target/
|
dspace/modules/*/target/
|
||||||
Dockerfile.*
|
Dockerfile.*
|
||||||
|
dspace/src/main/docker/dspace-postgres-pgcrypto
|
||||||
|
dspace/src/main/docker/dspace-postgres-pgcrypto-curl
|
||||||
|
dspace/src/main/docker/solr
|
||||||
|
dspace/src/main/docker/README.md
|
||||||
|
dspace/src/main/docker-compose/
|
||||||
|
28
README.md
28
README.md
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
[](https://travis-ci.org/DSpace/DSpace)
|
[](https://travis-ci.org/DSpace/DSpace)
|
||||||
|
|
||||||
[DSpace Documentation](https://wiki.duraspace.org/display/DSDOC/) |
|
[DSpace Documentation](https://wiki.duraspace.org/display/DSDOC/) |
|
||||||
[DSpace Releases](https://github.com/DSpace/DSpace/releases) |
|
[DSpace Releases](https://github.com/DSpace/DSpace/releases) |
|
||||||
[DSpace Wiki](https://wiki.duraspace.org/display/DSPACE/Home) |
|
[DSpace Wiki](https://wiki.duraspace.org/display/DSPACE/Home) |
|
||||||
[Support](https://wiki.duraspace.org/display/DSPACE/Support)
|
[Support](https://wiki.duraspace.org/display/DSPACE/Support)
|
||||||
|
|
||||||
DSpace open source software is a turnkey repository application used by more than
|
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.
|
2,000 organizations and institutions worldwide to provide durable access to digital resources.
|
||||||
For more information, visit http://www.dspace.org/
|
For more information, visit http://www.dspace.org/
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ For more information, visit http://www.dspace.org/
|
|||||||
* DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-server-webapp) of this repository.
|
* DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-server-webapp) of this repository.
|
||||||
* The REST Contract is being documented at https://github.com/DSpace/Rest7Contract
|
* The REST Contract is being documented at https://github.com/DSpace/Rest7Contract
|
||||||
* DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular
|
* DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular
|
||||||
|
|
||||||
**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 UI Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+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.
|
**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,21 +31,21 @@ Past releases are all available via GitHub at https://github.com/DSpace/DSpace/r
|
|||||||
|
|
||||||
## Documentation / Installation
|
## 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.duraspace.org/display/DSDOC/).
|
||||||
|
|
||||||
The latest DSpace Installation instructions are available at:
|
The latest DSpace Installation instructions are available at:
|
||||||
https://wiki.duraspace.org/display/DSDOC6x/Installing+DSpace
|
https://wiki.duraspace.org/display/DSDOC6x/Installing+DSpace
|
||||||
|
|
||||||
Please be aware that, as a Java web application, DSpace requires a database (PostgreSQL or Oracle)
|
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.
|
and a servlet container (usually Tomcat) in order to function.
|
||||||
More information about these and all other prerequisites can be found in the Installation instructions above.
|
More information about these and all other prerequisites can be found in the Installation instructions above.
|
||||||
|
|
||||||
## Dockerfile Usage
|
## Running DSpace 7 in Docker
|
||||||
See the [DSpace Docker Tutorial](https://dspace-labs.github.io/DSpace-Docker-Images/).
|
See [Running DSpace 7 with Docker Compose](dspace/src/main/docker-compose/README.md)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
DSpace is a community built and supported project. We do not have a centralized development or support team,
|
DSpace is a community built and supported project. We do not have a centralized development or support team,
|
||||||
but have a dedicated group of volunteers who help us improve the software, documentation, resources, etc.
|
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:
|
We welcome contributions of any type. Here's a few basic guides that provide suggestions for contributing to DSpace:
|
||||||
@@ -71,8 +71,8 @@ Great Q&A is also available under the [DSpace tag on Stackoverflow](http://stack
|
|||||||
|
|
||||||
Additional support options are listed at https://wiki.duraspace.org/display/DSPACE/Support
|
Additional support options are listed at https://wiki.duraspace.org/display/DSPACE/Support
|
||||||
|
|
||||||
DSpace also has an active service provider network. If you'd rather hire a service provider to
|
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
|
install, upgrade, customize or host DSpace, then we recommend getting in touch with one of our
|
||||||
[Registered Service Providers](http://www.dspace.org/service-providers).
|
[Registered Service Providers](http://www.dspace.org/service-providers).
|
||||||
|
|
||||||
## Issue Tracker
|
## Issue Tracker
|
||||||
@@ -101,7 +101,7 @@ run automatically by [Travis CI](https://travis-ci.org/DSpace/DSpace/) for all P
|
|||||||
# Run all tests in a specific test class
|
# Run all tests in a specific test class
|
||||||
# NOTE: testClassName is just the class name, do not include package
|
# NOTE: testClassName is just the class name, do not include package
|
||||||
mvn clean test -Dmaven.test.skip=false -Dtest=[testClassName]
|
mvn clean test -Dmaven.test.skip=false -Dtest=[testClassName]
|
||||||
|
|
||||||
# Run one test method in a specific test class
|
# Run one test method in a specific test class
|
||||||
mvn clean test -Dmaven.test.skip=false -Dtest=[testClassName]#[testMethodName]
|
mvn clean test -Dmaven.test.skip=false -Dtest=[testClassName]#[testMethodName]
|
||||||
```
|
```
|
||||||
@@ -115,7 +115,7 @@ run automatically by [Travis CI](https://travis-ci.org/DSpace/DSpace/) for all P
|
|||||||
# NOTE: Integration Tests only run for "verify" or "install" phases
|
# NOTE: Integration Tests only run for "verify" or "install" phases
|
||||||
# NOTE: testClassName is just the class name, do not include package
|
# NOTE: testClassName is just the class name, do not include package
|
||||||
mvn clean verify -Dmaven.test.skip=false -DskipITs=false -Dit.test=[testClassName]
|
mvn clean verify -Dmaven.test.skip=false -DskipITs=false -Dit.test=[testClassName]
|
||||||
|
|
||||||
# Run one test method in a specific test class
|
# Run one test method in a specific test class
|
||||||
mvn clean verify -Dmaven.test.skip=false -DskipITs=false -Dit.test=[testClassName]#[testMethodName]
|
mvn clean verify -Dmaven.test.skip=false -DskipITs=false -Dit.test=[testClassName]#[testMethodName]
|
||||||
```
|
```
|
||||||
@@ -124,7 +124,7 @@ run automatically by [Travis CI](https://travis-ci.org/DSpace/DSpace/) for all P
|
|||||||
# Before you can run only one module's tests, other modules may need installing into your ~/.m2
|
# Before you can run only one module's tests, other modules may need installing into your ~/.m2
|
||||||
cd [dspace-src]
|
cd [dspace-src]
|
||||||
mvn clean install
|
mvn clean install
|
||||||
|
|
||||||
# Then, move into a module subdirectory, and run the test command
|
# Then, move into a module subdirectory, and run the test command
|
||||||
cd [dspace-src]/dspace-server-webapp
|
cd [dspace-src]/dspace-server-webapp
|
||||||
# Choose your test command from the lists above
|
# Choose your test command from the lists above
|
||||||
|
25
docker-compose-cli.yml
Normal file
25
docker-compose-cli.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
dspace-cli:
|
||||||
|
image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}"
|
||||||
|
container_name: dspace-cli
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.cli.jdk8
|
||||||
|
#environment:
|
||||||
|
volumes:
|
||||||
|
- ./dspace/src/main/docker-compose/local.cfg:/dspace/config/local.cfg
|
||||||
|
- assetstore:/dspace/assetstore
|
||||||
|
entrypoint: /dspace/bin/dspace
|
||||||
|
command: help
|
||||||
|
networks:
|
||||||
|
- dspacenet
|
||||||
|
tty: true
|
||||||
|
stdin_open: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
assetstore:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
62
docker-compose.yml
Normal file
62
docker-compose.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
version: '3.7'
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
services:
|
||||||
|
dspace:
|
||||||
|
container_name: dspace
|
||||||
|
image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-jdk8-test}"
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.jdk8-test
|
||||||
|
depends_on:
|
||||||
|
- dspacedb
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
ports:
|
||||||
|
- published: 8080
|
||||||
|
target: 8080
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- assetstore:/dspace/assetstore
|
||||||
|
- ./dspace/src/main/docker-compose/local.cfg:/dspace/config/local.cfg
|
||||||
|
# Ensure that the database is ready before starting tomcat
|
||||||
|
entrypoint:
|
||||||
|
- /bin/bash
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
/dspace/bin/dspace database migrate
|
||||||
|
catalina.sh run
|
||||||
|
dspacedb:
|
||||||
|
container_name: dspacedb
|
||||||
|
environment:
|
||||||
|
PGDATA: /pgdata
|
||||||
|
image: dspace/dspace-postgres-pgcrypto
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- pgdata:/pgdata
|
||||||
|
dspacesolr:
|
||||||
|
container_name: dspacesolr
|
||||||
|
image: dspace/dspace-solr
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
ports:
|
||||||
|
- published: 8983
|
||||||
|
target: 8983
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- solr_authority:/opt/solr/server/solr/authority/data
|
||||||
|
- solr_oai:/opt/solr/server/solr/oai/data
|
||||||
|
- solr_search:/opt/solr/server/solr/search/data
|
||||||
|
- solr_statistics:/opt/solr/server/solr/statistics/data
|
||||||
|
volumes:
|
||||||
|
assetstore:
|
||||||
|
pgdata:
|
||||||
|
solr_authority:
|
||||||
|
solr_oai:
|
||||||
|
solr_search:
|
||||||
|
solr_statistics:
|
@@ -666,7 +666,7 @@ public class MetadataImport {
|
|||||||
|
|
||||||
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName())) {
|
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName())) {
|
||||||
List<RelationshipType> relationshipTypeList = relationshipTypeService
|
List<RelationshipType> relationshipTypeList = relationshipTypeService
|
||||||
.findByLeftOrRightLabel(c, element);
|
.findByLeftwardOrRightwardTypeName(c, element);
|
||||||
for (RelationshipType relationshipType : relationshipTypeList) {
|
for (RelationshipType relationshipType : relationshipTypeList) {
|
||||||
for (Relationship relationship : relationshipService
|
for (Relationship relationship : relationshipService
|
||||||
.findByItemAndRelationshipType(c, item, relationshipType)) {
|
.findByItemAndRelationshipType(c, item, relationshipType)) {
|
||||||
@@ -762,17 +762,22 @@ public class MetadataImport {
|
|||||||
List<RelationshipType> leftRelationshipTypesForEntity = entityService.getLeftRelationshipTypes(c, entity);
|
List<RelationshipType> leftRelationshipTypesForEntity = entityService.getLeftRelationshipTypes(c, entity);
|
||||||
List<RelationshipType> rightRelationshipTypesForEntity = entityService.getRightRelationshipTypes(c, entity);
|
List<RelationshipType> rightRelationshipTypesForEntity = entityService.getRightRelationshipTypes(c, entity);
|
||||||
|
|
||||||
|
//Identify which RelationshipType objects match the combination of:
|
||||||
|
// * the left entity type
|
||||||
|
// * the right entity type
|
||||||
|
// * the name of the relationship type (based on the expected direction of the relationship)
|
||||||
|
//The matches are included in the acceptableRelationshipTypes
|
||||||
for (RelationshipType relationshipType : entityService.getAllRelationshipTypes(c, entity)) {
|
for (RelationshipType relationshipType : entityService.getAllRelationshipTypes(c, entity)) {
|
||||||
if (StringUtils.equalsIgnoreCase(relationshipType.getLeftLabel(), element)) {
|
if (StringUtils.equalsIgnoreCase(relationshipType.getLeftwardType(), element)) {
|
||||||
left = handleLeftLabelEqualityRelationshipTypeElement(c, entity, relationEntity, left,
|
left = verifyValidLeftwardRelationshipType(c, entity, relationEntity, left,
|
||||||
acceptableRelationshipTypes,
|
acceptableRelationshipTypes,
|
||||||
leftRelationshipTypesForEntity,
|
leftRelationshipTypesForEntity,
|
||||||
relationshipType);
|
relationshipType);
|
||||||
} else if (StringUtils.equalsIgnoreCase(relationshipType.getRightLabel(), element)) {
|
} else if (StringUtils.equalsIgnoreCase(relationshipType.getRightwardType(), element)) {
|
||||||
left = handleRightLabelEqualityRelationshipTypeElement(c, entity, relationEntity, left,
|
left = verifyValidRightwardRelationshipType(c, entity, relationEntity, left,
|
||||||
acceptableRelationshipTypes,
|
acceptableRelationshipTypes,
|
||||||
rightRelationshipTypesForEntity,
|
rightRelationshipTypesForEntity,
|
||||||
relationshipType);
|
relationshipType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,16 +837,20 @@ public class MetadataImport {
|
|||||||
* for the right entity
|
* for the right entity
|
||||||
* @param relationshipType The RelationshipType object that we want to check whether it's
|
* @param relationshipType The RelationshipType object that we want to check whether it's
|
||||||
* valid to be added or not
|
* valid to be added or not
|
||||||
* @return A boolean indicating whether the relationship is left or right, will
|
* @return A boolean indicating whether the relationship is left or right.
|
||||||
* be false in this case
|
* Will be set to false if the relationship is valid.
|
||||||
|
* Will remain unmodified from the left parameter if the
|
||||||
|
* relationship is not valid.
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
private boolean handleRightLabelEqualityRelationshipTypeElement(Context c, Entity entity, Entity relationEntity,
|
private boolean verifyValidRightwardRelationshipType(Context c, Entity entity,
|
||||||
boolean left,
|
Entity relationEntity,
|
||||||
List<RelationshipType> acceptableRelationshipTypes,
|
boolean left,
|
||||||
List<RelationshipType>
|
List<RelationshipType>
|
||||||
rightRelationshipTypesForEntity,
|
acceptableRelationshipTypes,
|
||||||
RelationshipType relationshipType)
|
List<RelationshipType>
|
||||||
|
rightRelationshipTypesForEntity,
|
||||||
|
RelationshipType relationshipType)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
||||||
relationshipType.getRightType().getLabel()) &&
|
relationshipType.getRightType().getLabel()) &&
|
||||||
@@ -874,16 +883,20 @@ public class MetadataImport {
|
|||||||
* for the left entity
|
* for the left entity
|
||||||
* @param relationshipType The RelationshipType object that we want to check whether it's
|
* @param relationshipType The RelationshipType object that we want to check whether it's
|
||||||
* valid to be added or not
|
* valid to be added or not
|
||||||
* @return A boolean indicating whether the relationship is left or right, will
|
* @return A boolean indicating whether the relationship is left or right.
|
||||||
* be true in this case
|
* Will be set to true if the relationship is valid.
|
||||||
|
* Will remain unmodified from the left parameter if the
|
||||||
|
* relationship is not valid.
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
private boolean handleLeftLabelEqualityRelationshipTypeElement(Context c, Entity entity, Entity relationEntity,
|
private boolean verifyValidLeftwardRelationshipType(Context c, Entity entity,
|
||||||
boolean left,
|
Entity relationEntity,
|
||||||
List<RelationshipType> acceptableRelationshipTypes,
|
boolean left,
|
||||||
List<RelationshipType>
|
List<RelationshipType>
|
||||||
leftRelationshipTypesForEntity,
|
acceptableRelationshipTypes,
|
||||||
RelationshipType relationshipType)
|
List<RelationshipType>
|
||||||
|
leftRelationshipTypesForEntity,
|
||||||
|
RelationshipType relationshipType)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
||||||
relationshipType.getLeftType().getLabel()) &&
|
relationshipType.getLeftType().getLabel()) &&
|
||||||
|
@@ -272,9 +272,8 @@ public class Harvest {
|
|||||||
targetCollection = (Collection) dso;
|
targetCollection = (Collection) dso;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not a handle, try and treat it as an integer collection database ID
|
// not a handle, try and treat it as an collection database UUID
|
||||||
System.out.println("Looking up by id: " + collectionID + ", parsed as '" + Integer
|
System.out.println("Looking up by UUID: " + collectionID + ", " + "in context: " + context);
|
||||||
.parseInt(collectionID) + "', " + "in context: " + context);
|
|
||||||
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,7 +459,7 @@ public class Harvest {
|
|||||||
List<String> errors;
|
List<String> errors;
|
||||||
|
|
||||||
System.out.print("Testing basic PMH access: ");
|
System.out.print("Testing basic PMH access: ");
|
||||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||||
(null != metadataFormat) ? metadataFormat : "dc", false);
|
(null != metadataFormat) ? metadataFormat : "dc", false);
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
System.out.println("OK");
|
System.out.println("OK");
|
||||||
@@ -471,7 +470,7 @@ public class Harvest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.out.print("Testing ORE support: ");
|
System.out.print("Testing ORE support: ");
|
||||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||||
(null != metadataFormat) ? metadataFormat : "dc", true);
|
(null != metadataFormat) ? metadataFormat : "dc", true);
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
System.out.println("OK");
|
System.out.println("OK");
|
||||||
|
@@ -128,8 +128,8 @@ public class InitializeEntities {
|
|||||||
|
|
||||||
String leftType = eElement.getElementsByTagName("leftType").item(0).getTextContent();
|
String leftType = eElement.getElementsByTagName("leftType").item(0).getTextContent();
|
||||||
String rightType = eElement.getElementsByTagName("rightType").item(0).getTextContent();
|
String rightType = eElement.getElementsByTagName("rightType").item(0).getTextContent();
|
||||||
String leftLabel = eElement.getElementsByTagName("leftLabel").item(0).getTextContent();
|
String leftwardType = eElement.getElementsByTagName("leftwardType").item(0).getTextContent();
|
||||||
String rightLabel = eElement.getElementsByTagName("rightLabel").item(0).getTextContent();
|
String rightwardType = eElement.getElementsByTagName("rightwardType").item(0).getTextContent();
|
||||||
|
|
||||||
|
|
||||||
NodeList leftCardinalityList = eElement.getElementsByTagName("leftCardinality");
|
NodeList leftCardinalityList = eElement.getElementsByTagName("leftCardinality");
|
||||||
@@ -154,7 +154,7 @@ public class InitializeEntities {
|
|||||||
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
||||||
|
|
||||||
}
|
}
|
||||||
populateRelationshipType(context, leftType, rightType, leftLabel, rightLabel,
|
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
||||||
leftCardinalityMin, leftCardinalityMax,
|
leftCardinalityMin, leftCardinalityMax,
|
||||||
rightCardinalityMin, rightCardinalityMax);
|
rightCardinalityMin, rightCardinalityMax);
|
||||||
|
|
||||||
@@ -173,8 +173,8 @@ public class InitializeEntities {
|
|||||||
return leftCardinalityMin;
|
return leftCardinalityMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateRelationshipType(Context context, String leftType, String rightType, String leftLabel,
|
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
||||||
String rightLabel, String leftCardinalityMin, String leftCardinalityMax,
|
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||||
String rightCardinalityMin, String rightCardinalityMax)
|
String rightCardinalityMin, String rightCardinalityMax)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
|
|
||||||
@@ -211,9 +211,9 @@ public class InitializeEntities {
|
|||||||
rightCardinalityMaxInteger = null;
|
rightCardinalityMaxInteger = null;
|
||||||
}
|
}
|
||||||
RelationshipType relationshipType = relationshipTypeService
|
RelationshipType relationshipType = relationshipTypeService
|
||||||
.findbyTypesAndLabels(context, leftEntityType, rightEntityType, leftLabel, rightLabel);
|
.findbyTypesAndLabels(context, leftEntityType, rightEntityType, leftwardType, rightwardType);
|
||||||
if (relationshipType == null) {
|
if (relationshipType == null) {
|
||||||
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftLabel, rightLabel,
|
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftwardType, rightwardType,
|
||||||
leftCardinalityMinInteger, leftCardinalityMaxInteger,
|
leftCardinalityMinInteger, leftCardinalityMaxInteger,
|
||||||
rightCardinalityMinInteger, rightCardinalityMaxInteger);
|
rightCardinalityMinInteger, rightCardinalityMaxInteger);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
package org.dspace.content;
|
package org.dspace.content;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -83,8 +84,8 @@ public class EntityServiceImpl implements EntityService {
|
|||||||
List<Relationship> relationshipList = relationshipService.findAll(context);
|
List<Relationship> relationshipList = relationshipService.findAll(context);
|
||||||
for (Relationship relationship : relationshipList) {
|
for (Relationship relationship : relationshipList) {
|
||||||
RelationshipType relationshipType = relationship.getRelationshipType();
|
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||||
if (StringUtils.equals(relationshipType.getLeftLabel(),label) ||
|
if (StringUtils.equals(relationshipType.getLeftwardType(),label) ||
|
||||||
StringUtils.equals(relationshipType.getRightLabel(),label)) {
|
StringUtils.equals(relationshipType.getRightwardType(),label)) {
|
||||||
listToReturn.add(relationship);
|
listToReturn.add(relationship);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +95,9 @@ public class EntityServiceImpl implements EntityService {
|
|||||||
@Override
|
@Override
|
||||||
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity) throws SQLException {
|
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||||
EntityType entityType = this.getType(context, entity);
|
EntityType entityType = this.getType(context, entity);
|
||||||
|
if (entityType == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||||
if (relationshipType.getLeftType().getID() == entityType.getID() ||
|
if (relationshipType.getLeftType().getID() == entityType.getID() ||
|
||||||
@@ -129,11 +133,11 @@ public class EntityServiceImpl implements EntityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RelationshipType> getRelationshipTypesByLabel(Context context, String label) throws SQLException {
|
public List<RelationshipType> getRelationshipTypesByTypeName(Context context, String label) throws SQLException {
|
||||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||||
if (StringUtils.equals(relationshipType.getLeftLabel(),label) ||
|
if (StringUtils.equals(relationshipType.getLeftwardType(),label) ||
|
||||||
StringUtils.equals(relationshipType.getRightLabel(),label)) {
|
StringUtils.equals(relationshipType.getRightwardType(),label)) {
|
||||||
listToReturn.add(relationshipType);
|
listToReturn.add(relationshipType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,11 +13,9 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -44,7 +42,6 @@ import org.dspace.content.service.ItemService;
|
|||||||
import org.dspace.content.service.MetadataSchemaService;
|
import org.dspace.content.service.MetadataSchemaService;
|
||||||
import org.dspace.content.service.RelationshipService;
|
import org.dspace.content.service.RelationshipService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
import org.dspace.content.virtual.VirtualMetadataConfiguration;
|
|
||||||
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -117,6 +114,9 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private RelationshipMetadataService relationshipMetadataService;
|
||||||
|
|
||||||
protected ItemServiceImpl() {
|
protected ItemServiceImpl() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -1344,27 +1344,6 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
return this.getMetadata(item, schema, element, qualifier, lang, true);
|
return this.getMetadata(item, schema, element, qualifier, lang, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata) {
|
|
||||||
Context context = new Context();
|
|
||||||
List<RelationshipMetadataValue> fullMetadataValueList = new LinkedList<>();
|
|
||||||
try {
|
|
||||||
List<MetadataValue> list = item.getMetadata();
|
|
||||||
String entityType = getEntityTypeStringFromMetadata(list);
|
|
||||||
if (StringUtils.isNotBlank(entityType)) {
|
|
||||||
List<Relationship> relationships = relationshipService.findByItem(context, item);
|
|
||||||
for (Relationship relationship : relationships) {
|
|
||||||
fullMetadataValueList
|
|
||||||
.addAll(handleItemRelationship(context, item, entityType, relationship, enableVirtualMetadata));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Lookup for Relationships for item with uuid: " + item.getID() + " caused DSpace to crash", e);
|
|
||||||
}
|
|
||||||
return fullMetadataValueList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
|
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
|
||||||
boolean enableVirtualMetadata) {
|
boolean enableVirtualMetadata) {
|
||||||
@@ -1372,7 +1351,8 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
//except for relation.type which is the type of item in the model
|
//except for relation.type which is the type of item in the model
|
||||||
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) {
|
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) {
|
||||||
|
|
||||||
List<RelationshipMetadataValue> relationMetadata = getRelationshipMetadata(item, false);
|
List<RelationshipMetadataValue> relationMetadata = relationshipMetadataService
|
||||||
|
.getRelationshipMetadata(item, false);
|
||||||
List<MetadataValue> listToReturn = new LinkedList<>();
|
List<MetadataValue> listToReturn = new LinkedList<>();
|
||||||
for (MetadataValue metadataValue : relationMetadata) {
|
for (MetadataValue metadataValue : relationMetadata) {
|
||||||
if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) {
|
if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) {
|
||||||
@@ -1388,7 +1368,7 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
|
|
||||||
List<MetadataValue> fullMetadataValueList = new LinkedList<>();
|
List<MetadataValue> fullMetadataValueList = new LinkedList<>();
|
||||||
if (enableVirtualMetadata) {
|
if (enableVirtualMetadata) {
|
||||||
fullMetadataValueList.addAll(getRelationshipMetadata(item, true));
|
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
|
||||||
|
|
||||||
}
|
}
|
||||||
fullMetadataValueList.addAll(dbMetadataValues);
|
fullMetadataValueList.addAll(dbMetadataValues);
|
||||||
@@ -1409,7 +1389,7 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
* This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element,
|
* This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element,
|
||||||
* MetadataField Qualifier and MetadataField Place in that order.
|
* MetadataField Qualifier and MetadataField Place in that order.
|
||||||
* @param listToReturn The list to be sorted
|
* @param listToReturn The list to be sorted
|
||||||
* @return The list sorted on those criteria
|
* @return The list sorted on those criteria
|
||||||
*/
|
*/
|
||||||
private List<MetadataValue> sortMetadataValueList(List<MetadataValue> listToReturn) {
|
private List<MetadataValue> sortMetadataValueList(List<MetadataValue> listToReturn) {
|
||||||
Comparator<MetadataValue> comparator = Comparator.comparing(
|
Comparator<MetadataValue> comparator = Comparator.comparing(
|
||||||
@@ -1427,137 +1407,5 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
return listToReturn;
|
return listToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This method processes the Relationship of an Item and will return a list of RelationshipMetadataValue objects
|
|
||||||
//that are generated for this specfic relationship for the item through the config in VirtualMetadataPopulator
|
|
||||||
private List<RelationshipMetadataValue> handleItemRelationship(Context context, Item item, String entityType,
|
|
||||||
Relationship relationship,
|
|
||||||
boolean enableVirtualMetadata)
|
|
||||||
throws SQLException {
|
|
||||||
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
|
||||||
RelationshipType relationshipType = relationship.getRelationshipType();
|
|
||||||
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
|
||||||
String relationName = "";
|
|
||||||
Item otherItem = null;
|
|
||||||
int place = 0;
|
|
||||||
if (StringUtils.equals(relationshipType.getLeftType().getLabel(), entityType)) {
|
|
||||||
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getLeftLabel());
|
|
||||||
otherItem = relationship.getRightItem();
|
|
||||||
relationName = relationship.getRelationshipType().getLeftLabel();
|
|
||||||
place = relationship.getLeftPlace();
|
|
||||||
} else if (StringUtils.equals(relationshipType.getRightType().getLabel(), entityType)) {
|
|
||||||
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getRightLabel());
|
|
||||||
otherItem = relationship.getLeftItem();
|
|
||||||
relationName = relationship.getRelationshipType().getRightLabel();
|
|
||||||
place = relationship.getRightPlace();
|
|
||||||
} else {
|
|
||||||
//No virtual metadata can be created
|
|
||||||
return resultingMetadataValueList;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hashMaps != null && enableVirtualMetadata) {
|
|
||||||
resultingMetadataValueList.addAll(handleRelationshipTypeMetadataMapping(context, item, hashMaps,
|
|
||||||
otherItem, relationName,
|
|
||||||
relationship.getID(), place));
|
|
||||||
}
|
|
||||||
RelationshipMetadataValue relationMetadataFromOtherItem =
|
|
||||||
getRelationMetadataFromOtherItem(context, otherItem, relationName, relationship.getID(), place);
|
|
||||||
if (relationMetadataFromOtherItem != null) {
|
|
||||||
resultingMetadataValueList.add(relationMetadataFromOtherItem);
|
|
||||||
}
|
|
||||||
return resultingMetadataValueList;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the
|
|
||||||
//hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects
|
|
||||||
//and the keys of the hashmap will be used to construct the RelationshipMetadataValue object.
|
|
||||||
private List<RelationshipMetadataValue> handleRelationshipTypeMetadataMapping(Context context, Item item,
|
|
||||||
HashMap<String, VirtualMetadataConfiguration> hashMaps,
|
|
||||||
Item otherItem, String relationName,
|
|
||||||
Integer relationshipId, int place)
|
|
||||||
throws SQLException {
|
|
||||||
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
|
||||||
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
|
||||||
String key = entry.getKey();
|
|
||||||
VirtualMetadataConfiguration virtualBean = entry.getValue();
|
|
||||||
|
|
||||||
for (String value : virtualBean.getValues(context, otherItem)) {
|
|
||||||
RelationshipMetadataValue metadataValue = constructMetadataValue(context, key);
|
|
||||||
if (metadataValue != null) {
|
|
||||||
metadataValue = constructResultingMetadataValue(item, value, metadataValue, relationshipId);
|
|
||||||
metadataValue.setUseForPlace(virtualBean.getUseForPlace());
|
|
||||||
metadataValue.setPlace(place);
|
|
||||||
if (StringUtils.isNotBlank(metadataValue.getValue())) {
|
|
||||||
resultingMetadataValueList.add(metadataValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resultingMetadataValueList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RelationshipMetadataValue getRelationMetadataFromOtherItem(Context context, Item otherItem,
|
|
||||||
String relationName,
|
|
||||||
Integer relationshipId, int place) {
|
|
||||||
RelationshipMetadataValue metadataValue = constructMetadataValue(context,
|
|
||||||
MetadataSchemaEnum.RELATION
|
|
||||||
.getName() + "." + relationName);
|
|
||||||
if (metadataValue != null) {
|
|
||||||
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
|
||||||
metadataValue.setValue(otherItem.getID().toString());
|
|
||||||
metadataValue.setPlace(place);
|
|
||||||
return metadataValue;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getEntityTypeStringFromMetadata(List<MetadataValue> list) {
|
|
||||||
for (MetadataValue mdv : list) {
|
|
||||||
if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(),
|
|
||||||
"relationship")
|
|
||||||
&& StringUtils.equals(mdv.getMetadataField().getElement(),
|
|
||||||
"type")) {
|
|
||||||
|
|
||||||
return mdv.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RelationshipMetadataValue constructResultingMetadataValue(Item item, String value,
|
|
||||||
RelationshipMetadataValue metadataValue,
|
|
||||||
Integer relationshipId) {
|
|
||||||
metadataValue.setValue(value);
|
|
||||||
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
|
||||||
metadataValue.setConfidence(-1);
|
|
||||||
metadataValue.setDSpaceObject(item);
|
|
||||||
return metadataValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This method will construct a RelationshipMetadataValue object with proper schema, element and qualifier based
|
|
||||||
//on the key String parameter passed along to it
|
|
||||||
private RelationshipMetadataValue constructMetadataValue(Context context, String key) {
|
|
||||||
String[] splittedKey = key.split("\\.");
|
|
||||||
RelationshipMetadataValue metadataValue = new RelationshipMetadataValue();
|
|
||||||
String metadataSchema = splittedKey.length > 0 ? splittedKey[0] : null;
|
|
||||||
String metadataElement = splittedKey.length > 1 ? splittedKey[1] : null;
|
|
||||||
String metadataQualifier = splittedKey.length > 2 ? splittedKey[2] : null;
|
|
||||||
MetadataField metadataField = null;
|
|
||||||
try {
|
|
||||||
metadataField = metadataFieldService
|
|
||||||
.findByElement(context, metadataSchema, metadataElement, metadataQualifier);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Could not find element with MetadataSchema: " + metadataSchema +
|
|
||||||
", MetadataElement: " + metadataElement + " and MetadataQualifier: " + metadataQualifier, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (metadataField == null) {
|
|
||||||
log.error("A MetadataValue was attempted to construct with MetadataField for parameters: " +
|
|
||||||
"metadataschema: {}, metadataelement: {}, metadataqualifier: {}",
|
|
||||||
metadataSchema, metadataElement, metadataQualifier);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
metadataValue.setMetadataField(metadataField);
|
|
||||||
metadataValue.setLanguage(Item.ANY);
|
|
||||||
return metadataValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -77,6 +77,18 @@ public class Relationship implements ReloadableEntity<Integer> {
|
|||||||
@Column(name = "right_place")
|
@Column(name = "right_place")
|
||||||
private int rightPlace;
|
private int rightPlace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String containing an alternative value (name variant) for the left side
|
||||||
|
*/
|
||||||
|
@Column(name = "leftward_value")
|
||||||
|
private String leftwardValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String containing an alternative value (name variant) for the right side
|
||||||
|
*/
|
||||||
|
@Column(name = "rightward_value")
|
||||||
|
private String rightwardValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected constructor, create object using:
|
* Protected constructor, create object using:
|
||||||
* {@link org.dspace.content.service.RelationshipService#create(Context)} }
|
* {@link org.dspace.content.service.RelationshipService#create(Context)} }
|
||||||
@@ -170,6 +182,38 @@ public class Relationship implements ReloadableEntity<Integer> {
|
|||||||
this.rightPlace = rightPlace;
|
this.rightPlace = rightPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the leftwardValue String in this Relationship
|
||||||
|
* @return the leftwardValue String for this relationship
|
||||||
|
*/
|
||||||
|
public String getLeftwardValue() {
|
||||||
|
return leftwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the leftwardValue String in this Relationship
|
||||||
|
* @param leftwardValue the leftwardValue String that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setLeftwardValue(String leftwardValue) {
|
||||||
|
this.leftwardValue = leftwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard getter for the rightwardValue String in this Relationship
|
||||||
|
* @return the rightwardValue string for this relationship
|
||||||
|
*/
|
||||||
|
public String getRightwardValue() {
|
||||||
|
return rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard setter for the rightwardValue String in this Relationship
|
||||||
|
* @param rightwardValue the rightwardValue String that will be used in this relationship
|
||||||
|
*/
|
||||||
|
public void setRightwardValue(String rightwardValue) {
|
||||||
|
this.rightwardValue = rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard getter for the ID for this Relationship
|
* Standard getter for the ID for this Relationship
|
||||||
* @return The ID of this relationship
|
* @return The ID of this relationship
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used for the {@link RelationshipMetadataServiceImpl}
|
||||||
|
* This will define methods regarding the RelationshipMetadata
|
||||||
|
*/
|
||||||
|
public interface RelationshipMetadataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method retrieves a list of MetadataValue objects that get constructed from processing
|
||||||
|
* the given Item's Relationships through the config given to the {@link VirtualMetadataPopulator}
|
||||||
|
* @param item The Item that will be processed through it's Relationships
|
||||||
|
* @param enableVirtualMetadata This parameter will determine whether the list of Relationship metadata
|
||||||
|
* should be populated with metadata that is being generated through the
|
||||||
|
* VirtualMetadataPopulator functionality or not
|
||||||
|
* @return The list of MetadataValue objects constructed through the Relationships
|
||||||
|
*/
|
||||||
|
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata);
|
||||||
|
}
|
@@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.content;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataConfiguration;
|
||||||
|
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class RelationshipMetadataServiceImpl implements RelationshipMetadataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log4j category
|
||||||
|
*/
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger();
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected RelationshipService relationshipService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected MetadataFieldService metadataFieldService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata) {
|
||||||
|
Context context = new Context();
|
||||||
|
List<RelationshipMetadataValue> fullMetadataValueList = new LinkedList<>();
|
||||||
|
try {
|
||||||
|
List<MetadataValue> list = item.getMetadata();
|
||||||
|
String entityType = getEntityTypeStringFromMetadata(list);
|
||||||
|
if (StringUtils.isNotBlank(entityType)) {
|
||||||
|
List<Relationship> relationships = relationshipService.findByItem(context, item);
|
||||||
|
for (Relationship relationship : relationships) {
|
||||||
|
fullMetadataValueList
|
||||||
|
.addAll(findRelationshipMetadataValueForItemRelationship(context, item, entityType,
|
||||||
|
relationship, enableVirtualMetadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Lookup for Relationships for item with uuid: " + item.getID() + " caused DSpace to crash", e);
|
||||||
|
}
|
||||||
|
return fullMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEntityTypeStringFromMetadata(List<MetadataValue> list) {
|
||||||
|
for (MetadataValue mdv : list) {
|
||||||
|
if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(),
|
||||||
|
"relationship")
|
||||||
|
&& StringUtils.equals(mdv.getMetadataField().getElement(),
|
||||||
|
"type")) {
|
||||||
|
|
||||||
|
return mdv.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method processes one Relationship of an Item and will return a list of RelationshipMetadataValue objects
|
||||||
|
* that are generated for this specific relationship for the item through the config in VirtualMetadataPopulator
|
||||||
|
*
|
||||||
|
* It returns a combination of the output of the findVirtualMetadataFromConfiguration method and
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param entityType The entity type of the given item
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param enableVirtualMetadata Determines whether the VirtualMetadataPopulator should be used.
|
||||||
|
* If false, only the relation."relationname" metadata is populated
|
||||||
|
* If true, fields from the spring config virtual metadata is included as well
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
private List<RelationshipMetadataValue> findRelationshipMetadataValueForItemRelationship(
|
||||||
|
Context context, Item item, String entityType, Relationship relationship, boolean enableVirtualMetadata)
|
||||||
|
throws SQLException {
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||||
|
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
||||||
|
String relationName;
|
||||||
|
Item otherItem;
|
||||||
|
int place = 0;
|
||||||
|
boolean isLeftwards;
|
||||||
|
if (StringUtils.equals(relationshipType.getLeftType().getLabel(), entityType)) {
|
||||||
|
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getLeftwardType());
|
||||||
|
otherItem = relationship.getRightItem();
|
||||||
|
relationName = relationship.getRelationshipType().getLeftwardType();
|
||||||
|
place = relationship.getLeftPlace();
|
||||||
|
isLeftwards = false; //if the current item is stored on the left,
|
||||||
|
// the name variant is retrieved from the rightwards label
|
||||||
|
} else if (StringUtils.equals(relationshipType.getRightType().getLabel(), entityType)) {
|
||||||
|
hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getRightwardType());
|
||||||
|
otherItem = relationship.getLeftItem();
|
||||||
|
relationName = relationship.getRelationshipType().getRightwardType();
|
||||||
|
place = relationship.getRightPlace();
|
||||||
|
isLeftwards = true; //if the current item is stored on the right,
|
||||||
|
// the name variant is retrieved from the leftwards label
|
||||||
|
} else {
|
||||||
|
//No virtual metadata can be created
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashMaps != null && enableVirtualMetadata) {
|
||||||
|
resultingMetadataValueList.addAll(findVirtualMetadataFromConfiguration(context, item, hashMaps,
|
||||||
|
otherItem, relationName,
|
||||||
|
relationship, place, isLeftwards));
|
||||||
|
}
|
||||||
|
RelationshipMetadataValue relationMetadataFromOtherItem =
|
||||||
|
getRelationMetadataFromOtherItem(context, otherItem, relationName, relationship.getID(), place);
|
||||||
|
if (relationMetadataFromOtherItem != null) {
|
||||||
|
resultingMetadataValueList.add(relationMetadataFromOtherItem);
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the
|
||||||
|
* hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects
|
||||||
|
* and the keys of the hashmap will be used to construct the RelationshipMetadataValue object.
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param hashMaps The list of VirtualMetadataConfiguration objects which will generate the
|
||||||
|
* virtual metadata. These configurations are applicable for a relationship
|
||||||
|
* between both items
|
||||||
|
* @param otherItem The related item whose actual metadata is requested
|
||||||
|
* @param relationName The name of the relationship
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param place The place to use in the virtual metadata
|
||||||
|
* @param isLeftwards Determines the direction of the virtual metadata
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
private List<RelationshipMetadataValue> findVirtualMetadataFromConfiguration(Context context, Item item,
|
||||||
|
HashMap<String, VirtualMetadataConfiguration> hashMaps, Item otherItem, String relationName,
|
||||||
|
Relationship relationship, int place, boolean isLeftwards) throws SQLException {
|
||||||
|
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
VirtualMetadataConfiguration virtualBean = entry.getValue();
|
||||||
|
|
||||||
|
if (virtualBean.getPopulateWithNameVariant()) {
|
||||||
|
String wardLabel = isLeftwards ? relationship.getLeftwardValue() : relationship.getRightwardValue();
|
||||||
|
if (wardLabel != null) {
|
||||||
|
resultingMetadataValueList.add(
|
||||||
|
constructRelationshipMetadataValue(context, item, relationship.getID(), place, key, virtualBean,
|
||||||
|
wardLabel));
|
||||||
|
} else {
|
||||||
|
resultingMetadataValueList.addAll(
|
||||||
|
findRelationshipMetadataValueFromBean(context, item, otherItem, relationship, place, key,
|
||||||
|
virtualBean));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultingMetadataValueList.addAll(
|
||||||
|
findRelationshipMetadataValueFromBean(context, item, otherItem, relationship, place, key,
|
||||||
|
virtualBean));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the
|
||||||
|
* hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects
|
||||||
|
* and the keys of the hashmap will be used to construct the RelationshipMetadataValue object.
|
||||||
|
*
|
||||||
|
* @param context The context
|
||||||
|
* @param item The item whose virtual metadata is requested
|
||||||
|
* @param otherItem The related item whose actual metadata is requested
|
||||||
|
* @param relationship The relationship whose virtual metadata is requested
|
||||||
|
* @param place The place to use in the virtual metadata
|
||||||
|
* @param key The key corresponding to the VirtualMetadataConfiguration
|
||||||
|
* @param virtualBean The VirtualMetadataConfiguration object which will generate the
|
||||||
|
* virtual metadata. This configuration is applicable for a relationship
|
||||||
|
* between both items
|
||||||
|
* @return The list of virtual metadata values
|
||||||
|
*/
|
||||||
|
private List<RelationshipMetadataValue> findRelationshipMetadataValueFromBean(
|
||||||
|
Context context, Item item, Item otherItem, Relationship relationship, int place,
|
||||||
|
String key, VirtualMetadataConfiguration virtualBean) throws SQLException {
|
||||||
|
List<RelationshipMetadataValue> resultingMetadataValueList = new LinkedList<>();
|
||||||
|
for (String value : virtualBean.getValues(context, otherItem)) {
|
||||||
|
RelationshipMetadataValue relationshipMetadataValue = constructRelationshipMetadataValue(context, item,
|
||||||
|
relationship
|
||||||
|
.getID(),
|
||||||
|
place,
|
||||||
|
key, virtualBean,
|
||||||
|
value);
|
||||||
|
if (relationshipMetadataValue != null) {
|
||||||
|
resultingMetadataValueList.add(relationshipMetadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultingMetadataValueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This method will construct a RelationshipMetadataValue object with proper schema, element, qualifier,
|
||||||
|
//authority, item, place and useForPlace based on the key String parameter passed along to it
|
||||||
|
private RelationshipMetadataValue constructRelationshipMetadataValue(Context context, Item item,
|
||||||
|
Integer relationshipId, int place,
|
||||||
|
String key,
|
||||||
|
VirtualMetadataConfiguration virtualBean,
|
||||||
|
String value) {
|
||||||
|
RelationshipMetadataValue metadataValue = constructMetadataValue(context, key);
|
||||||
|
if (metadataValue != null) {
|
||||||
|
metadataValue = constructResultingMetadataValue(item, value, metadataValue, relationshipId);
|
||||||
|
metadataValue.setUseForPlace(virtualBean.getUseForPlace());
|
||||||
|
metadataValue.setPlace(place);
|
||||||
|
if (StringUtils.isNotBlank(metadataValue.getValue())) {
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This method will construct a RelationshipMetadataValue object with proper schema, element and qualifier based
|
||||||
|
//on the key String parameter passed along to it
|
||||||
|
private RelationshipMetadataValue constructMetadataValue(Context context, String key) {
|
||||||
|
String[] splittedKey = key.split("\\.");
|
||||||
|
RelationshipMetadataValue metadataValue = new RelationshipMetadataValue();
|
||||||
|
String metadataSchema = splittedKey.length > 0 ? splittedKey[0] : null;
|
||||||
|
String metadataElement = splittedKey.length > 1 ? splittedKey[1] : null;
|
||||||
|
String metadataQualifier = splittedKey.length > 2 ? splittedKey[2] : null;
|
||||||
|
MetadataField metadataField = null;
|
||||||
|
try {
|
||||||
|
metadataField = metadataFieldService
|
||||||
|
.findByElement(context, metadataSchema, metadataElement, metadataQualifier);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Could not find element with MetadataSchema: " + metadataSchema +
|
||||||
|
", MetadataElement: " + metadataElement + " and MetadataQualifier: " + metadataQualifier, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (metadataField == null) {
|
||||||
|
log.error("A MetadataValue was attempted to construct with MetadataField for parameters: " +
|
||||||
|
"metadataschema: {}, metadataelement: {}, metadataqualifier: {}",
|
||||||
|
metadataSchema, metadataElement, metadataQualifier);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
metadataValue.setMetadataField(metadataField);
|
||||||
|
metadataValue.setLanguage(Item.ANY);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//This method will update a RelationshipMetadataValue object with authority info and relation to the item
|
||||||
|
private RelationshipMetadataValue constructResultingMetadataValue(Item item, String value,
|
||||||
|
RelationshipMetadataValue metadataValue,
|
||||||
|
Integer relationshipId) {
|
||||||
|
metadataValue.setValue(value);
|
||||||
|
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
||||||
|
metadataValue.setConfidence(-1);
|
||||||
|
metadataValue.setDSpaceObject(item);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method will create the Relationship Metadatavalue that describes the relationship type and has the ID
|
||||||
|
// of the other item as value
|
||||||
|
private RelationshipMetadataValue getRelationMetadataFromOtherItem(Context context, Item otherItem,
|
||||||
|
String relationName,
|
||||||
|
Integer relationshipId, int place) {
|
||||||
|
RelationshipMetadataValue metadataValue = constructMetadataValue(context,
|
||||||
|
MetadataSchemaEnum.RELATION
|
||||||
|
.getName() + "." + relationName);
|
||||||
|
if (metadataValue != null) {
|
||||||
|
metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId);
|
||||||
|
metadataValue.setValue(otherItem.getID().toString());
|
||||||
|
metadataValue.setPlace(place);
|
||||||
|
return metadataValue;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -59,12 +59,21 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
@Override
|
@Override
|
||||||
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
int leftPlace, int rightPlace) throws AuthorizeException, SQLException {
|
int leftPlace, int rightPlace) throws AuthorizeException, SQLException {
|
||||||
|
return create(c, leftItem, rightItem, relationshipType, leftPlace, rightPlace, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
|
int leftPlace, int rightPlace, String leftwardValue, String rightwardValue)
|
||||||
|
throws AuthorizeException, SQLException {
|
||||||
Relationship relationship = new Relationship();
|
Relationship relationship = new Relationship();
|
||||||
relationship.setLeftItem(leftItem);
|
relationship.setLeftItem(leftItem);
|
||||||
relationship.setRightItem(rightItem);
|
relationship.setRightItem(rightItem);
|
||||||
relationship.setRelationshipType(relationshipType);
|
relationship.setRelationshipType(relationshipType);
|
||||||
relationship.setLeftPlace(leftPlace);
|
relationship.setLeftPlace(leftPlace);
|
||||||
relationship.setRightPlace(rightPlace);
|
relationship.setRightPlace(rightPlace);
|
||||||
|
relationship.setLeftwardValue(leftwardValue);
|
||||||
|
relationship.setRightwardValue(rightwardValue);
|
||||||
return create(c, relationship);
|
return create(c, relationship);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +122,7 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
rightRelationships.remove(relationship);
|
rightRelationships.remove(relationship);
|
||||||
}
|
}
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
//If useForPlace for the leftlabel is false for the relationshipType,
|
//If useForPlace for the leftwardType is false for the relationshipType,
|
||||||
// we need to sort the relationships here based on leftplace.
|
// we need to sort the relationships here based on leftplace.
|
||||||
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), true)) {
|
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), true)) {
|
||||||
if (!leftRelationships.isEmpty()) {
|
if (!leftRelationships.isEmpty()) {
|
||||||
@@ -130,7 +139,7 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If useForPlace for the rightLabel is false for the relationshipType,
|
//If useForPlace for the rightwardType is false for the relationshipType,
|
||||||
// we need to sort the relationships here based on the rightplace.
|
// we need to sort the relationships here based on the rightplace.
|
||||||
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), false)) {
|
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), false)) {
|
||||||
if (!rightRelationships.isEmpty()) {
|
if (!rightRelationships.isEmpty()) {
|
||||||
@@ -202,8 +211,8 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
|
|
||||||
private void logRelationshipTypeDetailsForError(RelationshipType relationshipType) {
|
private void logRelationshipTypeDetailsForError(RelationshipType relationshipType) {
|
||||||
log.warn("The relationshipType's ID is: " + relationshipType.getID());
|
log.warn("The relationshipType's ID is: " + relationshipType.getID());
|
||||||
log.warn("The relationshipType's left label is: " + relationshipType.getLeftLabel());
|
log.warn("The relationshipType's leftward type is: " + relationshipType.getLeftwardType());
|
||||||
log.warn("The relationshipType's right label is: " + relationshipType.getRightLabel());
|
log.warn("The relationshipType's rightward type is: " + relationshipType.getRightwardType());
|
||||||
log.warn("The relationshipType's left entityType label is: " + relationshipType.getLeftType().getLabel());
|
log.warn("The relationshipType's left entityType label is: " + relationshipType.getLeftType().getLabel());
|
||||||
log.warn("The relationshipType's right entityType label is: " + relationshipType.getRightType().getLabel());
|
log.warn("The relationshipType's right entityType label is: " + relationshipType.getRightType().getLabel());
|
||||||
log.warn("The relationshipType's left min cardinality is: " + relationshipType.getLeftMinCardinality());
|
log.warn("The relationshipType's left min cardinality is: " + relationshipType.getLeftMinCardinality());
|
||||||
@@ -243,8 +252,8 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
List<Relationship> list = relationshipDAO.findByItem(context, item);
|
List<Relationship> list = relationshipDAO.findByItem(context, item);
|
||||||
|
|
||||||
list.sort((o1, o2) -> {
|
list.sort((o1, o2) -> {
|
||||||
int relationshipType = o1.getRelationshipType().getLeftLabel()
|
int relationshipType = o1.getRelationshipType().getLeftwardType()
|
||||||
.compareTo(o2.getRelationshipType().getLeftLabel());
|
.compareTo(o2.getRelationshipType().getLeftwardType());
|
||||||
if (relationshipType != 0) {
|
if (relationshipType != 0) {
|
||||||
return relationshipType;
|
return relationshipType;
|
||||||
} else {
|
} else {
|
||||||
@@ -357,12 +366,16 @@ public class RelationshipServiceImpl implements RelationshipService {
|
|||||||
for (Relationship relationship : list) {
|
for (Relationship relationship : list) {
|
||||||
if (isLeft) {
|
if (isLeft) {
|
||||||
if (StringUtils
|
if (StringUtils
|
||||||
.equals(relationship.getRelationshipType().getLeftLabel(), relationshipType.getLeftLabel())) {
|
.equals(
|
||||||
|
relationship.getRelationshipType().getLeftwardType(), relationshipType.getLeftwardType())
|
||||||
|
) {
|
||||||
listToReturn.add(relationship);
|
listToReturn.add(relationship);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (StringUtils
|
if (StringUtils
|
||||||
.equals(relationship.getRelationshipType().getRightLabel(), relationshipType.getRightLabel())) {
|
.equals(
|
||||||
|
relationship.getRelationshipType().getRightwardType(), relationshipType.getRightwardType())
|
||||||
|
) {
|
||||||
listToReturn.add(relationship);
|
listToReturn.add(relationship);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,8 @@ import org.dspace.core.ReloadableEntity;
|
|||||||
* Class representing a RelationshipType
|
* Class representing a RelationshipType
|
||||||
* This class contains an Integer ID that will be the unique value and primary key in the database.
|
* This class contains an Integer ID that will be the unique value and primary key in the database.
|
||||||
* This key is automatically generated
|
* This key is automatically generated
|
||||||
* It also has a leftType and rightType EntityType that describes the relationshipType together with a leftLabel and
|
* It also has a leftType and rightType EntityType that describes the relationshipType together with a leftwardType and
|
||||||
* rightLabel.
|
* rightwardType.
|
||||||
* The cardinality properties describe how many of each relations this relationshipType can support
|
* The cardinality properties describe how many of each relations this relationshipType can support
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@@ -61,20 +61,20 @@ public class RelationshipType implements ReloadableEntity<Integer> {
|
|||||||
private EntityType rightType;
|
private EntityType rightType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The leftLabel String field for the relationshipType
|
* The leftwardType String field for the relationshipType
|
||||||
* This is stored as a String and cannot be null
|
* This is stored as a String and cannot be null
|
||||||
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||||
*/
|
*/
|
||||||
@Column(name = "left_label", nullable = false)
|
@Column(name = "leftward_type", nullable = false)
|
||||||
private String leftLabel;
|
private String leftwardType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The rightLabel String field for the relationshipType
|
* The rightwardType String field for the relationshipType
|
||||||
* This is stored as a String and cannot be null
|
* This is stored as a String and cannot be null
|
||||||
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
* This is a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||||
*/
|
*/
|
||||||
@Column(name = "right_label", nullable = false)
|
@Column(name = "rightward_type", nullable = false)
|
||||||
private String rightLabel;
|
private String rightwardType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum amount of relations for the leftItem that need to be present at all times
|
* The minimum amount of relations for the leftItem that need to be present at all times
|
||||||
@@ -149,35 +149,35 @@ public class RelationshipType implements ReloadableEntity<Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard getter for the leftLabel String for this RelationshipType
|
* Standard getter for the leftwardType String for this RelationshipType
|
||||||
* @return The leftLabel String of this RelationshipType
|
* @return The leftwardType String of this RelationshipType
|
||||||
*/
|
*/
|
||||||
public String getLeftLabel() {
|
public String getLeftwardType() {
|
||||||
return leftLabel;
|
return leftwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard setter for the leftLabel String for this RelationshipType
|
* Standard setter for the leftwardType String for this RelationshipType
|
||||||
* @param leftLabel The leftLabel String that this RelationshipType should receive
|
* @param leftwardType The leftwardType String that this RelationshipType should receive
|
||||||
*/
|
*/
|
||||||
public void setLeftLabel(String leftLabel) {
|
public void setLeftwardType(String leftwardType) {
|
||||||
this.leftLabel = leftLabel;
|
this.leftwardType = leftwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard getter for the rightLabel String for this RelationshipType
|
* Standard getter for the rightwardType String for this RelationshipType
|
||||||
* @return The rightLabel String of this RelationshipType
|
* @return The rightwardType String of this RelationshipType
|
||||||
*/
|
*/
|
||||||
public String getRightLabel() {
|
public String getRightwardType() {
|
||||||
return rightLabel;
|
return rightwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard setter for the rightLabel String for this RelationshipType
|
* Standard setter for the rightwardType String for this RelationshipType
|
||||||
* @param rightLabel The rightLabel String that this RelationshipType should receive
|
* @param rightwardType The rightwardType String that this RelationshipType should receive
|
||||||
*/
|
*/
|
||||||
public void setRightLabel(String rightLabel) {
|
public void setRightwardType(String rightwardType) {
|
||||||
this.rightLabel = rightLabel;
|
this.rightwardType = rightwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -48,8 +48,8 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
public RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
||||||
String leftLabel,String rightLabel) throws SQLException {
|
String leftwardType,String rightwardType) throws SQLException {
|
||||||
return relationshipTypeDAO.findByTypesAndLabels(context, leftType, rightType, leftLabel, rightLabel);
|
return relationshipTypeDAO.findByTypesAndLabels(context, leftType, rightType, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,8 +58,8 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException {
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String label) throws SQLException {
|
||||||
return relationshipTypeDAO.findByLeftOrRightLabel(context, label);
|
return relationshipTypeDAO.findByLeftwardOrRightwardTypeName(context, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -69,15 +69,15 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
public RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||||
String leftLabel, String rightLabel, Integer leftCardinalityMinInteger,
|
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
|
||||||
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
||||||
Integer rightCardinalityMaxInteger)
|
Integer rightCardinalityMaxInteger)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
RelationshipType relationshipType = new RelationshipType();
|
RelationshipType relationshipType = new RelationshipType();
|
||||||
relationshipType.setLeftType(leftEntityType);
|
relationshipType.setLeftType(leftEntityType);
|
||||||
relationshipType.setRightType(rightEntityType);
|
relationshipType.setRightType(rightEntityType);
|
||||||
relationshipType.setLeftLabel(leftLabel);
|
relationshipType.setLeftwardType(leftwardType);
|
||||||
relationshipType.setRightLabel(rightLabel);
|
relationshipType.setRightwardType(rightwardType);
|
||||||
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
||||||
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
||||||
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
||||||
|
@@ -25,28 +25,30 @@ public interface RelationshipTypeDAO extends GenericDAO<RelationshipType> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to retrieve the RelationshipType object that has the same
|
* This method is used to retrieve the RelationshipType object that has the same
|
||||||
* leftType, rightType, leftLabel and rightLabel as given in the parameters
|
* leftType, rightType, leftwardType and rightwardType as given in the parameters
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param leftType The leftType EntityType object to be matched in the query
|
* @param leftType The leftType EntityType object to be matched in the query
|
||||||
* @param rightType The rightType EntityType object to be matched in the query
|
* @param rightType The rightType EntityType object to be matched in the query
|
||||||
* @param leftLabel The leftLabel String to be matched in the query
|
* @param leftwardType The leftwardType String to be matched in the query
|
||||||
* @param rightLabel The rightLabel String to be matched in the query
|
* @param rightwardType The rightwardType String to be matched in the query
|
||||||
* @return The RelationshipType object that matches all the given parameters
|
* @return The RelationshipType object that matches all the given parameters
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
RelationshipType findByTypesAndLabels(Context context,
|
RelationshipType findByTypesAndLabels(Context context, EntityType leftType,EntityType rightType,
|
||||||
EntityType leftType,EntityType rightType,String leftLabel,String rightLabel)
|
String leftwardType,
|
||||||
throws SQLException;
|
String rightwardType)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return a list of RelationshipType objects for which the given label is equal to
|
* This method will return a list of RelationshipType objects for which the given label is equal to
|
||||||
* either the leftLabel or rightLabel.
|
* either the leftwardType or rightwardType.
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param label The label that will be used to check on
|
* @param type The label that will be used to check on
|
||||||
* @return A list of RelationshipType objects that have the given label as either the leftLabel or rightLabel
|
* @return A list of RelationshipType objects that have the given label as either the leftwardType
|
||||||
|
* or rightwardType
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException;
|
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||||
|
@@ -8,8 +8,6 @@
|
|||||||
package org.dspace.content.dao.impl;
|
package org.dspace.content.dao.impl;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
@@ -62,11 +60,20 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
public List<Community> findAll(Context context, MetadataField sortField, Integer limit, Integer offset)
|
public List<Community> findAll(Context context, MetadataField sortField, Integer limit, Integer offset)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
queryBuilder.append("SELECT ").append(Community.class.getSimpleName()).append(" FROM Community as ")
|
|
||||||
.append(Community.class.getSimpleName()).append(" ");
|
|
||||||
addMetadataLeftJoin(queryBuilder, Community.class.getSimpleName(), Arrays.asList(sortField));
|
|
||||||
addMetadataSortQuery(queryBuilder, Arrays.asList(sortField), Collections.EMPTY_LIST);
|
|
||||||
|
|
||||||
|
// The query has to be rather complex because we want to sort the retrieval of Communities based on the title
|
||||||
|
// We'll join the Communities with the metadata fields on the sortfield specified in the parameters
|
||||||
|
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||||
|
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||||
|
queryBuilder.append("SELECT c" +
|
||||||
|
" FROM Community c" +
|
||||||
|
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||||
|
" title.dSpaceObject = c.id and" +
|
||||||
|
" title.place = (select min(internal.place) " +
|
||||||
|
"from c.metadata internal " +
|
||||||
|
"where internal.metadataField = :sortField and" +
|
||||||
|
" internal.dSpaceObject = c.id)" +
|
||||||
|
" ORDER BY LOWER(title.value)");
|
||||||
Query query = createQuery(context, queryBuilder.toString());
|
Query query = createQuery(context, queryBuilder.toString());
|
||||||
if (offset != null) {
|
if (offset != null) {
|
||||||
query.setFirstResult(offset);
|
query.setFirstResult(offset);
|
||||||
@@ -74,7 +81,8 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
query.setMaxResults(limit);
|
query.setMaxResults(limit);
|
||||||
}
|
}
|
||||||
query.setParameter(sortField.toString(), sortField.getID());
|
query.setParameter("sortField", sortField);
|
||||||
|
|
||||||
return list(query);
|
return list(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +99,26 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
|||||||
@Override
|
@Override
|
||||||
public List<Community> findAllNoParent(Context context, MetadataField sortField) throws SQLException {
|
public List<Community> findAllNoParent(Context context, MetadataField sortField) throws SQLException {
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
queryBuilder.append("SELECT community FROM Community as community ");
|
|
||||||
addMetadataLeftJoin(queryBuilder, Community.class.getSimpleName().toLowerCase(), Arrays.asList(sortField));
|
|
||||||
addMetadataValueWhereQuery(queryBuilder, Collections.EMPTY_LIST, null, " community.parentCommunities IS EMPTY");
|
|
||||||
addMetadataSortQuery(queryBuilder, Arrays.asList(sortField), Collections.EMPTY_LIST);
|
|
||||||
|
|
||||||
|
// The query has to be rather complex because we want to sort the retrieval of Communities based on the title
|
||||||
|
// We'll join the Communities with the metadata fields on the sortfield specified in the parameters
|
||||||
|
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||||
|
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||||
|
// This query has the added where clause to enforce that the community cannot have any parent communities
|
||||||
|
queryBuilder.append("SELECT c" +
|
||||||
|
" FROM Community c" +
|
||||||
|
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||||
|
" title.dSpaceObject = c.id and" +
|
||||||
|
" title.place = (select min(internal.place) " +
|
||||||
|
"from c.metadata internal " +
|
||||||
|
"where internal.metadataField = :sortField and" +
|
||||||
|
" internal.dSpaceObject = c.id)" +
|
||||||
|
" WHERE c.parentCommunities IS EMPTY " +
|
||||||
|
" ORDER BY LOWER(title.value)");
|
||||||
Query query = createQuery(context, queryBuilder.toString());
|
Query query = createQuery(context, queryBuilder.toString());
|
||||||
query.setParameter(sortField.toString(), sortField.getID());
|
query.setParameter("sortField", sortField);
|
||||||
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
||||||
|
|
||||||
|
|
||||||
return findMany(context, query);
|
return findMany(context, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,31 +24,31 @@ public class RelationshipTypeDAOImpl extends AbstractHibernateDAO<RelationshipTy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RelationshipType findByTypesAndLabels(Context context, EntityType leftType, EntityType rightType,
|
public RelationshipType findByTypesAndLabels(Context context, EntityType leftType, EntityType rightType,
|
||||||
String leftLabel, String rightLabel)
|
String leftwardType, String rightwardType)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
criteriaQuery.select(relationshipTypeRoot);
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
criteriaQuery.where(
|
criteriaQuery.where(
|
||||||
criteriaBuilder.and(criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), leftType),
|
criteriaBuilder.and(
|
||||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), rightType),
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), leftType),
|
||||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftLabel), leftLabel),
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), rightType),
|
||||||
criteriaBuilder
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), leftwardType),
|
||||||
.equal(relationshipTypeRoot.get(RelationshipType_.rightLabel), rightLabel)));
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), rightwardType)));
|
||||||
return uniqueResult(context, criteriaQuery, false, RelationshipType.class, -1, -1);
|
return uniqueResult(context, criteriaQuery, false, RelationshipType.class, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException {
|
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException {
|
||||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||||
criteriaQuery.select(relationshipTypeRoot);
|
criteriaQuery.select(relationshipTypeRoot);
|
||||||
criteriaQuery.where(
|
criteriaQuery.where(
|
||||||
criteriaBuilder.or(
|
criteriaBuilder.or(
|
||||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftLabel), label),
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), type),
|
||||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightLabel), label)
|
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), type)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return list(context, criteriaQuery, true, RelationshipType.class, -1, -1);
|
return list(context, criteriaQuery, true, RelationshipType.class, -1, -1);
|
||||||
|
@@ -12,6 +12,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.InProgressSubmission;
|
import org.dspace.content.InProgressSubmission;
|
||||||
|
import org.dspace.content.RelationshipMetadataService;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.service.BitstreamFormatService;
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
@@ -112,6 +113,8 @@ public abstract class ContentServiceFactory {
|
|||||||
*/
|
*/
|
||||||
public abstract EntityService getEntityService();
|
public abstract EntityService getEntityService();
|
||||||
|
|
||||||
|
public abstract RelationshipMetadataService getRelationshipMetadataService();
|
||||||
|
|
||||||
public InProgressSubmissionService getInProgressSubmissionService(InProgressSubmission inProgressSubmission) {
|
public InProgressSubmissionService getInProgressSubmissionService(InProgressSubmission inProgressSubmission) {
|
||||||
if (inProgressSubmission instanceof WorkspaceItem) {
|
if (inProgressSubmission instanceof WorkspaceItem) {
|
||||||
return getWorkspaceItemService();
|
return getWorkspaceItemService();
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.content.factory;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.RelationshipMetadataService;
|
||||||
import org.dspace.content.service.BitstreamFormatService;
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.BundleService;
|
import org.dspace.content.service.BundleService;
|
||||||
@@ -78,6 +79,8 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private RelationshipTypeService relationshipTypeService;
|
private RelationshipTypeService relationshipTypeService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
|
private RelationshipMetadataService relationshipMetadataService;
|
||||||
|
@Autowired(required = true)
|
||||||
private EntityTypeService entityTypeService;
|
private EntityTypeService entityTypeService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private EntityService entityService;
|
private EntityService entityService;
|
||||||
@@ -182,4 +185,8 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
|||||||
return entityService;
|
return entityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelationshipMetadataService getRelationshipMetadataService() {
|
||||||
|
return relationshipMetadataService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -122,6 +122,6 @@ public interface EntityService {
|
|||||||
* to the given label parameter
|
* to the given label parameter
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
List<RelationshipType> getRelationshipTypesByLabel(Context context, String label) throws SQLException;
|
List<RelationshipType> getRelationshipTypesByTypeName(Context context, String label) throws SQLException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -24,10 +24,8 @@ import org.dspace.content.Community;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.RelationshipMetadataValue;
|
|
||||||
import org.dspace.content.Thumbnail;
|
import org.dspace.content.Thumbnail;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
@@ -40,7 +38,7 @@ import org.dspace.eperson.Group;
|
|||||||
* @author kevinvandevelde at atmire.com
|
* @author kevinvandevelde at atmire.com
|
||||||
*/
|
*/
|
||||||
public interface ItemService
|
public interface ItemService
|
||||||
extends DSpaceObjectService<Item>, DSpaceObjectLegacySupportService<Item>, IndexableObjectService<Item, UUID> {
|
extends DSpaceObjectService<Item>, DSpaceObjectLegacySupportService<Item>, IndexableObjectService<Item, UUID> {
|
||||||
|
|
||||||
public Thumbnail getThumbnail(Context context, Item item, boolean requireOriginal) throws SQLException;
|
public Thumbnail getThumbnail(Context context, Item item, boolean requireOriginal) throws SQLException;
|
||||||
|
|
||||||
@@ -205,7 +203,7 @@ public interface ItemService
|
|||||||
* @throws SQLException if database error
|
* @throws SQLException if database error
|
||||||
*/
|
*/
|
||||||
public Iterator<Item> findInArchiveOrWithdrawnNonDiscoverableModifiedSince(Context context, Date since)
|
public Iterator<Item> findInArchiveOrWithdrawnNonDiscoverableModifiedSince(Context context, Date since)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the items (including private and withdrawn) in this collection. The order is indeterminate.
|
* Get all the items (including private and withdrawn) in this collection. The order is indeterminate.
|
||||||
@@ -677,19 +675,6 @@ public interface ItemService
|
|||||||
*/
|
*/
|
||||||
boolean isInProgressSubmission(Context context, Item item) throws SQLException;
|
boolean isInProgressSubmission(Context context, Item item) throws SQLException;
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves a list of MetadataValue objects that get constructed from processing
|
|
||||||
* the given Item's Relationships through the config given to the {@link VirtualMetadataPopulator}
|
|
||||||
* @param item The Item that will be processed through it's Relationships
|
|
||||||
* @param enableVirtualMetadata This parameter will determine whether the list of Relationship metadata
|
|
||||||
* should be populated with metadata that is being generated through the
|
|
||||||
* VirtualMetadataPopulator functionality or not
|
|
||||||
* @return The list of MetadataValue objects constructed through the Relationships
|
|
||||||
*/
|
|
||||||
public List<RelationshipMetadataValue> getRelationshipMetadata(Item item, boolean enableVirtualMetadata);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get metadata for the DSpace Object in a chosen schema.
|
* Get metadata for the DSpace Object in a chosen schema.
|
||||||
* See <code>MetadataSchema</code> for more information about schemas.
|
* See <code>MetadataSchema</code> for more information about schemas.
|
||||||
|
@@ -89,7 +89,7 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will update the place for the Relationship and all other relationships found by the items and
|
* This method will update the place for the Relationship and all other relationships found by the items and
|
||||||
* relationship type of the given Relatonship. It will give this Relationship the last place in both the
|
* relationship type of the given Relationship. It will give this Relationship the last place in both the
|
||||||
* left and right place determined by querying for the list of leftRelationships and rightRelationships
|
* left and right place determined by querying for the list of leftRelationships and rightRelationships
|
||||||
* by the leftItem, rightItem and relationshipType of the given Relationship.
|
* by the leftItem, rightItem and relationshipType of the given Relationship.
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
@@ -115,7 +115,7 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a list of Relationship objets for which the relationshipType property is equal to the given
|
* This method returns a list of Relationship objects for which the relationshipType property is equal to the given
|
||||||
* RelationshipType object
|
* RelationshipType object
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
||||||
@@ -133,11 +133,31 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
|||||||
* @param relationshipType The RelationshipType object for the relationship
|
* @param relationshipType The RelationshipType object for the relationship
|
||||||
* @param leftPlace The leftPlace integer for the relationship
|
* @param leftPlace The leftPlace integer for the relationship
|
||||||
* @param rightPlace The rightPlace integer for the relationship
|
* @param rightPlace The rightPlace integer for the relationship
|
||||||
|
* @param leftwardValue The leftwardValue string for the relationship
|
||||||
|
* @param rightwardValue The rightwardValue string for the relationship
|
||||||
|
* @return The created Relationship object with the given properties
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
|
int leftPlace, int rightPlace, String leftwardValue, String rightwardValue)
|
||||||
|
throws AuthorizeException, SQLException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to construct a Relationship object with all it's variables,
|
||||||
|
* except the leftward and rightward labels
|
||||||
|
* @param c The relevant DSpace context
|
||||||
|
* @param leftItem The leftItem Item object for the relationship
|
||||||
|
* @param rightItem The rightItem Item object for the relationship
|
||||||
|
* @param relationshipType The RelationshipType object for the relationship
|
||||||
|
* @param leftPlace The leftPlace integer for the relationship
|
||||||
|
* @param rightPlace The rightPlace integer for the relationship
|
||||||
* @return The created Relationship object with the given properties
|
* @return The created Relationship object with the given properties
|
||||||
* @throws AuthorizeException If something goes wrong
|
* @throws AuthorizeException If something goes wrong
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||||
int leftPlace, int rightPlace)
|
int leftPlace, int rightPlace)
|
||||||
throws AuthorizeException, SQLException;
|
throws AuthorizeException, SQLException;
|
||||||
}
|
}
|
@@ -23,9 +23,9 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates the given RelationshipType object in the database and returns it
|
* This method creates the given RelationshipType object in the database and returns it
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param relationshipType The RelationshipType to be created in the database
|
* @param relationshipType The RelationshipType to be created in the database
|
||||||
* @return The newly created RelationshipType
|
* @return The newly created RelationshipType
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
* @throws AuthorizeException If something goes wrong with authorizations
|
* @throws AuthorizeException If something goes wrong with authorizations
|
||||||
*/
|
*/
|
||||||
@@ -33,16 +33,16 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a RelationshipType for which the given parameters all match the one in the returned RelationshipType
|
* Retrieves a RelationshipType for which the given parameters all match the one in the returned RelationshipType
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param leftType The rightType EntityType that needs to match for the returned RelationshipType
|
* @param leftType The rightType EntityType that needs to match for the returned RelationshipType
|
||||||
* @param rightType The rightType EntityType that needs to match for the returned RelationshipType
|
* @param rightType The rightType EntityType that needs to match for the returned RelationshipType
|
||||||
* @param leftLabel The leftLabel String that needs to match for the returned RelationshipType
|
* @param leftwardType The leftwardType String that needs to match for the returned RelationshipType
|
||||||
* @param rightLabel The rightLabel String that needs to match for the returned RelationshipType
|
* @param rightwardType The rightwardType String that needs to match for the returned RelationshipType
|
||||||
* @return
|
* @return
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
||||||
String leftLabel,String rightLabel)
|
String leftwardType,String rightwardType)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +54,7 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
List<RelationshipType> findAll(Context context) throws SQLException;
|
List<RelationshipType> findAll(Context context) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all RelationshipType objects that have a left or right label that is
|
* Retrieves all RelationshipType objects that have a left or right type that is
|
||||||
* equal to the given String
|
* equal to the given String
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param label The label that has to match
|
* @param label The label that has to match
|
||||||
@@ -62,7 +62,7 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
* that is equal to the given label param
|
* that is equal to the given label param
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException;
|
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String label) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of RelationshipType objects for which the given EntityType is equal to either the leftType
|
* Returns a list of RelationshipType objects for which the given EntityType is equal to either the leftType
|
||||||
@@ -80,8 +80,8 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param leftEntityType The leftEntityType EntityType object for this relationshipType
|
* @param leftEntityType The leftEntityType EntityType object for this relationshipType
|
||||||
* @param rightEntityType The rightEntityType EntityType object for this relationshipType
|
* @param rightEntityType The rightEntityType EntityType object for this relationshipType
|
||||||
* @param leftLabel The leftLabel String object for this relationshipType
|
* @param leftwardType The leftwardType String object for this relationshipType
|
||||||
* @param rightLabel The rightLabel String object for this relationshipType
|
* @param rightwardType The rightwardType String object for this relationshipType
|
||||||
* @param leftCardinalityMinInteger The leftCardinalityMinInteger Integer object for this relationshipType
|
* @param leftCardinalityMinInteger The leftCardinalityMinInteger Integer object for this relationshipType
|
||||||
* @param leftCardinalityMaxInteger The leftCardinalityMaxInteger Integer object for this relationshipType
|
* @param leftCardinalityMaxInteger The leftCardinalityMaxInteger Integer object for this relationshipType
|
||||||
* @param rightCardinalityMinInteger The rightCardinalityMinInteger Integer object for this relationshipType
|
* @param rightCardinalityMinInteger The rightCardinalityMinInteger Integer object for this relationshipType
|
||||||
@@ -90,8 +90,9 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
|||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
* @throws AuthorizeException If something goes wrong
|
* @throws AuthorizeException If something goes wrong
|
||||||
*/
|
*/
|
||||||
RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType, String leftLabel,
|
RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||||
String rightLabel, Integer leftCardinalityMinInteger, Integer leftCardinalityMaxInteger,
|
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
|
||||||
Integer rightCardinalityMinInteger, Integer rightCardinalityMaxInteger)
|
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
||||||
|
Integer rightCardinalityMaxInteger)
|
||||||
throws SQLException, AuthorizeException;
|
throws SQLException, AuthorizeException;
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,7 @@ public class Collected implements VirtualMetadataConfiguration {
|
|||||||
* Generic setter for the useForPlace property
|
* Generic setter for the useForPlace property
|
||||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setUseForPlace(boolean useForPlace) {
|
public void setUseForPlace(boolean useForPlace) {
|
||||||
this.useForPlace = useForPlace;
|
this.useForPlace = useForPlace;
|
||||||
}
|
}
|
||||||
@@ -73,10 +74,19 @@ public class Collected implements VirtualMetadataConfiguration {
|
|||||||
* Generic getter for the useForPlace property
|
* Generic getter for the useForPlace property
|
||||||
* @return The useForPlace to be used by this bean
|
* @return The useForPlace to be used by this bean
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean getUseForPlace() {
|
public boolean getUseForPlace() {
|
||||||
return useForPlace;
|
return useForPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPopulateWithNameVariant(boolean populateWithNameVariant) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPopulateWithNameVariant() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this method will retrieve the metadata values from the given item for all the metadata fields listed
|
* this method will retrieve the metadata values from the given item for all the metadata fields listed
|
||||||
* in the fields property and it'll return all those values as a list
|
* in the fields property and it'll return all those values as a list
|
||||||
|
@@ -44,6 +44,7 @@ public class Concatenate implements VirtualMetadataConfiguration {
|
|||||||
*/
|
*/
|
||||||
private boolean useForPlace = false;
|
private boolean useForPlace = false;
|
||||||
|
|
||||||
|
private boolean populateWithNameVariant = false;
|
||||||
/**
|
/**
|
||||||
* Generic getter for the fields property
|
* Generic getter for the fields property
|
||||||
* @return The list of fields to be used in this bean
|
* @return The list of fields to be used in this bean
|
||||||
@@ -80,6 +81,7 @@ public class Concatenate implements VirtualMetadataConfiguration {
|
|||||||
* Generic setter for the useForPlace property
|
* Generic setter for the useForPlace property
|
||||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setUseForPlace(boolean useForPlace) {
|
public void setUseForPlace(boolean useForPlace) {
|
||||||
this.useForPlace = useForPlace;
|
this.useForPlace = useForPlace;
|
||||||
}
|
}
|
||||||
@@ -88,10 +90,21 @@ public class Concatenate implements VirtualMetadataConfiguration {
|
|||||||
* Generic getter for the useForPlace property
|
* Generic getter for the useForPlace property
|
||||||
* @return The useForPlace to be used by this bean
|
* @return The useForPlace to be used by this bean
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean getUseForPlace() {
|
public boolean getUseForPlace() {
|
||||||
return useForPlace;
|
return useForPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPopulateWithNameVariant(boolean populateWithNameVariant) {
|
||||||
|
this.populateWithNameVariant = populateWithNameVariant;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPopulateWithNameVariant() {
|
||||||
|
return populateWithNameVariant;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this method will retrieve the metadata values from the given item for all the metadata fields listed
|
* this method will retrieve the metadata values from the given item for all the metadata fields listed
|
||||||
* in the fields property and it'll concatenate all those values together with the separator specified
|
* in the fields property and it'll concatenate all those values together with the separator specified
|
||||||
@@ -100,6 +113,7 @@ public class Concatenate implements VirtualMetadataConfiguration {
|
|||||||
* @param item The item that will be used to either retrieve metadata values from
|
* @param item The item that will be used to either retrieve metadata values from
|
||||||
* @return The String value for all of the retrieved metadatavalues combined with the separator
|
* @return The String value for all of the retrieved metadatavalues combined with the separator
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public List<String> getValues(Context context, Item item) {
|
public List<String> getValues(Context context, Item item) {
|
||||||
|
|
||||||
List<String> resultValues = new LinkedList<>();
|
List<String> resultValues = new LinkedList<>();
|
||||||
|
@@ -120,6 +120,7 @@ public class Related implements VirtualMetadataConfiguration {
|
|||||||
* Generic setter for the useForPlace property
|
* Generic setter for the useForPlace property
|
||||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setUseForPlace(boolean useForPlace) {
|
public void setUseForPlace(boolean useForPlace) {
|
||||||
this.useForPlace = useForPlace;
|
this.useForPlace = useForPlace;
|
||||||
}
|
}
|
||||||
@@ -128,10 +129,19 @@ public class Related implements VirtualMetadataConfiguration {
|
|||||||
* Generic getter for the useForPlace property
|
* Generic getter for the useForPlace property
|
||||||
* @return The useForPlace to be used by this bean
|
* @return The useForPlace to be used by this bean
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean getUseForPlace() {
|
public boolean getUseForPlace() {
|
||||||
return useForPlace;
|
return useForPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPopulateWithNameVariant(boolean populateWithNameVariant) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPopulateWithNameVariant() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will find the correct Relationship from the given item to retrieve the other item from it
|
* This method will find the correct Relationship from the given item to retrieve the other item from it
|
||||||
* and pass this along to the next VirtualBean that's stored in this class.
|
* and pass this along to the next VirtualBean that's stored in this class.
|
||||||
@@ -142,6 +152,7 @@ public class Related implements VirtualMetadataConfiguration {
|
|||||||
* Will return an empty list if no relationships are found
|
* Will return an empty list if no relationships are found
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public List<String> getValues(Context context, Item item) throws SQLException {
|
public List<String> getValues(Context context, Item item) throws SQLException {
|
||||||
Entity entity = entityService.findByItemId(context, item.getID());
|
Entity entity = entityService.findByItemId(context, item.getID());
|
||||||
EntityType entityType = entityService.getType(context, entity);
|
EntityType entityType = entityService.getType(context, entity);
|
||||||
@@ -149,8 +160,8 @@ public class Related implements VirtualMetadataConfiguration {
|
|||||||
List<RelationshipType> relationshipTypes = entityService.getAllRelationshipTypes(context, entity);
|
List<RelationshipType> relationshipTypes = entityService.getAllRelationshipTypes(context, entity);
|
||||||
List<RelationshipType> possibleRelationshipTypes = new LinkedList<>();
|
List<RelationshipType> possibleRelationshipTypes = new LinkedList<>();
|
||||||
for (RelationshipType relationshipType : relationshipTypes) {
|
for (RelationshipType relationshipType : relationshipTypes) {
|
||||||
if (StringUtils.equals(relationshipType.getLeftLabel(), relationshipTypeString) || StringUtils
|
if (StringUtils.equals(relationshipType.getLeftwardType(), relationshipTypeString) || StringUtils
|
||||||
.equals(relationshipType.getRightLabel(), relationshipTypeString)) {
|
.equals(relationshipType.getRightwardType(), relationshipTypeString)) {
|
||||||
possibleRelationshipTypes.add(relationshipType);
|
possibleRelationshipTypes.add(relationshipType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,4 +38,12 @@ public class UUIDValue implements VirtualMetadataConfiguration {
|
|||||||
public boolean getUseForPlace() {
|
public boolean getUseForPlace() {
|
||||||
return useForPlace;
|
return useForPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPopulateWithNameVariant(boolean populateWithNameVariant) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPopulateWithNameVariant() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,4 +42,18 @@ public interface VirtualMetadataConfiguration {
|
|||||||
* @return The useForPlace to be used by this bean
|
* @return The useForPlace to be used by this bean
|
||||||
*/
|
*/
|
||||||
boolean getUseForPlace();
|
boolean getUseForPlace();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the populateWithNameVariant
|
||||||
|
* This property defines whether the value should be retrieved from the left/rightward on the Relationship (true)
|
||||||
|
* or through the configuration and usual way (false)
|
||||||
|
* @param populateWithNameVariant The boolean value that the populateWithNameVariant property will be set to
|
||||||
|
*/
|
||||||
|
void setPopulateWithNameVariant(boolean populateWithNameVariant);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the populateWithNameVariant property
|
||||||
|
* @return The populatewithNameVariant to be used by this bean
|
||||||
|
*/
|
||||||
|
boolean getPopulateWithNameVariant();
|
||||||
}
|
}
|
||||||
|
@@ -42,17 +42,17 @@ public class VirtualMetadataPopulator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return a boolean indicating whether the useForPlace is true or false for the given
|
* This method will return a boolean indicating whether the useForPlace is true or false for the given
|
||||||
* RelationshipType for the left or right label as indicated by the second parameter.
|
* RelationshipType for the left or right type as indicated by the second parameter.
|
||||||
* @param relationshipType The relationshipType for which this should be checked
|
* @param relationshipType The relationshipType for which this should be checked
|
||||||
* @param isLeft The boolean indicating whether to check the left or the right label
|
* @param isLeft The boolean indicating whether to check the left or the right type
|
||||||
* @return A boolean indicating whether the useForPlace is true or not for the given parameters
|
* @return A boolean indicating whether the useForPlace is true or not for the given parameters
|
||||||
*/
|
*/
|
||||||
public boolean isUseForPlaceTrueForRelationshipType(RelationshipType relationshipType, boolean isLeft) {
|
public boolean isUseForPlaceTrueForRelationshipType(RelationshipType relationshipType, boolean isLeft) {
|
||||||
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
||||||
if (isLeft) {
|
if (isLeft) {
|
||||||
hashMaps = this.getMap().get(relationshipType.getLeftLabel());
|
hashMaps = this.getMap().get(relationshipType.getLeftwardType());
|
||||||
} else {
|
} else {
|
||||||
hashMaps = this.getMap().get(relationshipType.getRightLabel());
|
hashMaps = this.getMap().get(relationshipType.getRightwardType());
|
||||||
}
|
}
|
||||||
if (hashMaps != null) {
|
if (hashMaps != null) {
|
||||||
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
||||||
|
@@ -7,16 +7,28 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.harvest;
|
package org.dspace.harvest;
|
||||||
|
|
||||||
|
import static org.dspace.harvest.OAIHarvester.OAI_ADDRESS_ERROR;
|
||||||
|
import static org.dspace.harvest.OAIHarvester.OAI_DMD_ERROR;
|
||||||
|
import static org.dspace.harvest.OAIHarvester.OAI_ORE_ERROR;
|
||||||
|
import static org.dspace.harvest.OAIHarvester.OAI_SET_ERROR;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import ORG.oclc.oai.harvester2.verb.Identify;
|
||||||
|
import ORG.oclc.oai.harvester2.verb.ListIdentifiers;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.harvest.dao.HarvestedCollectionDAO;
|
import org.dspace.harvest.dao.HarvestedCollectionDAO;
|
||||||
import org.dspace.harvest.service.HarvestedCollectionService;
|
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.DOMBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,6 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
* @author kevinvandevelde at atmire.com
|
* @author kevinvandevelde at atmire.com
|
||||||
*/
|
*/
|
||||||
public class HarvestedCollectionServiceImpl implements HarvestedCollectionService {
|
public class HarvestedCollectionServiceImpl implements HarvestedCollectionService {
|
||||||
|
|
||||||
|
private static final Namespace ORE_NS = Namespace.getNamespace("http://www.openarchives.org/ore/terms/");
|
||||||
|
private static final Namespace OAI_NS = Namespace.getNamespace("http://www.openarchives.org/OAI/2.0/");
|
||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected HarvestedCollectionDAO harvestedCollectionDAO;
|
protected HarvestedCollectionDAO harvestedCollectionDAO;
|
||||||
|
|
||||||
@@ -156,5 +172,94 @@ public class HarvestedCollectionServiceImpl implements HarvestedCollectionServic
|
|||||||
return 0 < harvestedCollectionDAO.count(context);
|
return 0 < harvestedCollectionDAO.count(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the existence of an OAI server with the specified set and
|
||||||
|
* supporting the provided metadata formats.
|
||||||
|
*
|
||||||
|
* @param oaiSource the address of the OAI-PMH provider
|
||||||
|
* @param oaiSetId OAI set identifier
|
||||||
|
* @param metaPrefix OAI metadataPrefix
|
||||||
|
* @param testORE whether the method should also check the PMH provider for ORE support
|
||||||
|
* @return list of errors encountered during verification. Empty list indicates a "success" condition.
|
||||||
|
*/
|
||||||
|
public List<String> verifyOAIharvester(String oaiSource,
|
||||||
|
String oaiSetId, String metaPrefix, boolean testORE) {
|
||||||
|
List<String> errorSet = new ArrayList<String>();
|
||||||
|
|
||||||
|
// First, see if we can contact the target server at all.
|
||||||
|
try {
|
||||||
|
new Identify(oaiSource);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached.");
|
||||||
|
return errorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, make sure the metadata we need is supported by the target server
|
||||||
|
Namespace DMD_NS = OAIHarvester.getDMDNamespace(metaPrefix);
|
||||||
|
if (null == DMD_NS) {
|
||||||
|
errorSet.add(OAI_DMD_ERROR + ": " + metaPrefix);
|
||||||
|
return errorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OREOAIPrefix = null;
|
||||||
|
String DMDOAIPrefix = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OREOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, OAIHarvester.getORENamespace().getURI());
|
||||||
|
DMDOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, DMD_NS.getURI());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
errorSet.add(OAI_ADDRESS_ERROR
|
||||||
|
+ ": OAI did not respond to ListMetadataFormats query ("
|
||||||
|
+ ORE_NS.getPrefix() + ":" + OREOAIPrefix + " ; "
|
||||||
|
+ DMD_NS.getPrefix() + ":" + DMDOAIPrefix + "): "
|
||||||
|
+ ex.getMessage());
|
||||||
|
return errorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testORE && OREOAIPrefix == null) {
|
||||||
|
errorSet.add(OAI_ORE_ERROR + ": The OAI server does not support ORE dissemination");
|
||||||
|
}
|
||||||
|
if (DMDOAIPrefix == null) {
|
||||||
|
errorSet.add(OAI_DMD_ERROR + ": The OAI server does not support dissemination in this format");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now scan the sets and make sure the one supplied is in the list
|
||||||
|
boolean foundSet = false;
|
||||||
|
try {
|
||||||
|
//If we do not want to harvest from one set, then skip this.
|
||||||
|
if (!"all".equals(oaiSetId)) {
|
||||||
|
ListIdentifiers ls = new ListIdentifiers(oaiSource, null, null, oaiSetId, DMDOAIPrefix);
|
||||||
|
|
||||||
|
// The only error we can really get here is "noSetHierarchy"
|
||||||
|
if (ls.getErrors() != null && ls.getErrors().getLength() > 0) {
|
||||||
|
for (int i = 0; i < ls.getErrors().getLength(); i++) {
|
||||||
|
String errorCode = ls.getErrors().item(i).getAttributes().getNamedItem("code").getTextContent();
|
||||||
|
errorSet.add(
|
||||||
|
OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec (" +
|
||||||
|
errorCode + ")");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Drilling down to /OAI-PMH/ListSets/set
|
||||||
|
DOMBuilder db = new DOMBuilder();
|
||||||
|
Document reply = db.build(ls.getDocument());
|
||||||
|
Element root = reply.getRootElement();
|
||||||
|
//Check if we can find items, if so this indicates that we have children and our sets exist
|
||||||
|
foundSet = 0 < root.getChild("ListIdentifiers", OAI_NS).getChildren().size();
|
||||||
|
|
||||||
|
if (!foundSet) {
|
||||||
|
errorSet.add(OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached");
|
||||||
|
return errorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,14 @@ import java.sql.SQLException;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
@@ -28,7 +32,6 @@ import javax.xml.transform.TransformerException;
|
|||||||
|
|
||||||
import ORG.oclc.oai.harvester2.verb.GetRecord;
|
import ORG.oclc.oai.harvester2.verb.GetRecord;
|
||||||
import ORG.oclc.oai.harvester2.verb.Identify;
|
import ORG.oclc.oai.harvester2.verb.Identify;
|
||||||
import ORG.oclc.oai.harvester2.verb.ListIdentifiers;
|
|
||||||
import ORG.oclc.oai.harvester2.verb.ListMetadataFormats;
|
import ORG.oclc.oai.harvester2.verb.ListMetadataFormats;
|
||||||
import ORG.oclc.oai.harvester2.verb.ListRecords;
|
import ORG.oclc.oai.harvester2.verb.ListRecords;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -102,7 +105,7 @@ public class OAIHarvester {
|
|||||||
protected BitstreamFormatService bitstreamFormatService;
|
protected BitstreamFormatService bitstreamFormatService;
|
||||||
protected BundleService bundleService;
|
protected BundleService bundleService;
|
||||||
protected CollectionService collectionService;
|
protected CollectionService collectionService;
|
||||||
protected HarvestedCollectionService harvestedCollection;
|
protected HarvestedCollectionService harvestedCollectionService;
|
||||||
protected InstallItemService installItemService;
|
protected InstallItemService installItemService;
|
||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
protected HandleService handleService;
|
protected HandleService handleService;
|
||||||
@@ -140,7 +143,7 @@ public class OAIHarvester {
|
|||||||
bundleService = ContentServiceFactory.getInstance().getBundleService();
|
bundleService = ContentServiceFactory.getInstance().getBundleService();
|
||||||
collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||||
handleService = HandleServiceFactory.getInstance().getHandleService();
|
handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||||
harvestedCollection = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
|
harvestedCollectionService = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
|
||||||
harvestedItemService = HarvestServiceFactory.getInstance().getHarvestedItemService();
|
harvestedItemService = HarvestServiceFactory.getInstance().getHarvestedItemService();
|
||||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||||
installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||||
@@ -150,7 +153,6 @@ public class OAIHarvester {
|
|||||||
|
|
||||||
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
|
|
||||||
if (dso.getType() != Constants.COLLECTION) {
|
if (dso.getType() != Constants.COLLECTION) {
|
||||||
throw new HarvestingException("OAIHarvester can only harvest collections");
|
throw new HarvestingException("OAIHarvester can only harvest collections");
|
||||||
}
|
}
|
||||||
@@ -159,7 +161,7 @@ public class OAIHarvester {
|
|||||||
targetCollection = (Collection) dso;
|
targetCollection = (Collection) dso;
|
||||||
|
|
||||||
harvestRow = hc;
|
harvestRow = hc;
|
||||||
if (harvestRow == null || !harvestedCollection.isHarvestable(harvestRow)) {
|
if (harvestRow == null || !harvestedCollectionService.isHarvestable(harvestRow)) {
|
||||||
throw new HarvestingException("Provided collection is not set up for harvesting");
|
throw new HarvestingException("Provided collection is not set up for harvesting");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +190,7 @@ public class OAIHarvester {
|
|||||||
*
|
*
|
||||||
* @return Namespace of the supported ORE format. Returns null if not found.
|
* @return Namespace of the supported ORE format. Returns null if not found.
|
||||||
*/
|
*/
|
||||||
private static Namespace getORENamespace() {
|
public static Namespace getORENamespace() {
|
||||||
String ORESerializationString = null;
|
String ORESerializationString = null;
|
||||||
String ORESeialKey = null;
|
String ORESeialKey = null;
|
||||||
String oreString = "oai.harvester.oreSerializationFormat";
|
String oreString = "oai.harvester.oreSerializationFormat";
|
||||||
@@ -213,7 +215,7 @@ public class OAIHarvester {
|
|||||||
* @param metadataKey
|
* @param metadataKey
|
||||||
* @return Namespace of the designated metadata format. Returns null of not found.
|
* @return Namespace of the designated metadata format. Returns null of not found.
|
||||||
*/
|
*/
|
||||||
private static Namespace getDMDNamespace(String metadataKey) {
|
public static Namespace getDMDNamespace(String metadataKey) {
|
||||||
String metadataString = null;
|
String metadataString = null;
|
||||||
String metaString = "oai.harvester.metadataformats";
|
String metaString = "oai.harvester.metadataformats";
|
||||||
|
|
||||||
@@ -313,7 +315,7 @@ public class OAIHarvester {
|
|||||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_BUSY);
|
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_BUSY);
|
||||||
harvestRow.setHarvestMessage("Collection harvesting is initializing...");
|
harvestRow.setHarvestMessage("Collection harvesting is initializing...");
|
||||||
harvestRow.setHarvestStartTime(startTime);
|
harvestRow.setHarvestStartTime(startTime);
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
intermediateCommit();
|
intermediateCommit();
|
||||||
|
|
||||||
// expiration timer starts
|
// expiration timer starts
|
||||||
@@ -354,7 +356,7 @@ public class OAIHarvester {
|
|||||||
harvestRow.setHarvestStartTime(new Date());
|
harvestRow.setHarvestStartTime(new Date());
|
||||||
harvestRow.setHarvestMessage("OAI server did not contain any updates");
|
harvestRow.setHarvestMessage("OAI server did not contain any updates");
|
||||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new HarvestingException(errorSet.toString());
|
throw new HarvestingException(errorSet.toString());
|
||||||
@@ -411,7 +413,7 @@ public class OAIHarvester {
|
|||||||
harvestRow.setHarvestMessage(String
|
harvestRow.setHarvestMessage(String
|
||||||
.format("Collection is currently being harvested (item %d of %d)",
|
.format("Collection is currently being harvested (item %d of %d)",
|
||||||
currentRecord, totalListSize));
|
currentRecord, totalListSize));
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
} finally {
|
} finally {
|
||||||
//In case of an exception, make sure to restore our authentication state to the previous state
|
//In case of an exception, make sure to restore our authentication state to the previous state
|
||||||
ourContext.restoreAuthSystemState();
|
ourContext.restoreAuthSystemState();
|
||||||
@@ -429,19 +431,19 @@ public class OAIHarvester {
|
|||||||
alertAdmin(HarvestedCollection.STATUS_OAI_ERROR, hex);
|
alertAdmin(HarvestedCollection.STATUS_OAI_ERROR, hex);
|
||||||
}
|
}
|
||||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_OAI_ERROR);
|
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_OAI_ERROR);
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
ourContext.complete();
|
ourContext.complete();
|
||||||
return;
|
return;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
harvestRow.setHarvestMessage("Unknown error occurred while generating an OAI response");
|
harvestRow.setHarvestMessage("Unknown error occurred while generating an OAI response");
|
||||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_UNKNOWN_ERROR);
|
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_UNKNOWN_ERROR);
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
alertAdmin(HarvestedCollection.STATUS_UNKNOWN_ERROR, ex);
|
alertAdmin(HarvestedCollection.STATUS_UNKNOWN_ERROR, ex);
|
||||||
log.error("Error occurred while generating an OAI response: " + ex.getMessage() + " " + ex.getCause(), ex);
|
log.error("Error occurred while generating an OAI response: " + ex.getMessage() + " " + ex.getCause(), ex);
|
||||||
ourContext.complete();
|
ourContext.complete();
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
ourContext.turnOffAuthorisationSystem();
|
ourContext.turnOffAuthorisationSystem();
|
||||||
collectionService.update(ourContext, targetCollection);
|
collectionService.update(ourContext, targetCollection);
|
||||||
ourContext.restoreAuthSystemState();
|
ourContext.restoreAuthSystemState();
|
||||||
@@ -456,7 +458,7 @@ public class OAIHarvester {
|
|||||||
log.info(
|
log.info(
|
||||||
"Harvest from " + oaiSource + " successful. The process took " + timeTaken + " milliseconds. Harvested "
|
"Harvest from " + oaiSource + " successful. The process took " + timeTaken + " milliseconds. Harvested "
|
||||||
+ currentRecord + " items.");
|
+ currentRecord + " items.");
|
||||||
harvestedCollection.update(ourContext, harvestRow);
|
harvestedCollectionService.update(ourContext, harvestRow);
|
||||||
|
|
||||||
ourContext.setMode(originalMode);
|
ourContext.setMode(originalMode);
|
||||||
}
|
}
|
||||||
@@ -900,94 +902,44 @@ public class OAIHarvester {
|
|||||||
String oaiSetId = harvestRow.getOaiSetId();
|
String oaiSetId = harvestRow.getOaiSetId();
|
||||||
String metaPrefix = harvestRow.getHarvestMetadataConfig();
|
String metaPrefix = harvestRow.getHarvestMetadataConfig();
|
||||||
|
|
||||||
return verifyOAIharvester(oaiSource, oaiSetId, metaPrefix, true);
|
return harvestedCollectionService.verifyOAIharvester(oaiSource, oaiSetId, metaPrefix, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the existence of an OAI server with the specified set and
|
* Return all available metadata formats
|
||||||
* supporting the provided metadata formats.
|
|
||||||
*
|
*
|
||||||
* @param oaiSource the address of the OAI-PMH provider
|
* @return a list containing a map for each supported metadata format
|
||||||
* @param oaiSetId OAI set identifier
|
|
||||||
* @param metaPrefix OAI metadataPrefix
|
|
||||||
* @param testORE whether the method should also check the PMH provider for ORE support
|
|
||||||
* @return list of errors encountered during verification. Empty list indicates a "success" condition.
|
|
||||||
*/
|
*/
|
||||||
public static List<String> verifyOAIharvester(String oaiSource,
|
public static List<Map<String,String>> getAvailableMetadataFormats() {
|
||||||
String oaiSetId, String metaPrefix, boolean testORE) {
|
List<Map<String,String>> configs = new ArrayList<>();
|
||||||
List<String> errorSet = new ArrayList<String>();
|
String metaString = "oai.harvester.metadataformats.";
|
||||||
|
Enumeration pe = Collections.enumeration(
|
||||||
|
DSpaceServicesFactory.getInstance().getConfigurationService()
|
||||||
|
.getPropertyKeys("oai.harvester.metadataformats")
|
||||||
|
);
|
||||||
|
while (pe.hasMoreElements()) {
|
||||||
|
String key = (String) pe.nextElement();
|
||||||
|
String metadataString = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty(key);
|
||||||
|
|
||||||
// First, see if we can contact the target server at all.
|
String id = key.substring(metaString.length());
|
||||||
try {
|
String label;
|
||||||
new Identify(oaiSource);
|
String namespace = "";
|
||||||
} catch (Exception ex) {
|
|
||||||
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached.");
|
|
||||||
return errorSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, make sure the metadata we need is supported by the target server
|
if (metadataString.indexOf(',') != -1) {
|
||||||
Namespace DMD_NS = OAIHarvester.getDMDNamespace(metaPrefix);
|
label = metadataString.substring(metadataString.indexOf(',') + 2);
|
||||||
if (null == DMD_NS) {
|
namespace = metadataString.substring(0, metadataString.indexOf(','));
|
||||||
errorSet.add(OAI_DMD_ERROR + ": " + metaPrefix);
|
} else {
|
||||||
return errorSet;
|
label = id + "(" + metadataString + ")";
|
||||||
}
|
|
||||||
|
|
||||||
String OREOAIPrefix = null;
|
|
||||||
String DMDOAIPrefix = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
OREOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, getORENamespace().getURI());
|
|
||||||
DMDOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, DMD_NS.getURI());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
errorSet.add(OAI_ADDRESS_ERROR
|
|
||||||
+ ": OAI did not respond to ListMetadataFormats query ("
|
|
||||||
+ ORE_NS.getPrefix() + ":" + OREOAIPrefix + " ; "
|
|
||||||
+ DMD_NS.getPrefix() + ":" + DMDOAIPrefix + "): "
|
|
||||||
+ ex.getMessage());
|
|
||||||
return errorSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (testORE && OREOAIPrefix == null) {
|
|
||||||
errorSet.add(OAI_ORE_ERROR + ": The OAI server does not support ORE dissemination");
|
|
||||||
}
|
|
||||||
if (DMDOAIPrefix == null) {
|
|
||||||
errorSet.add(OAI_DMD_ERROR + ": The OAI server does not support dissemination in this format");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now scan the sets and make sure the one supplied is in the list
|
|
||||||
boolean foundSet = false;
|
|
||||||
try {
|
|
||||||
//If we do not want to harvest from one set, then skip this.
|
|
||||||
if (!"all".equals(oaiSetId)) {
|
|
||||||
ListIdentifiers ls = new ListIdentifiers(oaiSource, null, null, oaiSetId, DMDOAIPrefix);
|
|
||||||
|
|
||||||
// The only error we can really get here is "noSetHierarchy"
|
|
||||||
if (ls.getErrors() != null && ls.getErrors().getLength() > 0) {
|
|
||||||
for (int i = 0; i < ls.getErrors().getLength(); i++) {
|
|
||||||
String errorCode = ls.getErrors().item(i).getAttributes().getNamedItem("code").getTextContent();
|
|
||||||
errorSet.add(
|
|
||||||
OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec (" +
|
|
||||||
errorCode + ")");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Drilling down to /OAI-PMH/ListSets/set
|
|
||||||
Document reply = db.build(ls.getDocument());
|
|
||||||
Element root = reply.getRootElement();
|
|
||||||
//Check if we can find items, if so this indicates that we have children and our sets exist
|
|
||||||
foundSet = 0 < root.getChild("ListIdentifiers", OAI_NS).getChildren().size();
|
|
||||||
|
|
||||||
if (!foundSet) {
|
|
||||||
errorSet.add(OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (RuntimeException re) {
|
|
||||||
throw re;
|
Map<String,String> config = new HashMap<>();
|
||||||
} catch (Exception e) {
|
config.put("id", id);
|
||||||
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached");
|
config.put("label", label);
|
||||||
return errorSet;
|
config.put("namespace", namespace);
|
||||||
|
|
||||||
|
configs.add(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorSet;
|
return configs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -137,4 +137,15 @@ public interface HarvestedCollectionService {
|
|||||||
public void update(Context context, HarvestedCollection harvestedCollection) throws SQLException;
|
public void update(Context context, HarvestedCollection harvestedCollection) throws SQLException;
|
||||||
|
|
||||||
public boolean exists(Context context) throws SQLException;
|
public boolean exists(Context context) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the given harvest settings
|
||||||
|
* @param oaiSource the address of the OAI-PMH provider
|
||||||
|
* @param oaiSetId OAI set identifier
|
||||||
|
* @param metaPrefix OAI metadataPrefix
|
||||||
|
* @param testORE whether the method should also check the PMH provider for ORE support
|
||||||
|
* @return list of errors encountered during verification. An empty list indicates a "success" condition.
|
||||||
|
*/
|
||||||
|
public List<String> verifyOAIharvester(String oaiSource,
|
||||||
|
String oaiSetId, String metaPrefix, boolean testORE);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
-- Create columns leftwardValue and rightwardValue in table relationship
|
||||||
|
-- Rename columns left_label and right_label to leftward_type and rightward_type
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALTER TABLE relationship ADD leftward_value VARCHAR;
|
||||||
|
ALTER TABLE relationship ADD rightward_value VARCHAR;
|
||||||
|
|
||||||
|
ALTER TABLE relationship_type ALTER COLUMN left_label RENAME TO leftward_type;
|
||||||
|
ALTER TABLE relationship_type ALTER COLUMN right_label RENAME TO rightward_type;
|
@@ -0,0 +1,18 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
-- Create columns leftwardValue and rightwardValue in table relationship
|
||||||
|
-- Rename columns left_label and right_label to leftward_type and rightward_type
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALTER TABLE relationship ADD leftward_value VARCHAR;
|
||||||
|
ALTER TABLE relationship ADD rightward_value VARCHAR;
|
||||||
|
|
||||||
|
ALTER TABLE relationship_type RENAME left_label TO leftward_type;
|
||||||
|
ALTER TABLE relationship_type RENAME right_label TO rightward_type;
|
@@ -0,0 +1,18 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
-- Create columns leftwardValue and rightwardValue in table relationship
|
||||||
|
-- Rename columns left_label and right_label to leftward_type and rightward_type
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALTER TABLE relationship ADD leftward_value VARCHAR;
|
||||||
|
ALTER TABLE relationship ADD rightward_value VARCHAR;
|
||||||
|
|
||||||
|
ALTER TABLE relationship_type RENAME COLUMN left_label TO leftward_type;
|
||||||
|
ALTER TABLE relationship_type RENAME COLUMN right_label TO rightward_type;
|
@@ -5,8 +5,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>Person</rightType>
|
<rightType>Person</rightType>
|
||||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>10</min>
|
<min>10</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>Project</rightType>
|
<rightType>Project</rightType>
|
||||||
<leftLabel>isProjectOfPublication</leftLabel>
|
<leftwardType>isProjectOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfProject</rightLabel>
|
<rightwardType>isPublicationOfProject</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfPublication</leftLabel>
|
<leftwardType>isOrgUnitOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfOrgUnit</rightLabel>
|
<rightwardType>isPublicationOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -41,8 +41,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Person</leftType>
|
<leftType>Person</leftType>
|
||||||
<rightType>Project</rightType>
|
<rightType>Project</rightType>
|
||||||
<leftLabel>isProjectOfPerson</leftLabel>
|
<leftwardType>isProjectOfPerson</leftwardType>
|
||||||
<rightLabel>isPersonOfProject</rightLabel>
|
<rightwardType>isPersonOfProject</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -53,8 +53,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Person</leftType>
|
<leftType>Person</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfPerson</leftLabel>
|
<leftwardType>isOrgUnitOfPerson</leftwardType>
|
||||||
<rightLabel>isPersonOfOrgUnit</rightLabel>
|
<rightwardType>isPersonOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -65,8 +65,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Project</leftType>
|
<leftType>Project</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfProject</leftLabel>
|
<leftwardType>isOrgUnitOfProject</leftwardType>
|
||||||
<rightLabel>isProjectOfOrgUnit</rightLabel>
|
<rightwardType>isProjectOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Journal</leftType>
|
<leftType>Journal</leftType>
|
||||||
<rightType>JournalVolume</rightType>
|
<rightType>JournalVolume</rightType>
|
||||||
<leftLabel>isVolumeOfJournal</leftLabel>
|
<leftwardType>isVolumeOfJournal</leftwardType>
|
||||||
<rightLabel>isJournalOfVolume</rightLabel>
|
<rightwardType>isJournalOfVolume</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -89,8 +89,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>JournalVolume</leftType>
|
<leftType>JournalVolume</leftType>
|
||||||
<rightType>JournalIssue</rightType>
|
<rightType>JournalIssue</rightType>
|
||||||
<leftLabel>isIssueOfJournalVolume</leftLabel>
|
<leftwardType>isIssueOfJournalVolume</leftwardType>
|
||||||
<rightLabel>isJournalVolumeOfIssue</rightLabel>
|
<rightwardType>isJournalVolumeOfIssue</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -102,8 +102,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -114,8 +114,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>JournalIssue</leftType>
|
<leftType>JournalIssue</leftType>
|
||||||
<rightType>Publication</rightType>
|
<rightType>Publication</rightType>
|
||||||
<leftLabel>isPublicationOfJournalIssue</leftLabel>
|
<leftwardType>isPublicationOfJournalIssue</leftwardType>
|
||||||
<rightLabel>isJournalIssueOfPublication</rightLabel>
|
<rightwardType>isJournalIssueOfPublication</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
|
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
|
|
||||||
<!ELEMENT relationships (type)*>
|
<!ELEMENT relationships (type)*>
|
||||||
<!ELEMENT type (leftType|rightType|leftLabel|rightLabel|leftCardinality|rightCardinality)*>
|
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality)*>
|
||||||
<!ELEMENT leftType (#PCDATA)>
|
<!ELEMENT leftType (#PCDATA)>
|
||||||
<!ELEMENT rightType (#PCDATA)>
|
<!ELEMENT rightType (#PCDATA)>
|
||||||
<!ELEMENT leftLabel (#PCDATA)>
|
<!ELEMENT leftwardType (#PCDATA)>
|
||||||
<!ELEMENT rightLabel (#PCDATA)>
|
<!ELEMENT rightwardType (#PCDATA)>
|
||||||
<!ELEMENT leftCardinality (min|max)*>
|
<!ELEMENT leftCardinality (min|max)*>
|
||||||
<!ELEMENT min (#PCDATA)>
|
<!ELEMENT min (#PCDATA)>
|
||||||
<!ELEMENT rightCardinality (min|max)*>
|
<!ELEMENT rightCardinality (min|max)*>
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>Person</rightType>
|
<rightType>Person</rightType>
|
||||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>Project</rightType>
|
<rightType>Project</rightType>
|
||||||
<leftLabel>isProjectOfPublication</leftLabel>
|
<leftwardType>isProjectOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfProject</rightLabel>
|
<rightwardType>isPublicationOfProject</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfPublication</leftLabel>
|
<leftwardType>isOrgUnitOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfOrgUnit</rightLabel>
|
<rightwardType>isPublicationOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -41,8 +41,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Person</leftType>
|
<leftType>Person</leftType>
|
||||||
<rightType>Project</rightType>
|
<rightType>Project</rightType>
|
||||||
<leftLabel>isProjectOfPerson</leftLabel>
|
<leftwardType>isProjectOfPerson</leftwardType>
|
||||||
<rightLabel>isPersonOfProject</rightLabel>
|
<rightwardType>isPersonOfProject</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -53,8 +53,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Person</leftType>
|
<leftType>Person</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfPerson</leftLabel>
|
<leftwardType>isOrgUnitOfPerson</leftwardType>
|
||||||
<rightLabel>isPersonOfOrgUnit</rightLabel>
|
<rightwardType>isPersonOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -65,8 +65,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Project</leftType>
|
<leftType>Project</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isOrgUnitOfProject</leftLabel>
|
<leftwardType>isOrgUnitOfProject</leftwardType>
|
||||||
<rightLabel>isProjectOfOrgUnit</rightLabel>
|
<rightwardType>isProjectOfOrgUnit</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Journal</leftType>
|
<leftType>Journal</leftType>
|
||||||
<rightType>JournalVolume</rightType>
|
<rightType>JournalVolume</rightType>
|
||||||
<leftLabel>isVolumeOfJournal</leftLabel>
|
<leftwardType>isVolumeOfJournal</leftwardType>
|
||||||
<rightLabel>isJournalOfVolume</rightLabel>
|
<rightwardType>isJournalOfVolume</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -89,8 +89,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>JournalVolume</leftType>
|
<leftType>JournalVolume</leftType>
|
||||||
<rightType>JournalIssue</rightType>
|
<rightType>JournalIssue</rightType>
|
||||||
<leftLabel>isIssueOfJournalVolume</leftLabel>
|
<leftwardType>isIssueOfJournalVolume</leftwardType>
|
||||||
<rightLabel>isJournalVolumeOfIssue</rightLabel>
|
<rightwardType>isJournalVolumeOfIssue</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -102,8 +102,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>Publication</leftType>
|
<leftType>Publication</leftType>
|
||||||
<rightType>OrgUnit</rightType>
|
<rightType>OrgUnit</rightType>
|
||||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
@@ -114,8 +114,8 @@
|
|||||||
<type>
|
<type>
|
||||||
<leftType>JournalIssue</leftType>
|
<leftType>JournalIssue</leftType>
|
||||||
<rightType>Publication</rightType>
|
<rightType>Publication</rightType>
|
||||||
<leftLabel>isPublicationOfJournalIssue</leftLabel>
|
<leftwardType>isPublicationOfJournalIssue</leftwardType>
|
||||||
<rightLabel>isJournalIssueOfPublication</rightLabel>
|
<rightwardType>isJournalIssueOfPublication</rightwardType>
|
||||||
<leftCardinality>
|
<leftCardinality>
|
||||||
<min>0</min>
|
<min>0</min>
|
||||||
</leftCardinality>
|
</leftCardinality>
|
||||||
|
@@ -145,15 +145,15 @@ public class EntityServiceImplTest {
|
|||||||
List<Relationship> relationshipList = new ArrayList<>();
|
List<Relationship> relationshipList = new ArrayList<>();
|
||||||
relationshipList.add(relationship);
|
relationshipList.add(relationship);
|
||||||
|
|
||||||
// Mock the state of objects utilized in getRelationsByLabel() to meet the success criteria of an invocation
|
// Mock the state of objects utilized in getRelationsByType() to meet the success criteria of an invocation
|
||||||
when(relationshipService.findAll(context)).thenReturn(relationshipList);
|
when(relationshipService.findAll(context)).thenReturn(relationshipList);
|
||||||
when(relationship.getRelationshipType()).thenReturn(relationshipType);
|
when(relationship.getRelationshipType()).thenReturn(relationshipType);
|
||||||
when(relationshipType.getLeftLabel()).thenReturn("leftLabel");
|
when(relationshipType.getLeftwardType()).thenReturn("leftwardType");
|
||||||
when(relationshipType.getRightLabel()).thenReturn("rightLabel");
|
when(relationshipType.getRightwardType()).thenReturn("rightwardType");
|
||||||
|
|
||||||
// The relation(s) reported from our defined label should match our relationshipList
|
// The relation(s) reported from our defined type should match our relationshipList
|
||||||
assertEquals("TestGetRelationsByLabel 0", relationshipList,
|
assertEquals("TestGetRelationsByLabel 0", relationshipList,
|
||||||
entityService.getRelationsByLabel(context, "leftLabel"));
|
entityService.getRelationsByLabel(context, "leftwardType"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -260,15 +260,15 @@ public class EntityServiceImplTest {
|
|||||||
RelationshipType relationshipType = mock(RelationshipType.class);
|
RelationshipType relationshipType = mock(RelationshipType.class);
|
||||||
list.add(relationshipType);
|
list.add(relationshipType);
|
||||||
|
|
||||||
// Mock the state of objects utilized in getRelationshipTypesByLabel()
|
// Mock the state of objects utilized in getRelationshipTypesByTypeName()
|
||||||
// to meet the success criteria of the invocation
|
// to meet the success criteria of the invocation
|
||||||
when(relationshipTypeService.findAll(context)).thenReturn(list);
|
when(relationshipTypeService.findAll(context)).thenReturn(list);
|
||||||
when(relationshipType.getLeftLabel()).thenReturn("leftLabel");
|
when(relationshipType.getLeftwardType()).thenReturn("leftwardType");
|
||||||
when(relationshipType.getRightLabel()).thenReturn("rightLabel");
|
when(relationshipType.getRightwardType()).thenReturn("rightwardType");
|
||||||
|
|
||||||
// The RelationshipType(s) reported from our mocked Entity should match our list
|
// The RelationshipType(s) reported from our mocked Entity should match our list
|
||||||
assertEquals("TestGetRelationshipTypesByLabel 0", list,
|
assertEquals("TestGetRelationshipTypesByLabel 0", list,
|
||||||
entityService.getRelationshipTypesByLabel(context, "leftLabel"));
|
entityService.getRelationshipTypesByTypeName(context, "leftwardType"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -0,0 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* 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 static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.AbstractUnitTest;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
|
import org.dspace.content.service.EntityService;
|
||||||
|
import org.dspace.content.service.EntityTypeService;
|
||||||
|
import org.dspace.content.service.InstallItemService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class RelationshipMetadataServiceTest extends AbstractUnitTest {
|
||||||
|
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
|
.getLogger(RelationshipMetadataServiceTest.class);
|
||||||
|
|
||||||
|
protected RelationshipMetadataService relationshipMetadataService = ContentServiceFactory
|
||||||
|
.getInstance().getRelationshipMetadataService();
|
||||||
|
protected RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||||
|
protected RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||||
|
.getRelationshipTypeService();
|
||||||
|
protected EntityService entityService = ContentServiceFactory.getInstance().getEntityService();
|
||||||
|
protected EntityTypeService entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
|
||||||
|
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||||
|
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||||
|
protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||||
|
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||||
|
|
||||||
|
Item item;
|
||||||
|
Item authorItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run before every test as per @Before. It will
|
||||||
|
* initialize resources required for the tests.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @Before here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
try {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Community community = communityService.create(null, context);
|
||||||
|
|
||||||
|
Collection col = collectionService.create(context, community);
|
||||||
|
WorkspaceItem is = workspaceItemService.create(context, col, false);
|
||||||
|
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
|
||||||
|
|
||||||
|
item = installItemService.installItem(context, is);
|
||||||
|
authorItem = installItemService.installItem(context, authorIs);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
} catch (AuthorizeException ex) {
|
||||||
|
log.error("Authorization Error in init", ex);
|
||||||
|
fail("Authorization Error in init: " + ex.getMessage());
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
log.error("SQL Error in init", ex);
|
||||||
|
fail("SQL Error in init: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run after every test as per @After. It will
|
||||||
|
* clean resources initialized by the @Before methods.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @After here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
context.abort();
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRelationshipMetadata() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
|
||||||
|
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Author");
|
||||||
|
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
|
||||||
|
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
|
||||||
|
EntityType publicationEntityType = entityTypeService.create(context, "Publication");
|
||||||
|
EntityType authorEntityType = entityTypeService.create(context, "Author");
|
||||||
|
RelationshipType isAuthorOfPublication = relationshipTypeService
|
||||||
|
.create(context, publicationEntityType, authorEntityType, "isAuthorOfPublication", "isPublicationOfAuthor",
|
||||||
|
null, null, null, null);
|
||||||
|
|
||||||
|
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 0, 0);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
List<MetadataValue> authorList = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY);
|
||||||
|
assertThat(authorList.size(), equalTo(1));
|
||||||
|
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
|
||||||
|
|
||||||
|
List<MetadataValue> relationshipMetadataList = itemService
|
||||||
|
.getMetadata(item, "relation", "isAuthorOfPublication", null, Item.ANY);
|
||||||
|
assertThat(relationshipMetadataList.size(), equalTo(1));
|
||||||
|
assertThat(relationshipMetadataList.get(0).getValue(), equalTo(String.valueOf(authorItem.getID())));
|
||||||
|
|
||||||
|
List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(item, true);
|
||||||
|
assertThat(list.size(), equalTo(2));
|
||||||
|
assertThat(list.get(0).getValue(), equalTo("familyName, firstName"));
|
||||||
|
assertThat(list.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
|
||||||
|
assertThat(list.get(0).getMetadataField().getElement(), equalTo("contributor"));
|
||||||
|
assertThat(list.get(0).getMetadataField().getQualifier(), equalTo("author"));
|
||||||
|
assertThat(list.get(0).getAuthority(), equalTo("virtual::" + relationship.getID()));
|
||||||
|
|
||||||
|
assertThat(list.get(1).getValue(), equalTo(String.valueOf(authorItem.getID())));
|
||||||
|
assertThat(list.get(1).getMetadataField().getMetadataSchema().getName(), equalTo("relation"));
|
||||||
|
assertThat(list.get(1).getMetadataField().getElement(), equalTo("isAuthorOfPublication"));
|
||||||
|
assertThat(list.get(1).getAuthority(), equalTo("virtual::" + relationship.getID()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -84,12 +84,12 @@ public class RelationshipServiceImplTest {
|
|||||||
RelationshipType hasDog = new RelationshipType();
|
RelationshipType hasDog = new RelationshipType();
|
||||||
RelationshipType hasFather = new RelationshipType();
|
RelationshipType hasFather = new RelationshipType();
|
||||||
RelationshipType hasMother = new RelationshipType();
|
RelationshipType hasMother = new RelationshipType();
|
||||||
hasDog.setLeftLabel("hasDog");
|
hasDog.setLeftwardType("hasDog");
|
||||||
hasDog.setRightLabel("isDogOf");
|
hasDog.setRightwardType("isDogOf");
|
||||||
hasFather.setLeftLabel("hasFather");
|
hasFather.setLeftwardType("hasFather");
|
||||||
hasFather.setRightLabel("isFatherOf");
|
hasFather.setRightwardType("isFatherOf");
|
||||||
hasMother.setLeftLabel("hasMother");
|
hasMother.setLeftwardType("hasMother");
|
||||||
hasMother.setRightLabel("isMotherOf");
|
hasMother.setRightwardType("isMotherOf");
|
||||||
|
|
||||||
relationshipTest.add(getRelationship(cindy, spot, hasDog,0,0));
|
relationshipTest.add(getRelationship(cindy, spot, hasDog,0,0));
|
||||||
relationshipTest.add(getRelationship(cindy, jasper, hasDog,0,1));
|
relationshipTest.add(getRelationship(cindy, jasper, hasDog,0,1));
|
||||||
@@ -194,8 +194,8 @@ public class RelationshipServiceImplTest {
|
|||||||
EntityType rightEntityType = mock(EntityType.class);
|
EntityType rightEntityType = mock(EntityType.class);
|
||||||
testRel.setLeftType(leftEntityType);
|
testRel.setLeftType(leftEntityType);
|
||||||
testRel.setRightType(rightEntityType);
|
testRel.setRightType(rightEntityType);
|
||||||
testRel.setLeftLabel("Entitylabel");
|
testRel.setLeftwardType("Entitylabel");
|
||||||
testRel.setRightLabel("Entitylabel");
|
testRel.setRightwardType("Entitylabel");
|
||||||
metsList.add(metVal);
|
metsList.add(metVal);
|
||||||
relationship = getRelationship(leftItem, rightItem, testRel, 0,0);
|
relationship = getRelationship(leftItem, rightItem, testRel, 0,0);
|
||||||
leftTypelist.add(relationship);
|
leftTypelist.add(relationship);
|
||||||
@@ -247,8 +247,8 @@ public class RelationshipServiceImplTest {
|
|||||||
EntityType rightEntityType = mock(EntityType.class);
|
EntityType rightEntityType = mock(EntityType.class);
|
||||||
testRel.setLeftType(leftEntityType);
|
testRel.setLeftType(leftEntityType);
|
||||||
testRel.setRightType(rightEntityType);
|
testRel.setRightType(rightEntityType);
|
||||||
testRel.setLeftLabel("Entitylabel");
|
testRel.setLeftwardType("Entitylabel");
|
||||||
testRel.setRightLabel("Entitylabel");
|
testRel.setRightwardType("Entitylabel");
|
||||||
testRel.setLeftMinCardinality(0);
|
testRel.setLeftMinCardinality(0);
|
||||||
testRel.setRightMinCardinality(0);
|
testRel.setRightMinCardinality(0);
|
||||||
metsList.add(metVal);
|
metsList.add(metVal);
|
||||||
@@ -299,8 +299,8 @@ public class RelationshipServiceImplTest {
|
|||||||
EntityType rightEntityType = mock(EntityType.class);
|
EntityType rightEntityType = mock(EntityType.class);
|
||||||
testRel.setLeftType(leftEntityType);
|
testRel.setLeftType(leftEntityType);
|
||||||
testRel.setRightType(rightEntityType);
|
testRel.setRightType(rightEntityType);
|
||||||
testRel.setLeftLabel("Entitylabel");
|
testRel.setLeftwardType("Entitylabel");
|
||||||
testRel.setRightLabel("Entitylabel");
|
testRel.setRightwardType("Entitylabel");
|
||||||
testRel.setLeftMinCardinality(0);
|
testRel.setLeftMinCardinality(0);
|
||||||
testRel.setRightMinCardinality(0);
|
testRel.setRightMinCardinality(0);
|
||||||
metsList.add(metVal);
|
metsList.add(metVal);
|
||||||
|
@@ -51,8 +51,8 @@ public class RelationshipTypeTest {
|
|||||||
firstRelationshipType.setId(1);
|
firstRelationshipType.setId(1);
|
||||||
firstRelationshipType.setLeftType(mock(EntityType.class));
|
firstRelationshipType.setLeftType(mock(EntityType.class));
|
||||||
firstRelationshipType.setRightType(mock(EntityType.class));
|
firstRelationshipType.setRightType(mock(EntityType.class));
|
||||||
firstRelationshipType.setLeftLabel("isAuthorOfPublication");
|
firstRelationshipType.setLeftwardType("isAuthorOfPublication");
|
||||||
firstRelationshipType.setRightLabel("isPublicationOfAuthor");
|
firstRelationshipType.setRightwardType("isPublicationOfAuthor");
|
||||||
firstRelationshipType.setLeftMinCardinality(0);
|
firstRelationshipType.setLeftMinCardinality(0);
|
||||||
firstRelationshipType.setLeftMaxCardinality(null);
|
firstRelationshipType.setLeftMaxCardinality(null);
|
||||||
firstRelationshipType.setRightMinCardinality(0);
|
firstRelationshipType.setRightMinCardinality(0);
|
||||||
@@ -63,8 +63,8 @@ public class RelationshipTypeTest {
|
|||||||
secondRelationshipType.setId(new Random().nextInt());
|
secondRelationshipType.setId(new Random().nextInt());
|
||||||
secondRelationshipType.setLeftType(mock(EntityType.class));
|
secondRelationshipType.setLeftType(mock(EntityType.class));
|
||||||
secondRelationshipType.setRightType(mock(EntityType.class));
|
secondRelationshipType.setRightType(mock(EntityType.class));
|
||||||
secondRelationshipType.setLeftLabel("isProjectOfPerson");
|
secondRelationshipType.setLeftwardType("isProjectOfPerson");
|
||||||
secondRelationshipType.setRightLabel("isPersonOfProject");
|
secondRelationshipType.setRightwardType("isPersonOfProject");
|
||||||
secondRelationshipType.setLeftMinCardinality(0);
|
secondRelationshipType.setLeftMinCardinality(0);
|
||||||
secondRelationshipType.setLeftMaxCardinality(null);
|
secondRelationshipType.setLeftMaxCardinality(null);
|
||||||
secondRelationshipType.setRightMinCardinality(0);
|
secondRelationshipType.setRightMinCardinality(0);
|
||||||
@@ -118,16 +118,16 @@ public class RelationshipTypeTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelationshipTypeFindByLeftOrRightLabel() throws Exception {
|
public void testRelationshipTypeFindByLeftOrRightwardType() throws Exception {
|
||||||
// Declare objects utilized for this test
|
// Declare objects utilized for this test
|
||||||
List<RelationshipType> mockedList = new LinkedList<>();
|
List<RelationshipType> mockedList = new LinkedList<>();
|
||||||
mockedList.add(firstRelationshipType);
|
mockedList.add(firstRelationshipType);
|
||||||
|
|
||||||
// Mock DAO to return our mockedList
|
// Mock DAO to return our mockedList
|
||||||
when(relationshipTypeDAO.findByLeftOrRightLabel(any(), any())).thenReturn(mockedList);
|
when(relationshipTypeDAO.findByLeftwardOrRightwardTypeName(any(), any())).thenReturn(mockedList);
|
||||||
|
|
||||||
// Invoke findByLeftOrRightLabel()
|
// Invoke findByLeftwardOrRightwardTypeName()
|
||||||
List<RelationshipType> found = relationshipTypeService.findByLeftOrRightLabel(context, "mock");
|
List<RelationshipType> found = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, "mock");
|
||||||
|
|
||||||
// Assert that our expected list contains our expected RelationshipType and nothing more
|
// Assert that our expected list contains our expected RelationshipType and nothing more
|
||||||
assertThat(found, notNullValue());
|
assertThat(found, notNullValue());
|
||||||
@@ -160,8 +160,8 @@ public class RelationshipTypeTest {
|
|||||||
*/
|
*/
|
||||||
private void checkRelationshipTypeValues(RelationshipType found, RelationshipType original) {
|
private void checkRelationshipTypeValues(RelationshipType found, RelationshipType original) {
|
||||||
assertThat(found, notNullValue());
|
assertThat(found, notNullValue());
|
||||||
assertThat(found.getLeftLabel(), equalTo(original.getLeftLabel()));
|
assertThat(found.getLeftwardType(), equalTo(original.getLeftwardType()));
|
||||||
assertThat(found.getRightLabel(), equalTo(original.getRightLabel()));
|
assertThat(found.getRightwardType(), equalTo(original.getRightwardType()));
|
||||||
assertThat(found.getLeftType(), equalTo(original.getLeftType()));
|
assertThat(found.getLeftType(), equalTo(original.getLeftType()));
|
||||||
assertThat(found.getRightType(), equalTo(original.getRightType()));
|
assertThat(found.getRightType(), equalTo(original.getRightType()));
|
||||||
assertThat(found.getLeftMinCardinality(), equalTo(original.getLeftMinCardinality()));
|
assertThat(found.getLeftMinCardinality(), equalTo(original.getLeftMinCardinality()));
|
||||||
|
@@ -124,15 +124,15 @@ public class RelatedTest {
|
|||||||
Entity entity = mock(Entity.class);
|
Entity entity = mock(Entity.class);
|
||||||
EntityType entityType = mock(EntityType.class);
|
EntityType entityType = mock(EntityType.class);
|
||||||
RelationshipType relationshipType = mock(RelationshipType.class);
|
RelationshipType relationshipType = mock(RelationshipType.class);
|
||||||
related.setRelationshipTypeString("LeftLabel");
|
related.setRelationshipTypeString("LeftwardType");
|
||||||
relationshipTypeList.add(relationshipType);
|
relationshipTypeList.add(relationshipType);
|
||||||
relationshipList.add(relationship);
|
relationshipList.add(relationship);
|
||||||
related.setPlace(0);
|
related.setPlace(0);
|
||||||
|
|
||||||
// Mock the state of objects utilized in getRelationsByLabel() to meet the success criteria of an invocation
|
// Mock the state of objects utilized in getRelationsByLabel() to meet the success criteria of an invocation
|
||||||
when(item.getID()).thenReturn(UUID.randomUUID());
|
when(item.getID()).thenReturn(UUID.randomUUID());
|
||||||
when(relationshipType.getLeftLabel()).thenReturn("LeftLabel");
|
when(relationshipType.getLeftwardType()).thenReturn("LeftwardType");
|
||||||
when(relationshipType.getRightLabel()).thenReturn("RightLabel");
|
when(relationshipType.getRightwardType()).thenReturn("RightwardType");
|
||||||
when(relationshipType.getLeftType()).thenReturn(entityType);
|
when(relationshipType.getLeftType()).thenReturn(entityType);
|
||||||
when(relationshipType.getRightType()).thenReturn(entityType);
|
when(relationshipType.getRightType()).thenReturn(entityType);
|
||||||
when(entityService.getAllRelationshipTypes(context, entity)).thenReturn(relationshipTypeList);
|
when(entityService.getAllRelationshipTypes(context, entity)).thenReturn(relationshipTypeList);
|
||||||
|
@@ -62,15 +62,15 @@ public class VirtualMetadataPopulatorTest {
|
|||||||
HashMap<String, VirtualMetadataConfiguration> mapExt = new HashMap<>();
|
HashMap<String, VirtualMetadataConfiguration> mapExt = new HashMap<>();
|
||||||
VirtualMetadataConfiguration virtualMetadataConfiguration = mock(VirtualMetadataConfiguration.class);
|
VirtualMetadataConfiguration virtualMetadataConfiguration = mock(VirtualMetadataConfiguration.class);
|
||||||
mapExt.put("hashKey", virtualMetadataConfiguration);
|
mapExt.put("hashKey", virtualMetadataConfiguration);
|
||||||
map.put("LeftLabel", mapExt);
|
map.put("LeftwardType", mapExt);
|
||||||
map.put("NotRightLabel", mapExt);
|
map.put("NotRightwardType", mapExt);
|
||||||
virtualMetadataPopulator.setMap(map);
|
virtualMetadataPopulator.setMap(map);
|
||||||
|
|
||||||
// Mock the state of objects utilized in isUseForPlaceTrueForRelationshipType()
|
// Mock the state of objects utilized in isUseForPlaceTrueForRelationshipType()
|
||||||
// to meet the success criteria of an invocation
|
// to meet the success criteria of an invocation
|
||||||
when(virtualMetadataConfiguration.getUseForPlace()).thenReturn(true);
|
when(virtualMetadataConfiguration.getUseForPlace()).thenReturn(true);
|
||||||
when(relationshipType.getLeftLabel()).thenReturn("LeftLabel");
|
when(relationshipType.getLeftwardType()).thenReturn("LeftwardType");
|
||||||
when(relationshipType.getRightLabel()).thenReturn("RightLabel");
|
when(relationshipType.getRightwardType()).thenReturn("RightwardType");
|
||||||
|
|
||||||
// Assert that the useForPlace for our mocked relationshipType is false
|
// Assert that the useForPlace for our mocked relationshipType is false
|
||||||
assertEquals("TestGetFields 0", false,
|
assertEquals("TestGetFields 0", false,
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.harvest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mock for the HarvestedCollectionService
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class MockHarvestedCollectionServiceImpl extends HarvestedCollectionServiceImpl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> verifyOAIharvester(String oaiSource,
|
||||||
|
String oaiSetId, String metaPrefix, boolean testORE) {
|
||||||
|
|
||||||
|
if (metaPrefix.equals("dc")) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
return Arrays.asList("(Mock error) Incorrect metadataConfigID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.converter.HarvestedCollectionConverter;
|
||||||
|
import org.dspace.app.rest.link.HalLinkService;
|
||||||
|
import org.dspace.app.rest.model.HarvestedCollectionRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.HarvestedCollectionResource;
|
||||||
|
import org.dspace.app.rest.repository.HarvestedCollectionRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rest controller that handles the harvest settings for collections
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/core/collections/" +
|
||||||
|
"{collectionUuid:[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12" +
|
||||||
|
"}}/harvester")
|
||||||
|
public class CollectionHarvestSettingsController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionConverter harvestedCollectionConverter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CollectionService collectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionService harvestedCollectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HalLinkService halLinkService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionRestRepository harvestedCollectionRestRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Utils utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint that returns the harvest settings of the given collection
|
||||||
|
* @param request The request object
|
||||||
|
* @param response The response object
|
||||||
|
* @return a HarvesterMetadataResource containing all available metadata formats
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasPermission(#collectionUuid, 'COLLECTION', 'WRITE')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET)
|
||||||
|
public HarvestedCollectionResource get(@PathVariable UUID collectionUuid,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response) throws SQLException {
|
||||||
|
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
Collection collection = collectionService.find(context, collectionUuid);
|
||||||
|
|
||||||
|
if (collection == null) {
|
||||||
|
throw new ResourceNotFoundException("Collection with uuid: " + collectionUuid + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest = harvestedCollectionRestRepository.findOne(collection);
|
||||||
|
HarvestedCollectionResource resource = new HarvestedCollectionResource(harvestedCollectionRest);
|
||||||
|
|
||||||
|
halLinkService.addLinks(resource);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT Endpoint for updating the settings of a collection.
|
||||||
|
*
|
||||||
|
* @param collectionUuid The collection whose settings should be changed
|
||||||
|
* @param response The response object
|
||||||
|
* @param request The request object
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasPermission(#collectionUuid, 'COLLECTION', 'WRITE')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, consumes = {"application/json"})
|
||||||
|
public HarvestedCollectionResource updateHarvestSettingsEndpoint(@PathVariable UUID collectionUuid,
|
||||||
|
HttpServletResponse response,
|
||||||
|
HttpServletRequest request) throws SQLException {
|
||||||
|
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
Collection collection = collectionService.find(context, collectionUuid);
|
||||||
|
HarvestedCollectionResource harvestedCollectionResource = null;
|
||||||
|
|
||||||
|
if (collection == null) {
|
||||||
|
throw new ResourceNotFoundException("Collection with uuid: " + collectionUuid + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest =
|
||||||
|
harvestedCollectionRestRepository.update(context, request, collection);
|
||||||
|
|
||||||
|
// Return a harvestedCollectionResource only if a new harvestedCollection was created
|
||||||
|
if (harvestedCollectionRest != null) {
|
||||||
|
harvestedCollectionResource = new HarvestedCollectionResource(harvestedCollectionRest);
|
||||||
|
halLinkService.addLinks(harvestedCollectionResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.commit();
|
||||||
|
|
||||||
|
return harvestedCollectionResource;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.link.HalLinkService;
|
||||||
|
import org.dspace.app.rest.model.HarvesterMetadataRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.HarvesterMetadataResource;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rest controller that handles the harvesting metadata formats
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/config/harvestermetadata")
|
||||||
|
public class HarvesterMetadataController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Utils utils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HalLinkService halLinkService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET endpoint that returns all available metadata formats
|
||||||
|
* @param request The request object
|
||||||
|
* @param response The response object
|
||||||
|
* @return a HarvesterMetadataResource containing all available metadata formats
|
||||||
|
*/
|
||||||
|
@RequestMapping(method = RequestMethod.GET)
|
||||||
|
public HarvesterMetadataResource get(HttpServletRequest request,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
|
||||||
|
HarvesterMetadataRest data = new HarvesterMetadataRest();
|
||||||
|
data.setConfigs(configs);
|
||||||
|
|
||||||
|
HarvesterMetadataResource resource = new HarvesterMetadataResource(data, utils);
|
||||||
|
halLinkService.addLinks(resource);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -51,6 +51,7 @@ import org.dspace.app.rest.repository.LinkRestRepository;
|
|||||||
import org.dspace.app.rest.utils.RestRepositoryUtils;
|
import org.dspace.app.rest.utils.RestRepositoryUtils;
|
||||||
import org.dspace.app.rest.utils.Utils;
|
import org.dspace.app.rest.utils.Utils;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.util.UUIDUtils;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -390,14 +391,17 @@ public class RestResourceController implements InitializingBean {
|
|||||||
* @param request The relevant request
|
* @param request The relevant request
|
||||||
* @param apiCategory The apiCategory to be used
|
* @param apiCategory The apiCategory to be used
|
||||||
* @param model The model to be used
|
* @param model The model to be used
|
||||||
|
* @param parent Optional parent identifier
|
||||||
* @return The relevant ResponseEntity for this request
|
* @return The relevant ResponseEntity for this request
|
||||||
* @throws HttpRequestMethodNotSupportedException If something goes wrong
|
* @throws HttpRequestMethodNotSupportedException If something goes wrong
|
||||||
*/
|
*/
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = {"application/json", "application/hal+json"})
|
@RequestMapping(method = RequestMethod.POST, consumes = {"application/json", "application/hal+json"})
|
||||||
public ResponseEntity<ResourceSupport> post(HttpServletRequest request, @PathVariable String apiCategory,
|
public ResponseEntity<ResourceSupport> post(HttpServletRequest request,
|
||||||
@PathVariable String model)
|
@PathVariable String apiCategory,
|
||||||
|
@PathVariable String model,
|
||||||
|
@RequestParam(required = false) String parent)
|
||||||
throws HttpRequestMethodNotSupportedException {
|
throws HttpRequestMethodNotSupportedException {
|
||||||
return postJsonInternal(request, apiCategory, model);
|
return postJsonInternal(request, apiCategory, model, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -432,16 +436,24 @@ public class RestResourceController implements InitializingBean {
|
|||||||
* @param request The relevant request
|
* @param request The relevant request
|
||||||
* @param apiCategory The apiCategory to be used
|
* @param apiCategory The apiCategory to be used
|
||||||
* @param model The model to be used
|
* @param model The model to be used
|
||||||
|
* @param parent The parent object id (optional)
|
||||||
* @return The relevant ResponseEntity for this request
|
* @return The relevant ResponseEntity for this request
|
||||||
* @throws HttpRequestMethodNotSupportedException If something goes wrong
|
* @throws HttpRequestMethodNotSupportedException If something goes wrong
|
||||||
*/
|
*/
|
||||||
public <ID extends Serializable> ResponseEntity<ResourceSupport> postJsonInternal(HttpServletRequest request,
|
public <ID extends Serializable> ResponseEntity<ResourceSupport> postJsonInternal(HttpServletRequest request,
|
||||||
String apiCategory,
|
String apiCategory,
|
||||||
String model)
|
String model, String parent)
|
||||||
throws HttpRequestMethodNotSupportedException {
|
throws HttpRequestMethodNotSupportedException {
|
||||||
checkModelPluralForm(apiCategory, model);
|
checkModelPluralForm(apiCategory, model);
|
||||||
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
|
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
|
||||||
RestAddressableModel modelObject = repository.createAndReturn();
|
|
||||||
|
RestAddressableModel modelObject;
|
||||||
|
if (parent != null) {
|
||||||
|
UUID parentUuid = UUIDUtils.fromString(parent);
|
||||||
|
modelObject = repository.createAndReturn(parentUuid);
|
||||||
|
} else {
|
||||||
|
modelObject = repository.createAndReturn();
|
||||||
|
}
|
||||||
if (modelObject == null) {
|
if (modelObject == null) {
|
||||||
return ControllerUtils.toEmptyResponse(HttpStatus.CREATED);
|
return ControllerUtils.toEmptyResponse(HttpStatus.CREATED);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.converter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.HarvestStatusEnum;
|
||||||
|
import org.dspace.app.rest.model.HarvestTypeEnum;
|
||||||
|
import org.dspace.app.rest.model.HarvestedCollectionRest;
|
||||||
|
import org.dspace.app.rest.model.HarvesterMetadataRest;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the converter from/to the HarvestedCollection in the DSpace API data model and the REST data model
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class HarvestedCollectionConverter implements DSpaceConverter<HarvestedCollection, HarvestedCollectionRest> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CollectionConverter collectionConverter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestedCollectionRest fromModel(HarvestedCollection obj) {
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest = new HarvestedCollectionRest();
|
||||||
|
|
||||||
|
if (obj != null) {
|
||||||
|
HarvestTypeEnum harvestTypeEnum = HarvestTypeEnum.fromInt(obj.getHarvestType());
|
||||||
|
HarvestStatusEnum harvestStatusEnum = HarvestStatusEnum.fromInt(obj.getHarvestStatus());
|
||||||
|
|
||||||
|
harvestedCollectionRest.setId(obj.getID());
|
||||||
|
harvestedCollectionRest.setCollection(collectionConverter.fromModel(obj.getCollection()));
|
||||||
|
harvestedCollectionRest.setHarvestType(harvestTypeEnum);
|
||||||
|
harvestedCollectionRest.setHarvestStatus(harvestStatusEnum);
|
||||||
|
harvestedCollectionRest.setMetadataConfigId(obj.getHarvestMetadataConfig());
|
||||||
|
harvestedCollectionRest.setOaiSetId(obj.getOaiSetId());
|
||||||
|
harvestedCollectionRest.setOaiSource(obj.getOaiSource());
|
||||||
|
harvestedCollectionRest.setHarvestMessage(obj.getHarvestMessage());
|
||||||
|
harvestedCollectionRest.setHarvestStartTime(obj.getHarvestStartTime());
|
||||||
|
harvestedCollectionRest.setLastHarvested(obj.getHarvestDate());
|
||||||
|
} else {
|
||||||
|
harvestedCollectionRest.setHarvestType(HarvestTypeEnum.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return harvestedCollectionRest;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public HarvestedCollectionRest fromModel(HarvestedCollection obj,
|
||||||
|
Collection collection,
|
||||||
|
List<Map<String,String>> metadata_configs) {
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest = this.fromModel(obj);
|
||||||
|
|
||||||
|
// Add collectionRest to the empty HarvestedCollectionRest so that we can use its uuid later in the linkFactory
|
||||||
|
if (obj == null) {
|
||||||
|
harvestedCollectionRest.setCollection(collectionConverter.fromModel(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
HarvesterMetadataRest harvesterMetadataRest = new HarvesterMetadataRest();
|
||||||
|
harvesterMetadataRest.setConfigs(metadata_configs);
|
||||||
|
|
||||||
|
harvestedCollectionRest.setMetadataConfigs(harvesterMetadataRest);
|
||||||
|
|
||||||
|
return harvestedCollectionRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestedCollection toModel(HarvestedCollectionRest obj) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
@@ -38,6 +38,8 @@ public class RelationshipConverter implements DSpaceConverter<Relationship, Rela
|
|||||||
relationshipRest.setRightId(obj.getRightItem().getID());
|
relationshipRest.setRightId(obj.getRightItem().getID());
|
||||||
relationshipRest.setLeftPlace(obj.getLeftPlace());
|
relationshipRest.setLeftPlace(obj.getLeftPlace());
|
||||||
relationshipRest.setRightPlace(obj.getRightPlace());
|
relationshipRest.setRightPlace(obj.getRightPlace());
|
||||||
|
relationshipRest.setLeftwardValue(obj.getLeftwardValue());
|
||||||
|
relationshipRest.setRightwardValue(obj.getRightwardValue());
|
||||||
return relationshipRest;
|
return relationshipRest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@ public class RelationshipTypeConverter implements DSpaceConverter<RelationshipTy
|
|||||||
RelationshipTypeRest relationshipTypeRest = new RelationshipTypeRest();
|
RelationshipTypeRest relationshipTypeRest = new RelationshipTypeRest();
|
||||||
|
|
||||||
relationshipTypeRest.setId(obj.getID());
|
relationshipTypeRest.setId(obj.getID());
|
||||||
relationshipTypeRest.setLeftLabel(obj.getLeftLabel());
|
relationshipTypeRest.setLeftwardType(obj.getLeftwardType());
|
||||||
relationshipTypeRest.setRightLabel(obj.getRightLabel());
|
relationshipTypeRest.setRightwardType(obj.getRightwardType());
|
||||||
relationshipTypeRest.setLeftMinCardinality(obj.getLeftMinCardinality());
|
relationshipTypeRest.setLeftMinCardinality(obj.getLeftMinCardinality());
|
||||||
relationshipTypeRest.setLeftMaxCardinality(obj.getLeftMaxCardinality());
|
relationshipTypeRest.setLeftMaxCardinality(obj.getLeftMaxCardinality());
|
||||||
relationshipTypeRest.setRightMinCardinality(obj.getRightMinCardinality());
|
relationshipTypeRest.setRightMinCardinality(obj.getRightMinCardinality());
|
||||||
|
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.link.harvest;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.HarvestedCollectionRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.HarvestedCollectionResource;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class adds links to {@link org.dspace.app.rest.model.hateoas.HarvestedCollectionResource}s
|
||||||
|
* This builds a link to the collection harvest link
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class HarvestedCollectionHalLinkFactory
|
||||||
|
extends HarvestedCollectionRestHalLinkFactory<HarvestedCollectionResource> {
|
||||||
|
|
||||||
|
protected void addLinks(HarvestedCollectionResource halResource, Pageable page, LinkedList<Link> list)
|
||||||
|
throws Exception {
|
||||||
|
HarvestedCollectionRest data = halResource.getContent();
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
list.add(
|
||||||
|
buildLink(
|
||||||
|
Link.REL_SELF,
|
||||||
|
getMethodOn().get(UUID.fromString(data.getCollectionRest().getUuid()), null, null)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class<HarvestedCollectionResource> getResourceClass() {
|
||||||
|
return HarvestedCollectionResource.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.link.harvest;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.CollectionHarvestSettingsController;
|
||||||
|
import org.dspace.app.rest.link.HalLinkFactory;
|
||||||
|
|
||||||
|
public abstract class HarvestedCollectionRestHalLinkFactory<T>
|
||||||
|
extends HalLinkFactory<T, CollectionHarvestSettingsController> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<CollectionHarvestSettingsController> getControllerClass() {
|
||||||
|
return CollectionHarvestSettingsController.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -24,7 +24,7 @@ public class StatisticsSupportHalLinkFactory
|
|||||||
|
|
||||||
list.add(buildLink(Link.REL_SELF, getMethodOn().getStatisticsSupport()));
|
list.add(buildLink(Link.REL_SELF, getMethodOn().getStatisticsSupport()));
|
||||||
list.add(buildLink("viewevents", getMethodOn().getViewEvents()));
|
list.add(buildLink("viewevents", getMethodOn().getViewEvents()));
|
||||||
list.add(buildLink("searchevents", getMethodOn().getViewEvents()));
|
list.add(buildLink("searchevents", getMethodOn().getSearchEvents()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class<StatisticsRestController> getControllerClass() {
|
protected Class<StatisticsRestController> getControllerClass() {
|
||||||
|
@@ -25,6 +25,7 @@ public class CollectionRest extends DSpaceObjectRest {
|
|||||||
public static final String NAME = "collection";
|
public static final String NAME = "collection";
|
||||||
public static final String CATEGORY = RestAddressableModel.CORE;
|
public static final String CATEGORY = RestAddressableModel.CORE;
|
||||||
public static final String LICENSE = "license";
|
public static final String LICENSE = "license";
|
||||||
|
public static final String HARVEST = "harvester";
|
||||||
public static final String DEFAULT_ACCESS_CONDITIONS = "defaultAccessConditions";
|
public static final String DEFAULT_ACCESS_CONDITIONS = "defaultAccessConditions";
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private BitstreamRest logo;
|
private BitstreamRest logo;
|
||||||
|
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum containing all the possible harvest statuses
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public enum HarvestStatusEnum {
|
||||||
|
READY(0),
|
||||||
|
BUSY(1),
|
||||||
|
QUEUED(2),
|
||||||
|
OAI_ERROR(3),
|
||||||
|
UNKNOWN_ERROR(-1);
|
||||||
|
|
||||||
|
private int harvestStatus;
|
||||||
|
|
||||||
|
HarvestStatusEnum(int harvestStatus) {
|
||||||
|
this.harvestStatus = harvestStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return harvestStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HarvestStatusEnum fromInt(Integer harvestStatus) {
|
||||||
|
if (harvestStatus == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (harvestStatus) {
|
||||||
|
case -1: return HarvestStatusEnum.UNKNOWN_ERROR;
|
||||||
|
case 0: return HarvestStatusEnum.READY;
|
||||||
|
case 1: return HarvestStatusEnum.BUSY;
|
||||||
|
case 2: return HarvestStatusEnum.QUEUED;
|
||||||
|
case 3: return HarvestStatusEnum.OAI_ERROR;
|
||||||
|
default: throw new IllegalArgumentException("No corresponding enum value for integer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum containing all the possible harvest types
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public enum HarvestTypeEnum {
|
||||||
|
NONE(0),
|
||||||
|
METADATA_ONLY(1),
|
||||||
|
METADATA_AND_REF(2),
|
||||||
|
METADATA_AND_BITSTREAMS(3);
|
||||||
|
|
||||||
|
private int harvestType;
|
||||||
|
|
||||||
|
HarvestTypeEnum(int harvestType) {
|
||||||
|
this.harvestType = harvestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return harvestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an enum from the given integer
|
||||||
|
* @param harvestType The harvest type
|
||||||
|
* @return a harvestTypeEnum
|
||||||
|
*/
|
||||||
|
public static HarvestTypeEnum fromInt(Integer harvestType) {
|
||||||
|
if (harvestType == null) {
|
||||||
|
return HarvestTypeEnum.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (harvestType) {
|
||||||
|
case 0: return HarvestTypeEnum.NONE;
|
||||||
|
case 1: return HarvestTypeEnum.METADATA_ONLY;
|
||||||
|
case 2: return HarvestTypeEnum.METADATA_AND_REF;
|
||||||
|
case 3: return HarvestTypeEnum.METADATA_AND_BITSTREAMS;
|
||||||
|
default: throw new IllegalArgumentException("No corresponding enum value for integer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HarvestCollection REST Resource
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class HarvestedCollectionRest extends BaseObjectRest<Integer> {
|
||||||
|
|
||||||
|
public static final String NAME = "collections";
|
||||||
|
public static final String CATEGORY = "core";
|
||||||
|
|
||||||
|
@JsonProperty("harvest_type")
|
||||||
|
private HarvestTypeEnum harvestType;
|
||||||
|
|
||||||
|
@JsonProperty("oai_source")
|
||||||
|
private String oaiSource;
|
||||||
|
|
||||||
|
@JsonProperty("oai_set_id")
|
||||||
|
private String oaiSetId;
|
||||||
|
|
||||||
|
@JsonProperty("harvest_message")
|
||||||
|
private String harvestMessage;
|
||||||
|
|
||||||
|
@JsonProperty("metadata_config_id")
|
||||||
|
private String metadataConfigId;
|
||||||
|
|
||||||
|
@JsonProperty("harvest_status")
|
||||||
|
private HarvestStatusEnum harvestStatus;
|
||||||
|
|
||||||
|
@JsonProperty("harvest_start_time")
|
||||||
|
private Date harvestStartTime;
|
||||||
|
|
||||||
|
@JsonProperty("last_harvested")
|
||||||
|
private Date lastHarvested;
|
||||||
|
|
||||||
|
private HarvesterMetadataRest metadata_configs;
|
||||||
|
|
||||||
|
private CollectionRest collectionRest;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class getController() {
|
||||||
|
return HarvestedCollectionRest.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public CollectionRest getCollectionRest() {
|
||||||
|
return this.collectionRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCollection(CollectionRest collectionRest) {
|
||||||
|
this.collectionRest = collectionRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public int getHarvestType() {
|
||||||
|
return harvestType.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonGetter("harvest_type")
|
||||||
|
public String getHarvestTypeAsString() {
|
||||||
|
return harvestType.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestType(HarvestTypeEnum harvestType) {
|
||||||
|
this.harvestType = harvestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOaiSource() {
|
||||||
|
return oaiSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOaiSource(String oaiSource) {
|
||||||
|
this.oaiSource = oaiSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOaiSetId() {
|
||||||
|
return oaiSetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOaiSetId(String oaiSetId) {
|
||||||
|
this.oaiSetId = oaiSetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMetadataConfigId() {
|
||||||
|
return metadataConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadataConfigId(String metadataConfigId) {
|
||||||
|
this.metadataConfigId = metadataConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getHarvestMessage() {
|
||||||
|
return harvestMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestMessage(String harvestMessage) {
|
||||||
|
this.harvestMessage = harvestMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public HarvestStatusEnum getHarvestStatus() {
|
||||||
|
return harvestStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonGetter("harvest_status")
|
||||||
|
public String getHarvestStatusAsString() {
|
||||||
|
return harvestStatus == null ? null : harvestStatus.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestStatus(HarvestStatusEnum harvestStatus) {
|
||||||
|
this.harvestStatus = harvestStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getHarvestStartTime() {
|
||||||
|
return harvestStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestStartTime(Date harvestStartTime) {
|
||||||
|
this.harvestStartTime = harvestStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastHarvested() {
|
||||||
|
return lastHarvested;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastHarvested(Date lastHarvested) {
|
||||||
|
this.lastHarvested = lastHarvested;
|
||||||
|
}
|
||||||
|
|
||||||
|
@LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata", optional = true)
|
||||||
|
@JsonIgnore
|
||||||
|
public HarvesterMetadataRest getMetadataConfigs() {
|
||||||
|
return metadata_configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadataConfigs(HarvesterMetadataRest metadata_configs) {
|
||||||
|
this.metadata_configs = metadata_configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -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.rest.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import org.dspace.app.rest.HarvesterMetadataController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rest resource used for harvester metadata
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class HarvesterMetadataRest extends BaseObjectRest {
|
||||||
|
|
||||||
|
public static final String CATEGORY = "config";
|
||||||
|
public static final String NAME = "harvesterMetadata";
|
||||||
|
|
||||||
|
private List<Map<String,String>> configs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
|
public Serializable getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Class getController() {
|
||||||
|
return HarvesterMetadataController.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String,String>> getConfigs() {
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigs(List<Map<String,String>> configs) {
|
||||||
|
this.configs = configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -30,6 +30,8 @@ public class RelationshipRest extends BaseObjectRest<Integer> {
|
|||||||
private RelationshipTypeRest relationshipType;
|
private RelationshipTypeRest relationshipType;
|
||||||
private int leftPlace;
|
private int leftPlace;
|
||||||
private int rightPlace;
|
private int rightPlace;
|
||||||
|
private String leftwardValue;
|
||||||
|
private String rightwardValue;
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return NAME;
|
return NAME;
|
||||||
@@ -92,4 +94,20 @@ public class RelationshipRest extends BaseObjectRest<Integer> {
|
|||||||
public void setRelationshipTypeId(int relationshipTypeId) {
|
public void setRelationshipTypeId(int relationshipTypeId) {
|
||||||
this.relationshipTypeId = relationshipTypeId;
|
this.relationshipTypeId = relationshipTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRightwardValue() {
|
||||||
|
return rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightwardValue(String rightwardValue) {
|
||||||
|
this.rightwardValue = rightwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLeftwardValue() {
|
||||||
|
return leftwardValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftwardValue(String leftwardValue) {
|
||||||
|
this.leftwardValue = leftwardValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,8 +20,8 @@ public class RelationshipTypeRest extends BaseObjectRest<Integer> {
|
|||||||
public static final String NAME = "relationshiptype";
|
public static final String NAME = "relationshiptype";
|
||||||
public static final String CATEGORY = "core";
|
public static final String CATEGORY = "core";
|
||||||
|
|
||||||
private String leftLabel;
|
private String leftwardType;
|
||||||
private String rightLabel;
|
private String rightwardType;
|
||||||
private Integer leftMinCardinality;
|
private Integer leftMinCardinality;
|
||||||
private Integer leftMaxCardinality;
|
private Integer leftMaxCardinality;
|
||||||
private Integer rightMinCardinality;
|
private Integer rightMinCardinality;
|
||||||
@@ -41,20 +41,20 @@ public class RelationshipTypeRest extends BaseObjectRest<Integer> {
|
|||||||
return RestResourceController.class;
|
return RestResourceController.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLeftLabel() {
|
public String getLeftwardType() {
|
||||||
return leftLabel;
|
return leftwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLeftLabel(String leftLabel) {
|
public void setLeftwardType(String leftwardType) {
|
||||||
this.leftLabel = leftLabel;
|
this.leftwardType = leftwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRightLabel() {
|
public String getRightwardType() {
|
||||||
return rightLabel;
|
return rightwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRightLabel(String rightLabel) {
|
public void setRightwardType(String rightwardType) {
|
||||||
this.rightLabel = rightLabel;
|
this.rightwardType = rightwardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getLeftMinCardinality() {
|
public Integer getLeftMinCardinality() {
|
||||||
|
@@ -22,6 +22,7 @@ public class CollectionResource extends DSpaceResource<CollectionRest> {
|
|||||||
public CollectionResource(CollectionRest collection, Utils utils, String... rels) {
|
public CollectionResource(CollectionRest collection, Utils utils, String... rels) {
|
||||||
super(collection, utils, rels);
|
super(collection, utils, rels);
|
||||||
add(utils.linkToSubResource(collection, CollectionRest.LICENSE));
|
add(utils.linkToSubResource(collection, CollectionRest.LICENSE));
|
||||||
|
add(utils.linkToSubResource(collection, CollectionRest.HARVEST));
|
||||||
add(utils.linkToSubResource(collection, "mappedItems"));
|
add(utils.linkToSubResource(collection, "mappedItems"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.HarvestedCollectionRest;
|
||||||
|
import org.dspace.app.rest.model.HarvesterMetadataRest;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HarvestedCollection Rest HAL Resource. The HAL Resource wraps the REST Resource
|
||||||
|
* adding support for the links and embedded resources
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class HarvestedCollectionResource extends HALResource<HarvestedCollectionRest> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Utils utils;
|
||||||
|
|
||||||
|
public HarvestedCollectionResource(HarvestedCollectionRest data) {
|
||||||
|
super(data);
|
||||||
|
embedResource("harvestermetadata", data.getMetadataConfigs());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void embedResource(String relationship, HarvesterMetadataRest harvesterMetadataRest) {
|
||||||
|
if (harvesterMetadataRest != null) {
|
||||||
|
HarvesterMetadataResource harvesterMetadataResource =
|
||||||
|
new HarvesterMetadataResource(harvesterMetadataRest, utils);
|
||||||
|
embedResource(relationship, harvesterMetadataResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.HarvesterMetadataRest;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HarvesterMetadata Rest HAL Resource. The HAL Resource wraps the REST Resource
|
||||||
|
* adding support for the links and embedded resources
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class HarvesterMetadataResource extends DSpaceResource<HarvesterMetadataRest> {
|
||||||
|
|
||||||
|
public HarvesterMetadataResource(HarvesterMetadataRest data, Utils utils, String... rels) {
|
||||||
|
super(data, utils, rels);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -17,7 +17,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
import org.dspace.app.rest.converter.CollectionConverter;
|
import org.dspace.app.rest.converter.CollectionConverter;
|
||||||
@@ -38,7 +37,6 @@ import org.dspace.content.service.CollectionService;
|
|||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.util.UUIDUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
@@ -169,8 +167,19 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
|
||||||
protected CollectionRest createAndReturn(Context context) throws AuthorizeException {
|
protected CollectionRest createAndReturn(Context context) throws AuthorizeException {
|
||||||
|
throw new DSpaceBadRequestException("Cannot create a Collection without providing a parent Community.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'ADD')")
|
||||||
|
protected CollectionRest createAndReturn(Context context, UUID id) throws AuthorizeException {
|
||||||
|
|
||||||
|
if (id == null) {
|
||||||
|
throw new DSpaceBadRequestException("Parent Community UUID is null. " +
|
||||||
|
"Cannot create a Collection without providing a parent Community");
|
||||||
|
}
|
||||||
|
|
||||||
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CollectionRest collectionRest;
|
CollectionRest collectionRest;
|
||||||
@@ -178,38 +187,21 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
ServletInputStream input = req.getInputStream();
|
ServletInputStream input = req.getInputStream();
|
||||||
collectionRest = mapper.readValue(input, CollectionRest.class);
|
collectionRest = mapper.readValue(input, CollectionRest.class);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
throw new UnprocessableEntityException("Error parsing request body: " + e1.toString());
|
throw new UnprocessableEntityException("Error parsing request body.", e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection collection;
|
Collection collection;
|
||||||
|
|
||||||
|
|
||||||
String parentCommunityString = req.getParameter("parent");
|
|
||||||
try {
|
try {
|
||||||
Community parent = null;
|
Community parent = communityService.find(context, id);
|
||||||
if (StringUtils.isNotBlank(parentCommunityString)) {
|
if (parent == null) {
|
||||||
|
throw new UnprocessableEntityException("Parent community for id: "
|
||||||
UUID parentCommunityUuid = UUIDUtils.fromString(parentCommunityString);
|
+ id + " not found");
|
||||||
if (parentCommunityUuid == null) {
|
|
||||||
throw new DSpaceBadRequestException("The given parent was invalid: "
|
|
||||||
+ parentCommunityString);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = communityService.find(context, parentCommunityUuid);
|
|
||||||
if (parent == null) {
|
|
||||||
throw new UnprocessableEntityException("Parent community for id: "
|
|
||||||
+ parentCommunityUuid + " not found");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new DSpaceBadRequestException("The parent parameter cannot be left empty," +
|
|
||||||
"collections require a parent community.");
|
|
||||||
}
|
}
|
||||||
collection = cs.create(context, parent);
|
collection = cs.create(context, parent);
|
||||||
cs.update(context, collection);
|
cs.update(context, collection);
|
||||||
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
|
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException("Unable to create new Collection under parent Community " +
|
throw new RuntimeException("Unable to create new Collection under parent Community " + id, e);
|
||||||
parentCommunityString, e);
|
|
||||||
}
|
}
|
||||||
return converter.convert(collection);
|
return converter.convert(collection);
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
import org.dspace.app.rest.converter.CommunityConverter;
|
import org.dspace.app.rest.converter.CommunityConverter;
|
||||||
@@ -34,7 +33,6 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.util.UUIDUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
@@ -83,25 +81,45 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
}
|
}
|
||||||
|
|
||||||
Community community;
|
Community community;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Community parent = null;
|
// top-level community
|
||||||
String parentCommunityString = req.getParameter("parent");
|
community = cs.create(null, context);
|
||||||
if (StringUtils.isNotBlank(parentCommunityString)) {
|
cs.update(context, community);
|
||||||
|
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
UUID parentCommunityUuid = UUIDUtils.fromString(parentCommunityString);
|
return dsoConverter.convert(community);
|
||||||
if (parentCommunityUuid == null) {
|
}
|
||||||
throw new DSpaceBadRequestException("The given parent parameter was invalid: "
|
|
||||||
+ parentCommunityString);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = cs.find(context, parentCommunityUuid);
|
@Override
|
||||||
if (parent == null) {
|
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'ADD')")
|
||||||
throw new UnprocessableEntityException("Parent community for id: "
|
protected CommunityRest createAndReturn(Context context, UUID id) throws AuthorizeException {
|
||||||
+ parentCommunityUuid + " not found");
|
|
||||||
}
|
if (id == null) {
|
||||||
|
throw new DSpaceBadRequestException("Parent Community UUID is null. " +
|
||||||
|
"Cannot create a SubCommunity without providing a parent Community.");
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
CommunityRest communityRest;
|
||||||
|
try {
|
||||||
|
ServletInputStream input = req.getInputStream();
|
||||||
|
communityRest = mapper.readValue(input, CommunityRest.class);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
throw new UnprocessableEntityException("Error parsing request body.", e1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Community community;
|
||||||
|
try {
|
||||||
|
Community parent = cs.find(context, id);
|
||||||
|
if (parent == null) {
|
||||||
|
throw new UnprocessableEntityException("Parent community for id: "
|
||||||
|
+ id + " not found");
|
||||||
}
|
}
|
||||||
|
// sub-community
|
||||||
community = cs.create(parent, context);
|
community = cs.create(parent, context);
|
||||||
cs.update(context, community);
|
cs.update(context, community);
|
||||||
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
||||||
|
@@ -12,6 +12,7 @@ import java.io.IOException;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
@@ -233,7 +234,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to implement to support scroll of entity instances from the collection resource endpoin
|
* Method to implement to support scroll of entity instances from the collection resource endpoint
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* the dspace context
|
* the dspace context
|
||||||
@@ -259,6 +260,46 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
*/
|
*/
|
||||||
public abstract DSpaceResource<T> wrapResource(T model, String... rels);
|
public abstract DSpaceResource<T> wrapResource(T model, String... rels);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a new instance. Data are usually retrieved from the thread bound http request
|
||||||
|
*
|
||||||
|
* @return the created REST object
|
||||||
|
*/
|
||||||
|
public T createAndReturn() {
|
||||||
|
Context context = null;
|
||||||
|
try {
|
||||||
|
context = obtainContext();
|
||||||
|
T entity = thisRepository.createAndReturn(context);
|
||||||
|
context.commit();
|
||||||
|
return entity;
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
throw new RESTAuthorizationException(e);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new RuntimeException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a new instance after adding to the parent. Data are usually retrieved from
|
||||||
|
* the thread bound http request.
|
||||||
|
*
|
||||||
|
* @param uuid the id of the parent object
|
||||||
|
* @return the created REST object
|
||||||
|
*/
|
||||||
|
public T createAndReturn(UUID uuid) {
|
||||||
|
Context context = null;
|
||||||
|
try {
|
||||||
|
context = obtainContext();
|
||||||
|
T entity = thisRepository.createAndReturn(context, uuid);
|
||||||
|
context.commit();
|
||||||
|
return entity;
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
throw new RESTAuthorizationException(e);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new RuntimeException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return a new instance. Data is recovered from the thread bound HTTP request and the list
|
* Create and return a new instance. Data is recovered from the thread bound HTTP request and the list
|
||||||
* of DSpaceObjects provided in the uri-list body
|
* of DSpaceObjects provided in the uri-list body
|
||||||
@@ -281,22 +322,22 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return a new instance. Data are usually retrieved from the thread bound http request
|
* Method to implement to support the creation of a new instance. Usually require to retrieve the http request from
|
||||||
|
* the thread bound attribute
|
||||||
*
|
*
|
||||||
|
* @param context
|
||||||
|
* the dspace context
|
||||||
|
* @param uuid
|
||||||
|
* The uuid of the parent object retrieved from the query param.
|
||||||
* @return the created REST object
|
* @return the created REST object
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws RepositoryMethodNotImplementedException
|
||||||
|
* returned by the default implementation when the operation is not supported for the entity
|
||||||
*/
|
*/
|
||||||
public T createAndReturn() {
|
protected T createAndReturn(Context context, UUID uuid)
|
||||||
Context context = null;
|
throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException {
|
||||||
try {
|
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
|
||||||
context = obtainContext();
|
|
||||||
T entity = thisRepository.createAndReturn(context);
|
|
||||||
context.commit();
|
|
||||||
return entity;
|
|
||||||
} catch (AuthorizeException e) {
|
|
||||||
throw new RESTAuthorizationException(e);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
throw new RuntimeException(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,190 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.repository;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.dspace.app.rest.converter.HarvestedCollectionConverter;
|
||||||
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.HarvestTypeEnum;
|
||||||
|
import org.dspace.app.rest.model.HarvestedCollectionRest;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the repository responsible for managing the HarvestedCollection Rest object
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
@Component(HarvestedCollectionRest.CATEGORY + "." + HarvestedCollectionRest.NAME)
|
||||||
|
public class HarvestedCollectionRestRepository extends AbstractDSpaceRestRepository {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionService harvestedCollectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionConverter harvestedCollectionConverter;
|
||||||
|
|
||||||
|
public HarvestedCollectionRest findOne(Collection collection) throws SQLException {
|
||||||
|
Context context = obtainContext();
|
||||||
|
|
||||||
|
if (collection == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection);
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to update the harvesting settings of a collection
|
||||||
|
* @param context The context object
|
||||||
|
* @param request The incoming put request
|
||||||
|
* @param collection The collection whose settings should be changed
|
||||||
|
* @return a harvestedCollection if a new harvestedCollection is created, otherwise null
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public HarvestedCollectionRest update(Context context,
|
||||||
|
HttpServletRequest request,
|
||||||
|
Collection collection) throws SQLException {
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest = parseHarvestedCollectionRest(context, request, collection);
|
||||||
|
HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection);
|
||||||
|
|
||||||
|
// Delete harvestedCollectionService object if harvest type is not set
|
||||||
|
if (harvestedCollectionRest.getHarvestType() == HarvestTypeEnum.NONE.getValue()
|
||||||
|
&& harvestedCollection != null) {
|
||||||
|
harvestedCollectionService.delete(context, harvestedCollection);
|
||||||
|
return harvestedCollectionConverter.fromModel(null);
|
||||||
|
|
||||||
|
} else if (harvestedCollectionRest.getHarvestType() != HarvestTypeEnum.NONE.getValue()) {
|
||||||
|
List<String> errors = testHarvestSettings(harvestedCollectionRest);
|
||||||
|
|
||||||
|
if (errors.size() == 0) {
|
||||||
|
if (harvestedCollection == null) {
|
||||||
|
harvestedCollection = harvestedCollectionService.create(context, collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCollectionHarvestSettings(context, harvestedCollection, harvestedCollectionRest);
|
||||||
|
harvestedCollection = harvestedCollectionService.find(context, collection);
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
|
||||||
|
return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs);
|
||||||
|
} else {
|
||||||
|
throw new UnprocessableEntityException(
|
||||||
|
"Incorrect harvest settings in request. The following errors were found: " + errors.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to parse a harvestedCollectionRest from an incoming put request
|
||||||
|
* @param context The context object
|
||||||
|
* @param request The incoming put request
|
||||||
|
* @param collection The collection to which the harvestedCollection belongs
|
||||||
|
* @return The harvestedCollectionRest object contained inn the request
|
||||||
|
*/
|
||||||
|
private HarvestedCollectionRest parseHarvestedCollectionRest(Context context,
|
||||||
|
HttpServletRequest request,
|
||||||
|
Collection collection) throws SQLException {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ServletInputStream input = request.getInputStream();
|
||||||
|
harvestedCollectionRest = mapper.readValue(input, HarvestedCollectionRest.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UnprocessableEntityException("Error parsing request body: " + e.toString(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return harvestedCollectionRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to update the harvest settings of a collection
|
||||||
|
* @param context The context object
|
||||||
|
* @param harvestedCollection The harvestedCollection whose settings should be updated
|
||||||
|
* @param harvestedCollectionRest An object containing the new harvest settings
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private void updateCollectionHarvestSettings(Context context, HarvestedCollection harvestedCollection,
|
||||||
|
HarvestedCollectionRest harvestedCollectionRest) throws SQLException {
|
||||||
|
int harvestType = harvestedCollectionRest.getHarvestType();
|
||||||
|
String oaiSource = harvestedCollectionRest.getOaiSource();
|
||||||
|
String oaiSetId = harvestedCollectionRest.getOaiSetId();
|
||||||
|
String metadataConfigId = harvestedCollectionRest.getMetadataConfigId();
|
||||||
|
|
||||||
|
harvestedCollection.setHarvestType(harvestType);
|
||||||
|
harvestedCollection.setOaiSource(oaiSource);
|
||||||
|
harvestedCollection.setOaiSetId(oaiSetId);
|
||||||
|
harvestedCollection.setHarvestMetadataConfig(metadataConfigId);
|
||||||
|
|
||||||
|
harvestedCollectionService.update(context, harvestedCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function used to verify that the harvest settings work
|
||||||
|
* @param collection The collection to which the harvest settings should be aplied
|
||||||
|
* @param harvestedCollectionRest A object containg the harvest settings to be tested
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<String> testHarvestSettings(HarvestedCollectionRest harvestedCollectionRest) {
|
||||||
|
|
||||||
|
int harvestType = harvestedCollectionRest.getHarvestType();
|
||||||
|
String metadataConfigId = harvestedCollectionRest.getMetadataConfigId();
|
||||||
|
|
||||||
|
List<String> errors = new ArrayList<>();
|
||||||
|
|
||||||
|
// See if metadata config identifier appears in available metadata formats
|
||||||
|
List<Map<String,String>> metadataFormats = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
boolean inAvailableMetadataFormats = metadataFormats.stream()
|
||||||
|
.filter(x -> x.get("id").equals(metadataConfigId))
|
||||||
|
.count() >= 1;
|
||||||
|
|
||||||
|
if (inAvailableMetadataFormats) {
|
||||||
|
boolean testORE = Arrays.asList(
|
||||||
|
HarvestTypeEnum.METADATA_AND_REF.getValue(),
|
||||||
|
HarvestTypeEnum.METADATA_AND_BITSTREAMS.getValue()
|
||||||
|
).contains(harvestType);
|
||||||
|
|
||||||
|
// Actually verify the harvest settings
|
||||||
|
List<String> verificationErrors = harvestedCollectionService.verifyOAIharvester(
|
||||||
|
harvestedCollectionRest.getOaiSource(),
|
||||||
|
harvestedCollectionRest.getOaiSetId(),
|
||||||
|
metadataConfigId,
|
||||||
|
testORE
|
||||||
|
);
|
||||||
|
errors = verificationErrors;
|
||||||
|
} else {
|
||||||
|
errors.add(
|
||||||
|
"The metadata format with identifier '" + metadataConfigId + "' is not an available metadata format."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,12 +7,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest.repository;
|
package org.dspace.app.rest.repository;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
@@ -109,11 +112,14 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
RelationshipType relationshipType = relationshipTypeService
|
RelationshipType relationshipType = relationshipTypeService
|
||||||
.find(context, Integer.parseInt(req.getParameter("relationshipType")));
|
.find(context, Integer.parseInt(req.getParameter("relationshipType")));
|
||||||
|
|
||||||
|
String leftwardValue = req.getParameter("leftwardValue");
|
||||||
|
String rightwardValue = req.getParameter("rightwardValue");
|
||||||
|
|
||||||
EPerson ePerson = context.getCurrentUser();
|
EPerson ePerson = context.getCurrentUser();
|
||||||
if (authorizeService.authorizeActionBoolean(context, leftItem, Constants.WRITE) ||
|
if (authorizeService.authorizeActionBoolean(context, leftItem, Constants.WRITE) ||
|
||||||
authorizeService.authorizeActionBoolean(context, rightItem, Constants.WRITE)) {
|
authorizeService.authorizeActionBoolean(context, rightItem, Constants.WRITE)) {
|
||||||
Relationship relationship = relationshipService.create(context, leftItem, rightItem,
|
Relationship relationship = relationshipService.create(context, leftItem, rightItem,
|
||||||
relationshipType, -1, -1);
|
relationshipType, -1, -1, leftwardValue, rightwardValue);
|
||||||
// The above if check deals with the case that a Relationship can be created if the user has write
|
// The above if check deals with the case that a Relationship can be created if the user has write
|
||||||
// rights on one of the two items. The following updateItem calls can however call the
|
// rights on one of the two items. The following updateItem calls can however call the
|
||||||
// ItemService.update() functions which would fail if the user doesn't have permission on both items.
|
// ItemService.update() functions which would fail if the user doesn't have permission on both items.
|
||||||
@@ -198,6 +204,66 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to replace the metadata of a relationship (the left/right places and the leftward/rightward labels)
|
||||||
|
* @param context the dspace context
|
||||||
|
* @param request
|
||||||
|
* @param apiCategory the API category e.g. "api"
|
||||||
|
* @param model the DSpace model e.g. "metadatafield"
|
||||||
|
* @param id the ID of the target REST object
|
||||||
|
* @param jsonNode the part of the request body representing the updated rest object
|
||||||
|
* @return
|
||||||
|
* @throws RepositoryMethodNotImplementedException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected RelationshipRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
||||||
|
Integer id, JsonNode jsonNode)
|
||||||
|
throws RepositoryMethodNotImplementedException, SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
Relationship relationship;
|
||||||
|
try {
|
||||||
|
relationship = relationshipService.find(context, id);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ResourceNotFoundException("Relationship" + " with id: " + id + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relationship == null) {
|
||||||
|
throw new ResourceNotFoundException("Relationship" + " with id: " + id + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
RelationshipRest relationshipRest;
|
||||||
|
|
||||||
|
try {
|
||||||
|
relationshipRest = new ObjectMapper().readValue(jsonNode.toString(), RelationshipRest.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UnprocessableEntityException("Error parsing request body: " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
relationship.setLeftwardValue(relationshipRest.getLeftwardValue());
|
||||||
|
relationship.setRightwardValue(relationshipRest.getRightwardValue());
|
||||||
|
|
||||||
|
if (jsonNode.hasNonNull("rightPlace")) {
|
||||||
|
relationship.setRightPlace(relationshipRest.getRightPlace());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonNode.hasNonNull("leftPlace")) {
|
||||||
|
relationship.setRightPlace(relationshipRest.getLeftPlace());
|
||||||
|
}
|
||||||
|
|
||||||
|
relationshipService.update(context, relationship);
|
||||||
|
context.commit();
|
||||||
|
context.reloadEntity(relationship);
|
||||||
|
|
||||||
|
return relationshipConverter.fromModel(relationship);
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
throw new AccessDeniedException("You do not have write rights on this relationship's metadata");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will check with the current user has write rights on both one of the original items and one of the
|
* This method will check with the current user has write rights on both one of the original items and one of the
|
||||||
* new items for the relationship.
|
* new items for the relationship.
|
||||||
@@ -253,7 +319,8 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
|
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
|
|
||||||
List<RelationshipType> relationshipTypeList = relationshipTypeService.findByLeftOrRightLabel(context, label);
|
List<RelationshipType> relationshipTypeList =
|
||||||
|
relationshipTypeService.findByLeftwardOrRightwardTypeName(context, label);
|
||||||
List<Relationship> relationships = new LinkedList<>();
|
List<Relationship> relationships = new LinkedList<>();
|
||||||
if (dsoId != null) {
|
if (dsoId != null) {
|
||||||
|
|
||||||
|
@@ -30,8 +30,8 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An authenicated user is allowed to view, update or delete his or her own data. This {@link RestPermissionEvaluatorPlugin}
|
* An authenticated user is allowed to view, update or delete his or her own data. This {@link RestPermissionEvaluatorPlugin}
|
||||||
* implemenents that requirement.
|
* implements that requirement.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class EPersonRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
|
public class EPersonRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:util="http://www.springframework.org/schema/util"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
|
||||||
|
default-lazy-init="true">
|
||||||
|
|
||||||
|
<!-- Replace harvestCollectionService with a mocked service -->
|
||||||
|
<bean class="org.dspace.harvest.MockHarvestedCollectionServiceImpl" id="org.dspace.harvest.service.HarvestedCollectionService" primary="true"/>
|
||||||
|
</beans>
|
@@ -0,0 +1,312 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.builder.CollectionBuilder;
|
||||||
|
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||||
|
import org.dspace.app.rest.builder.EPersonBuilder;
|
||||||
|
import org.dspace.app.rest.matcher.MetadataConfigsMatcher;
|
||||||
|
import org.dspace.app.rest.model.HarvestTypeEnum;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test for collection harvest settings controller
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class CollectionHarvestSettingsControllerIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HarvestedCollectionService harvestedCollectionService;
|
||||||
|
|
||||||
|
Collection collection;
|
||||||
|
Collection collectionNoHarvestSettings;
|
||||||
|
EPerson ePersonWithWriteRights;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void SetUp() throws SQLException, AuthorizeException {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community community = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
collection = CollectionBuilder.createCollection(context, community)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
collectionNoHarvestSettings = CollectionBuilder.createCollection(context, community)
|
||||||
|
.withName("Collection 2")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ePersonWithWriteRights = EPersonBuilder.createEPerson(context)
|
||||||
|
.withEmail("email@email.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
authorizeService.addPolicy(context, collection, Constants.WRITE, ePersonWithWriteRights);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to create a JSONObject containing the harvest settings
|
||||||
|
* @param harvestType The harvest type
|
||||||
|
* @param oaiSource The OAI source
|
||||||
|
* @param oaiSetId The OAI set id
|
||||||
|
* @param metadataConfigId The metadata config id
|
||||||
|
* @return A JSONObject containing the given harvest settings
|
||||||
|
*/
|
||||||
|
public JSONObject createHarvestSettingsJson(String harvestType,
|
||||||
|
String oaiSource, String oaiSetId, String metadataConfigId) {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("harvest_type", harvestType);
|
||||||
|
json.put("oai_source", oaiSource);
|
||||||
|
json.put("oai_set_id", oaiSetId);
|
||||||
|
json.put("metadata_config_id", metadataConfigId);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GetCollectionHarvestSettings() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
|
||||||
|
// Add harvest settings to collection
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
//Retrieve harvest settings
|
||||||
|
getClient(token).perform(
|
||||||
|
get("/api/core/collections/" + collection.getID() + "/harvester"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.harvest_type", is("METADATA_ONLY")))
|
||||||
|
.andExpect(jsonPath("$.oai_source", is("https://dspace.org/oai/request")))
|
||||||
|
.andExpect(jsonPath("$.oai_set_id", is("col_1721.1_114174")))
|
||||||
|
.andExpect(jsonPath("$.harvest_message", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.metadata_config_id", is("dc")))
|
||||||
|
.andExpect(jsonPath("$.harvest_status", is("READY")))
|
||||||
|
.andExpect(jsonPath("$.harvest_start_time", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.last_harvested", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
endsWith("api/core/collections/" + collection.getID() + "/harvester")))
|
||||||
|
.andExpect(jsonPath("$._embedded.harvestermetadata", Matchers.allOf(
|
||||||
|
MetadataConfigsMatcher.matchMetadataConfigs(configs)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._embedded.harvestermetadata._links.self.href",
|
||||||
|
endsWith("/api/config/harvestermetadata")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GetCollectionHarvestSettingsIfNotAdmin() throws Exception {
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GetAndPutCollectionHarvestSettingsIfUserHasWriteRights() throws Exception {
|
||||||
|
context.setCurrentUser(ePersonWithWriteRights);
|
||||||
|
String token = getAuthToken(ePersonWithWriteRights.getEmail(), password);
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
get("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAndPutCollectionHarvestSettingsAnonymousUserException() throws Exception {
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient().perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GetAndPutCollectionHarvestSettingsIfUserHasNoWriteRightsException() throws Exception {
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCollectionHarvestSettingsIfNotSet() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
get("/api/core/collections/" + collectionNoHarvestSettings.getID() + "/harvester"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.harvest_type", is("NONE")))
|
||||||
|
.andExpect(jsonPath("$.oai_source", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.oai_set_id", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.harvest_message", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.metadata_config_id", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.harvest_status", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.harvest_start_time", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$.last_harvested", is(nullValue())))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
endsWith("api/core/collections/" + collectionNoHarvestSettings.getID() + "/harvester")))
|
||||||
|
.andExpect(jsonPath("$._embedded.harvestermetadata", Matchers.allOf(
|
||||||
|
MetadataConfigsMatcher.matchMetadataConfigs(configs)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._embedded.harvestermetadata._links.self.href",
|
||||||
|
endsWith("/api/config/harvestermetadata")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutWorksWithStandardSettings() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection);
|
||||||
|
|
||||||
|
assertTrue(harvestedCollection.getHarvestType()
|
||||||
|
== HarvestTypeEnum.valueOf(json.getString("harvest_type")).getValue());
|
||||||
|
assertTrue(harvestedCollection.getOaiSource().equals(json.getString("oai_source")));
|
||||||
|
assertTrue(harvestedCollection.getOaiSetId().equals(json.getString("oai_set_id")));
|
||||||
|
assertTrue(harvestedCollection.getHarvestMetadataConfig().equals(json.getString("metadata_config_id")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutUnProcessableEntityIfIncorrectSettings() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://mydspace.edu/oai/request", "col_1721.1_114174", "bc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutHarvestSettingsDeletedIfHarvestTypeIsNone() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
JSONObject json = createHarvestSettingsJson("NONE", "", "", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection);
|
||||||
|
|
||||||
|
assertNull(harvestedCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutUnauthorizedIfNotAuthenticated() throws Exception {
|
||||||
|
getClient().perform(put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json"))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutForbiddenIfNotEnoughpermissions() throws Exception {
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutNotFoundIfNoSuchCollection() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
String fakeUuid = "6c9a081e-f2e5-42cd-8cf8-338f64b0841b";
|
||||||
|
getClient(token).perform(put("/api/core/collections/" + fakeUuid + "/harvester")
|
||||||
|
.contentType("application/json"))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PutUnprocessableEntityIfHarvestTypeIncorrect() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
JSONObject json = createHarvestSettingsJson("INCORRECT_HARVEST_TYPE", "https://mydspace.edu/oai/request", "col_1721.1_114174", "dc");
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
put("/api/core/collections/" + collection.getID() + "/harvester")
|
||||||
|
.contentType("application/json")
|
||||||
|
.content(json.toString()))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
}
|
||||||
|
}
|
@@ -98,6 +98,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections")
|
getClient().perform(get("/api/core/collections")
|
||||||
.param("size", "1"))
|
.param("size", "1"))
|
||||||
@@ -147,6 +148,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -180,6 +182,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
.withLogo("TestingContentForLogo").build();
|
.withLogo("TestingContentForLogo").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -225,6 +229,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/search/findAuthorized"))
|
getClient().perform(get("/api/core/collections/search/findAuthorized"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -254,6 +260,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/search/findAuthorizedByCommunity")
|
getClient().perform(get("/api/core/collections/search/findAuthorizedByCommunity")
|
||||||
.param("uuid", parentCommunity.getID().toString()))
|
.param("uuid", parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -294,6 +302,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/" + UUID.randomUUID()))
|
getClient().perform(get("/api/core/collections/" + UUID.randomUUID()))
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -318,6 +327,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child2).withName("Collection 2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
getClient().perform(get("/api/core/collections/" + col1.getID()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -363,6 +374,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
collectionRest.setMetadata(new MetadataRest()
|
collectionRest.setMetadata(new MetadataRest()
|
||||||
.put("dc.title", new MetadataValueRest("Electronic theses and dissertations")));
|
.put("dc.title", new MetadataValueRest("Electronic theses and dissertations")));
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(put("/api/core/collections/" + col1.getID().toString())
|
getClient(token).perform(put("/api/core/collections/" + col1.getID().toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(mapper.writeValueAsBytes(collectionRest)))
|
.content(mapper.writeValueAsBytes(collectionRest)))
|
||||||
@@ -408,6 +421,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/collections/" + col1.getID().toString()))
|
getClient(token).perform(get("/api/core/collections/" + col1.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -449,6 +464,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
.withName("Collection 1")
|
.withName("Collection 1")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/collections/" + col1.getID().toString()))
|
getClient().perform(get("/api/core/collections/" + col1.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -473,6 +490,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
.withName("Parent Community")
|
.withName("Parent Community")
|
||||||
.withLogo("ThisIsSomeDummyText")
|
.withLogo("ThisIsSomeDummyText")
|
||||||
.build();
|
.build();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CollectionRest collectionRest = new CollectionRest();
|
CollectionRest collectionRest = new CollectionRest();
|
||||||
@@ -519,6 +537,111 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createTestByAuthorizedUser() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and one collection.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.withLogo("ThisIsSomeDummyText")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
CollectionRest collectionRest = new CollectionRest();
|
||||||
|
// We send a name but the created collection should set this to the title
|
||||||
|
collectionRest.setName("Collection");
|
||||||
|
|
||||||
|
collectionRest.setMetadata(new MetadataRest()
|
||||||
|
.put("dc.description",
|
||||||
|
new MetadataValueRest("<p>Some cool HTML code here</p>"))
|
||||||
|
.put("dc.description.abstract",
|
||||||
|
new MetadataValueRest("Sample top-level community created via the REST API"))
|
||||||
|
.put("dc.description.tableofcontents",
|
||||||
|
new MetadataValueRest("<p>HTML News</p>"))
|
||||||
|
.put("dc.rights",
|
||||||
|
new MetadataValueRest("Custom Copyright Text"))
|
||||||
|
.put("dc.title",
|
||||||
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
|
// ADD authorization on parent community
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
authorizeService.addPolicy(context, parentCommunity, Constants.ADD, eperson);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(post("/api/core/collections")
|
||||||
|
.content(mapper.writeValueAsBytes(collectionRest))
|
||||||
|
.param("parent", parentCommunity.getID().toString())
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
hasJsonPath("$.id", not(empty())),
|
||||||
|
hasJsonPath("$.uuid", not(empty())),
|
||||||
|
hasJsonPath("$.name", is("Title Text")),
|
||||||
|
hasJsonPath("$.handle", not(empty())),
|
||||||
|
hasJsonPath("$.type", is("collection")),
|
||||||
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
|
MetadataMatcher.matchMetadata("dc.description",
|
||||||
|
"<p>Some cool HTML code here</p>"),
|
||||||
|
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||||
|
"Sample top-level community created via the REST API"),
|
||||||
|
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
||||||
|
"<p>HTML News</p>"),
|
||||||
|
MetadataMatcher.matchMetadata("dc.rights",
|
||||||
|
"Custom Copyright Text"),
|
||||||
|
MetadataMatcher.matchMetadata("dc.title",
|
||||||
|
"Title Text")
|
||||||
|
)))));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createTestByUnauthorizedUser() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and one collection.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.withLogo("ThisIsSomeDummyText")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
CollectionRest collectionRest = new CollectionRest();
|
||||||
|
// We send a name but the created collection should set this to the title
|
||||||
|
collectionRest.setName("Collection");
|
||||||
|
|
||||||
|
collectionRest.setMetadata(new MetadataRest()
|
||||||
|
.put("dc.description",
|
||||||
|
new MetadataValueRest("<p>Some cool HTML code here</p>"))
|
||||||
|
.put("dc.description.abstract",
|
||||||
|
new MetadataValueRest("Sample top-level community created via the REST API"))
|
||||||
|
.put("dc.description.tableofcontents",
|
||||||
|
new MetadataValueRest("<p>HTML News</p>"))
|
||||||
|
.put("dc.rights",
|
||||||
|
new MetadataValueRest("Custom Copyright Text"))
|
||||||
|
.put("dc.title",
|
||||||
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// User doesn't have add permission on the collection.
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(post("/api/core/collections")
|
||||||
|
.content(mapper.writeValueAsBytes(collectionRest))
|
||||||
|
.param("parent", parentCommunity.getID().toString())
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteCollectionEpersonWithDeleteRightsTest() throws Exception {
|
public void deleteCollectionEpersonWithDeleteRightsTest() throws Exception {
|
||||||
@@ -552,6 +675,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
|
|
||||||
String token = getAuthToken(eperson.getEmail(), password);
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/collections/" + col1.getID().toString()))
|
getClient(token).perform(get("/api/core/collections/" + col1.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -600,6 +725,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
context.setCurrentUser(eperson);
|
context.setCurrentUser(eperson);
|
||||||
authorizeService.addPolicy(context, col1, Constants.WRITE, eperson);
|
authorizeService.addPolicy(context, col1, Constants.WRITE, eperson);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
String token = getAuthToken(eperson.getEmail(), password);
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
@@ -677,6 +804,9 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
new MetadataValueRest("Title Text")));
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(authToken).perform(post("/api/core/collections")
|
getClient(authToken).perform(post("/api/core/collections")
|
||||||
.content(mapper.writeValueAsBytes(collectionRest))
|
.content(mapper.writeValueAsBytes(collectionRest))
|
||||||
.param("parent", "123")
|
.param("parent", "123")
|
||||||
@@ -716,6 +846,9 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
new MetadataValueRest("Title Text")));
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(authToken).perform(post("/api/core/collections")
|
getClient(authToken).perform(post("/api/core/collections")
|
||||||
.content(mapper.writeValueAsBytes(collectionRest))
|
.content(mapper.writeValueAsBytes(collectionRest))
|
||||||
.contentType(contentType))
|
.contentType(contentType))
|
||||||
|
@@ -9,6 +9,7 @@ package org.dspace.app.rest;
|
|||||||
|
|
||||||
import static com.jayway.jsonpath.JsonPath.read;
|
import static com.jayway.jsonpath.JsonPath.read;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@@ -21,8 +22,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
@@ -31,6 +36,7 @@ import org.dspace.app.rest.builder.CommunityBuilder;
|
|||||||
import org.dspace.app.rest.converter.CommunityConverter;
|
import org.dspace.app.rest.converter.CommunityConverter;
|
||||||
import org.dspace.app.rest.matcher.CommunityMatcher;
|
import org.dspace.app.rest.matcher.CommunityMatcher;
|
||||||
import org.dspace.app.rest.matcher.MetadataMatcher;
|
import org.dspace.app.rest.matcher.MetadataMatcher;
|
||||||
|
import org.dspace.app.rest.matcher.PageMatcher;
|
||||||
import org.dspace.app.rest.model.CommunityRest;
|
import org.dspace.app.rest.model.CommunityRest;
|
||||||
import org.dspace.app.rest.model.MetadataRest;
|
import org.dspace.app.rest.model.MetadataRest;
|
||||||
import org.dspace.app.rest.model.MetadataValueRest;
|
import org.dspace.app.rest.model.MetadataValueRest;
|
||||||
@@ -43,9 +49,12 @@ import org.dspace.content.service.CommunityService;
|
|||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration Tests against the /api/core/communities endpoint (including any subpaths)
|
* Integration Tests against the /api/core/communities endpoint (including any subpaths)
|
||||||
@@ -132,7 +141,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createWithParentTest() throws Exception {
|
public void createSubCommunityUnAuthorizedTest() throws Exception {
|
||||||
//We turn off the authorization system in order to create the structure as defined below
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
@@ -140,6 +149,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
.withName("Parent Community")
|
.withName("Parent Community")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
@@ -147,26 +157,65 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
// We send a name but the created community should set this to the title
|
// We send a name but the created community should set this to the title
|
||||||
comm.setName("Test Sub-Level Community");
|
comm.setName("Test Sub-Level Community");
|
||||||
|
|
||||||
comm.setMetadata(new MetadataRest()
|
// Anonymous user tries to create a community.
|
||||||
.put("dc.description",
|
// Should fail because user is not authenticated. Error 401.
|
||||||
new MetadataValueRest("<p>Some cool HTML code here</p>"))
|
getClient().perform(post("/api/core/communities")
|
||||||
.put("dc.description.abstract",
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
new MetadataValueRest("Sample top-level community created via the REST API"))
|
.param("parent", parentCommunity.getID().toString())
|
||||||
.put("dc.description.tableofcontents",
|
.contentType(contentType))
|
||||||
new MetadataValueRest("<p>HTML News</p>"))
|
.andExpect(status().isUnauthorized());
|
||||||
.put("dc.rights",
|
|
||||||
new MetadataValueRest("Custom Copyright Text"))
|
|
||||||
.put("dc.title",
|
|
||||||
new MetadataValueRest("Title Text")));
|
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
// Non-admin Eperson tries to create a community.
|
||||||
// Capture the UUID of the created Community (see andDo() below)
|
// Should fail because user doesn't have permissions. Error 403.
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
|
.param("parent", parentCommunity.getID().toString())
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createSubCommunityAuthorizedTest() throws Exception {
|
||||||
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
// Create a parent community to POST a new sub-community to
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// ADD authorization on parent community
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
authorizeService.addPolicy(context, parentCommunity, Constants.ADD, eperson);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
CommunityRest comm = new CommunityRest();
|
||||||
|
// We send a name but the created community should set this to the title
|
||||||
|
comm.setName("Test Sub-Level Community");
|
||||||
|
|
||||||
|
comm.setMetadata(new MetadataRest()
|
||||||
|
.put("dc.description",
|
||||||
|
new MetadataValueRest("<p>Some cool HTML code here</p>"))
|
||||||
|
.put("dc.description.abstract",
|
||||||
|
new MetadataValueRest("Sample top-level community created via the REST API"))
|
||||||
|
.put("dc.description.tableofcontents",
|
||||||
|
new MetadataValueRest("<p>HTML News</p>"))
|
||||||
|
.put("dc.rights",
|
||||||
|
new MetadataValueRest("Custom Copyright Text"))
|
||||||
|
.put("dc.title",
|
||||||
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
|
// Capture the UUID of the created Community (see andDo() below)
|
||||||
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
|
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
|
||||||
try {
|
try {
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.content(mapper.writeValueAsBytes(comm))
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
.param("parent", parentCommunity.getID().toString())
|
.param("parent", parentCommunity.getID().toString())
|
||||||
.contentType(contentType))
|
.contentType(contentType))
|
||||||
.andExpect(status().isCreated())
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$", Matchers.allOf(
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
@@ -181,15 +230,15 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
MetadataMatcher.matchMetadata("dc.description",
|
MetadataMatcher.matchMetadata("dc.description",
|
||||||
"<p>Some cool HTML code here</p>"),
|
"<p>Some cool HTML code here</p>"),
|
||||||
MetadataMatcher.matchMetadata("dc.description.abstract",
|
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||||
"Sample top-level community created via the REST API"),
|
"Sample top-level community created via the REST API"),
|
||||||
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
||||||
"<p>HTML News</p>"),
|
"<p>HTML News</p>"),
|
||||||
MetadataMatcher.matchMetadata("dc.rights",
|
MetadataMatcher.matchMetadata("dc.rights",
|
||||||
"Custom Copyright Text"),
|
"Custom Copyright Text"),
|
||||||
MetadataMatcher.matchMetadata("dc.title",
|
MetadataMatcher.matchMetadata("dc.title",
|
||||||
"Title Text")
|
"Title Text")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)))
|
)))
|
||||||
@@ -218,6 +267,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
comm.setMetadata(metadataRest);
|
comm.setMetadata(metadataRest);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
// Anonymous user tries to create a community.
|
// Anonymous user tries to create a community.
|
||||||
// Should fail because user is not authenticated. Error 401.
|
// Should fail because user is not authenticated. Error 401.
|
||||||
getClient().perform(post("/api/core/communities")
|
getClient().perform(post("/api/core/communities")
|
||||||
@@ -253,6 +304,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.withLogo("Test Logo")
|
.withLogo("Test Logo")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities"))
|
getClient().perform(get("/api/core/communities"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -269,6 +322,125 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllNoDuplicatesOnMultipleCommunityTitlesTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
List<String> titles = Arrays.asList("First title", "Second title", "Third title", "Fourth title");
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName(titles.get(0))
|
||||||
|
.withTitle(titles.get(1))
|
||||||
|
.withTitle(titles.get(2))
|
||||||
|
.withTitle(titles.get(3))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/communities").param("size", "2"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
|
||||||
|
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
|
||||||
|
parentCommunity.getHandle()),
|
||||||
|
CommunityMatcher.matchCommunityEntry(child1.getID(), child1.getHandle())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(2)))
|
||||||
|
.andExpect(jsonPath("$.page.totalPages", is(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllNoDuplicatesOnMultipleCommunityTitlesPaginationTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
List<String> titles = Arrays.asList("First title", "Second title", "Third title", "Fourth title");
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName(titles.get(0))
|
||||||
|
.withTitle(titles.get(1))
|
||||||
|
.withTitle(titles.get(2))
|
||||||
|
.withTitle(titles.get(3))
|
||||||
|
.build();
|
||||||
|
Community childCommunity = CommunityBuilder.createSubCommunity(context, parentCommunity).build();
|
||||||
|
Community secondParentCommunity = CommunityBuilder.createCommunity(context).withName("testing").build();
|
||||||
|
Community thirdParentCommunity = CommunityBuilder.createCommunity(context).withName("testingTitleTwo").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/communities").param("size", "2"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
|
||||||
|
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
|
||||||
|
parentCommunity.getHandle()),
|
||||||
|
CommunityMatcher.matchCommunityEntry(childCommunity.getID(), childCommunity.getHandle())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
|
||||||
|
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 2, 2, 4)));
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/communities").param("size", "2").param("page", "1"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
|
||||||
|
CommunityMatcher.matchCommunityEntry(secondParentCommunity.getID(),
|
||||||
|
secondParentCommunity.getHandle()),
|
||||||
|
CommunityMatcher.matchCommunityEntry(thirdParentCommunity.getID(),
|
||||||
|
thirdParentCommunity.getHandle())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
|
||||||
|
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(1, 2, 2, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllNoNameCommunityIsReturned() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context).build();
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/communities"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$._embedded.communities", Matchers.contains(
|
||||||
|
CommunityMatcher.matchCommunityEntry(parentCommunity.getID(),
|
||||||
|
parentCommunity.getHandle())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllCommunitiesAreReturnedInCorrectOrder() throws Exception {
|
||||||
|
// The hibernate query for finding all communities is "SELECT ... ORDER BY STR(dc_title.value)"
|
||||||
|
// So the communities should be returned in alphabetical order
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
List<String> orderedTitles = Arrays.asList("Abc", "Bcd", "Cde");
|
||||||
|
|
||||||
|
Community community1 = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName(orderedTitles.get(0))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Community community2 = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName(orderedTitles.get(1))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Community community3 = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName(orderedTitles.get(2))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
MvcResult result = getClient().perform(get("/api/core/communities")).andReturn();
|
||||||
|
String response = result.getResponse().getContentAsString();
|
||||||
|
JSONArray communities = new JSONObject(response).getJSONObject("_embedded").getJSONArray("communities");
|
||||||
|
List<String> responseTitles = StreamSupport.stream(communities.spliterator(), false)
|
||||||
|
.map(JSONObject.class::cast)
|
||||||
|
.map(x -> x.getString("name"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertEquals(orderedTitles, responseTitles);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllPaginationTest() throws Exception {
|
public void findAllPaginationTest() throws Exception {
|
||||||
//We turn off the authorization system in order to create the structure as defined below
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
@@ -284,6 +456,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities")
|
getClient().perform(get("/api/core/communities")
|
||||||
.param("size", "1"))
|
.param("size", "1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -335,6 +509,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -367,6 +543,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -444,6 +622,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/search/top"))
|
getClient().perform(get("/api/core/communities/search/top"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -504,6 +683,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.withName("Collection 1")
|
.withName("Collection 1")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/search/subCommunities")
|
getClient().perform(get("/api/core/communities/search/subCommunities")
|
||||||
.param("parent", parentCommunity.getID().toString()))
|
.param("parent", parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -611,6 +792,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/" + UUID.randomUUID())).andExpect(status().isNotFound());
|
getClient().perform(get("/api/core/communities/" + UUID.randomUUID())).andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,6 +836,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
communityRest.setMetadata(new MetadataRest()
|
communityRest.setMetadata(new MetadataRest()
|
||||||
.put("dc.title", new MetadataValueRest("Electronic theses and dissertations")));
|
.put("dc.title", new MetadataValueRest("Electronic theses and dissertations")));
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(put("/api/core/communities/" + parentCommunity.getID().toString())
|
getClient(token).perform(put("/api/core/communities/" + parentCommunity.getID().toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(mapper.writeValueAsBytes(communityRest)))
|
.content(mapper.writeValueAsBytes(communityRest)))
|
||||||
@@ -711,6 +896,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
getClient(token).perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -770,6 +957,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.withName("Collection 1")
|
.withName("Collection 1")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
getClient().perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -801,6 +989,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
String token = getAuthToken(eperson.getEmail(), password);
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
getClient(token).perform(get("/api/core/communities/" + parentCommunity.getID().toString()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -859,6 +1049,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
context.setCurrentUser(eperson);
|
context.setCurrentUser(eperson);
|
||||||
authorizeService.addPolicy(context, parentCommunity, Constants.WRITE, eperson);
|
authorizeService.addPolicy(context, parentCommunity, Constants.WRITE, eperson);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
String token = getAuthToken(eperson.getEmail(), password);
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
getClient(token).perform(put("/api/core/communities/" + parentCommunity.getID().toString())
|
getClient(token).perform(put("/api/core/communities/" + parentCommunity.getID().toString())
|
||||||
@@ -935,6 +1127,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
comm.setMetadata(metadataRest);
|
comm.setMetadata(metadataRest);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.param("parent", "123")
|
.param("parent", "123")
|
||||||
|
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.matcher.MetadataConfigsMatcher;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test for harvester metadata controller
|
||||||
|
*
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class HarvesterMetadataControllerIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GetReturnsAllAvailableMetadataFormats() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
|
||||||
|
|
||||||
|
getClient(token).perform(
|
||||||
|
get("/api/config/harvestermetadata"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
MetadataConfigsMatcher.matchMetadataConfigs(configs)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", endsWith("/api/config/harvestermetadata")));
|
||||||
|
|
||||||
|
|
||||||
|
getClient().perform(
|
||||||
|
get("/api/config/harvestermetadata"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
MetadataConfigsMatcher.matchMetadataConfigs(configs)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", endsWith("/api/config/harvestermetadata")));
|
||||||
|
|
||||||
|
token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(token).perform(
|
||||||
|
get("/api/config/harvestermetadata"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
MetadataConfigsMatcher.matchMetadataConfigs(configs)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", endsWith("/api/config/harvestermetadata")));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -49,87 +49,87 @@ public class RelationshipTypeRestRepositoryIT extends AbstractEntityIntegrationT
|
|||||||
public void findPublicationPersonRelationshipType() throws SQLException {
|
public void findPublicationPersonRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Publication";
|
String leftTypeString = "Publication";
|
||||||
String rightTypeString = "Person";
|
String rightTypeString = "Person";
|
||||||
String leftLabel = "isAuthorOfPublication";
|
String leftwardType = "isAuthorOfPublication";
|
||||||
String rightLabel = "isPublicationOfAuthor";
|
String rightwardType = "isPublicationOfAuthor";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findPublicationProjectRelationshipType() throws SQLException {
|
public void findPublicationProjectRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Publication";
|
String leftTypeString = "Publication";
|
||||||
String rightTypeString = "Project";
|
String rightTypeString = "Project";
|
||||||
String leftLabel = "isProjectOfPublication";
|
String leftwardType = "isProjectOfPublication";
|
||||||
String rightLabel = "isPublicationOfProject";
|
String rightwardType = "isPublicationOfProject";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findPublicationOrgUnitRelationshipType() throws SQLException {
|
public void findPublicationOrgUnitRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Publication";
|
String leftTypeString = "Publication";
|
||||||
String rightTypeString = "OrgUnit";
|
String rightTypeString = "OrgUnit";
|
||||||
String leftLabel = "isOrgUnitOfPublication";
|
String leftwardType = "isOrgUnitOfPublication";
|
||||||
String rightLabel = "isPublicationOfOrgUnit";
|
String rightwardType = "isPublicationOfOrgUnit";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findPersonProjectRelationshipType() throws SQLException {
|
public void findPersonProjectRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Person";
|
String leftTypeString = "Person";
|
||||||
String rightTypeString = "Project";
|
String rightTypeString = "Project";
|
||||||
String leftLabel = "isProjectOfPerson";
|
String leftwardType = "isProjectOfPerson";
|
||||||
String rightLabel = "isPersonOfProject";
|
String rightwardType = "isPersonOfProject";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findPersonOrgUnitRelationshipType() throws SQLException {
|
public void findPersonOrgUnitRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Person";
|
String leftTypeString = "Person";
|
||||||
String rightTypeString = "OrgUnit";
|
String rightTypeString = "OrgUnit";
|
||||||
String leftLabel = "isOrgUnitOfPerson";
|
String leftwardType = "isOrgUnitOfPerson";
|
||||||
String rightLabel = "isPersonOfOrgUnit";
|
String rightwardType = "isPersonOfOrgUnit";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findProjectOrgUnitRelationshipType() throws SQLException {
|
public void findProjectOrgUnitRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Project";
|
String leftTypeString = "Project";
|
||||||
String rightTypeString = "OrgUnit";
|
String rightTypeString = "OrgUnit";
|
||||||
String leftLabel = "isOrgUnitOfProject";
|
String leftwardType = "isOrgUnitOfProject";
|
||||||
String rightLabel = "isProjectOfOrgUnit";
|
String rightwardType = "isProjectOfOrgUnit";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findJournalJournalVolumeRelationshipType() throws SQLException {
|
public void findJournalJournalVolumeRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "Journal";
|
String leftTypeString = "Journal";
|
||||||
String rightTypeString = "JournalVolume";
|
String rightTypeString = "JournalVolume";
|
||||||
String leftLabel = "isVolumeOfJournal";
|
String leftwardType = "isVolumeOfJournal";
|
||||||
String rightLabel = "isJournalOfVolume";
|
String rightwardType = "isJournalOfVolume";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findJournalVolumeJournalIssueRelationshipType() throws SQLException {
|
public void findJournalVolumeJournalIssueRelationshipType() throws SQLException {
|
||||||
String leftTypeString = "JournalVolume";
|
String leftTypeString = "JournalVolume";
|
||||||
String rightTypeString = "JournalIssue";
|
String rightTypeString = "JournalIssue";
|
||||||
String leftLabel = "isIssueOfJournalVolume";
|
String leftwardType = "isIssueOfJournalVolume";
|
||||||
String rightLabel = "isJournalVolumeOfIssue";
|
String rightwardType = "isJournalVolumeOfIssue";
|
||||||
checkRelationshipType(leftTypeString, rightTypeString, leftLabel, rightLabel);
|
checkRelationshipType(leftTypeString, rightTypeString, leftwardType, rightwardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRelationshipType(String leftType, String rightType, String leftLabel, String rightLabel)
|
private void checkRelationshipType(String leftType, String rightType, String leftwardType, String rightwardType)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
RelationshipType relationshipType = relationshipTypeService
|
RelationshipType relationshipType = relationshipTypeService
|
||||||
.findbyTypesAndLabels(context, entityTypeService.findByEntityType(context, leftType),
|
.findbyTypesAndLabels(context, entityTypeService.findByEntityType(context, leftType),
|
||||||
entityTypeService.findByEntityType(context, rightType),
|
entityTypeService.findByEntityType(context, rightType),
|
||||||
leftLabel, rightLabel);
|
leftwardType, rightwardType);
|
||||||
assertNotNull(relationshipType);
|
assertNotNull(relationshipType);
|
||||||
assertEquals(entityTypeService.findByEntityType(context, leftType),
|
assertEquals(entityTypeService.findByEntityType(context, leftType),
|
||||||
relationshipType.getLeftType());
|
relationshipType.getLeftType());
|
||||||
assertEquals(entityTypeService.findByEntityType(context, rightType),
|
assertEquals(entityTypeService.findByEntityType(context, rightType),
|
||||||
relationshipType.getRightType());
|
relationshipType.getRightType());
|
||||||
assertEquals(leftLabel, relationshipType.getLeftLabel());
|
assertEquals(leftwardType, relationshipType.getLeftwardType());
|
||||||
assertEquals(rightLabel, relationshipType.getRightLabel());
|
assertEquals(rightwardType, relationshipType.getRightwardType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -167,8 +167,8 @@ public class RelationshipTypeRestRepositoryIT extends AbstractEntityIntegrationT
|
|||||||
|
|
||||||
RelationshipType foundRelationshipType = null;
|
RelationshipType foundRelationshipType = null;
|
||||||
for (RelationshipType relationshipType : relationshipTypes) {
|
for (RelationshipType relationshipType : relationshipTypes) {
|
||||||
if (StringUtils.equals(relationshipType.getLeftLabel(), "isAuthorOfPublication") && StringUtils
|
if (StringUtils.equals(relationshipType.getLeftwardType(), "isAuthorOfPublication") && StringUtils
|
||||||
.equals(relationshipType.getRightLabel(), "isPublicationOfAuthor")) {
|
.equals(relationshipType.getRightwardType(), "isPublicationOfAuthor")) {
|
||||||
foundRelationshipType = relationshipType;
|
foundRelationshipType = relationshipType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -212,8 +212,8 @@ public class RelationshipTypeRestRepositoryIT extends AbstractEntityIntegrationT
|
|||||||
|
|
||||||
RelationshipType foundRelationshipType = null;
|
RelationshipType foundRelationshipType = null;
|
||||||
for (RelationshipType relationshipType : relationshipTypes) {
|
for (RelationshipType relationshipType : relationshipTypes) {
|
||||||
if (StringUtils.equals(relationshipType.getLeftLabel(), "isIssueOfJournalVolume") && StringUtils
|
if (StringUtils.equals(relationshipType.getLeftwardType(), "isIssueOfJournalVolume") && StringUtils
|
||||||
.equals(relationshipType.getRightLabel(), "isJournalVolumeOfIssue")) {
|
.equals(relationshipType.getRightwardType(), "isJournalVolumeOfIssue")) {
|
||||||
foundRelationshipType = relationshipType;
|
foundRelationshipType = relationshipType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -63,6 +63,10 @@ public class CommunityBuilder extends AbstractDSpaceObjectBuilder<Community> {
|
|||||||
return setMetadataSingleValue(community, MetadataSchemaEnum.DC.getName(), "title", null, communityName);
|
return setMetadataSingleValue(community, MetadataSchemaEnum.DC.getName(), "title", null, communityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommunityBuilder withTitle(final String communityTitle) {
|
||||||
|
return addMetadataValue(community, MetadataSchemaEnum.DC.getName(), "title", null, communityTitle);
|
||||||
|
}
|
||||||
|
|
||||||
public CommunityBuilder withLogo(String content) throws AuthorizeException, IOException, SQLException {
|
public CommunityBuilder withLogo(String content) throws AuthorizeException, IOException, SQLException {
|
||||||
try (InputStream is = IOUtils.toInputStream(content, CharEncoding.UTF_8)) {
|
try (InputStream is = IOUtils.toInputStream(content, CharEncoding.UTF_8)) {
|
||||||
communityService.setLogo(context, community, is);
|
communityService.setLogo(context, community, is);
|
||||||
|
@@ -84,4 +84,19 @@ public class RelationshipBuilder extends AbstractBuilder<Relationship, Relations
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RelationshipBuilder withLeftwardValue(String leftwardValue) throws SQLException {
|
||||||
|
relationship.setLeftwardValue(leftwardValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RelationshipBuilder withRightwardValue(String rightwardValue) throws SQLException {
|
||||||
|
relationship.setRightwardValue(rightwardValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RelationshipBuilder withLeftPlace(int leftPlace) {
|
||||||
|
relationship.setLeftPlace(leftPlace);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -74,28 +74,30 @@ public class RelationshipTypeBuilder extends AbstractBuilder<RelationshipType, R
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static RelationshipTypeBuilder createRelationshipTypeBuilder(Context context, EntityType leftType,
|
public static RelationshipTypeBuilder createRelationshipTypeBuilder(Context context, EntityType leftType,
|
||||||
EntityType rightType, String leftLabel,
|
EntityType rightType,
|
||||||
String rightLabel, Integer leftCardinalityMin,
|
String leftwardType,
|
||||||
|
String rightwardType,
|
||||||
|
Integer leftCardinalityMin,
|
||||||
Integer leftCardinalityMax,
|
Integer leftCardinalityMax,
|
||||||
Integer rightCardinalityMin,
|
Integer rightCardinalityMin,
|
||||||
Integer rightCardinalityMax) {
|
Integer rightCardinalityMax) {
|
||||||
RelationshipTypeBuilder relationshipBuilder = new RelationshipTypeBuilder(context);
|
RelationshipTypeBuilder relationshipBuilder = new RelationshipTypeBuilder(context);
|
||||||
return relationshipBuilder.create(context, leftType,
|
return relationshipBuilder.create(context, leftType,
|
||||||
rightType, leftLabel,
|
rightType, leftwardType,
|
||||||
rightLabel, leftCardinalityMin,
|
rightwardType, leftCardinalityMin,
|
||||||
leftCardinalityMax, rightCardinalityMin,
|
leftCardinalityMax, rightCardinalityMin,
|
||||||
rightCardinalityMax);
|
rightCardinalityMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RelationshipTypeBuilder create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
private RelationshipTypeBuilder create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||||
String leftLabel, String rightLabel, Integer leftCardinalityMin,
|
String leftwardType, String rightwardType, Integer leftCardinalityMin,
|
||||||
Integer leftCardinalityMax, Integer rightCardinalityMin,
|
Integer leftCardinalityMax, Integer rightCardinalityMin,
|
||||||
Integer rightCardinalityMax) {
|
Integer rightCardinalityMax) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.relationshipType = relationshipTypeService
|
this.relationshipType = relationshipTypeService
|
||||||
.create(context, leftEntityType, rightEntityType, leftLabel, rightLabel, leftCardinalityMin,
|
.create(context, leftEntityType, rightEntityType, leftwardType, rightwardType, leftCardinalityMin,
|
||||||
leftCardinalityMax, rightCardinalityMin, rightCardinalityMax);
|
leftCardinalityMax, rightCardinalityMin, rightCardinalityMax);
|
||||||
|
|
||||||
} catch (SQLException | AuthorizeException e) {
|
} catch (SQLException | AuthorizeException e) {
|
||||||
|
@@ -11,6 +11,7 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
|||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
@@ -21,6 +22,34 @@ public class CommunityMatcher {
|
|||||||
|
|
||||||
private CommunityMatcher() { }
|
private CommunityMatcher() { }
|
||||||
|
|
||||||
|
// Matcher for communities with no titles / no name
|
||||||
|
// Since a name is simply the first title (see Community.java), we cannot use the matchers below
|
||||||
|
public static Matcher<? super Object> matchCommunityEntry(UUID uuid, String handle) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.uuid", is(uuid.toString())),
|
||||||
|
hasJsonPath("$.handle", is(handle)),
|
||||||
|
hasJsonPath("$.type", is("community")),
|
||||||
|
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
|
||||||
|
hasJsonPath("$._embedded.logo", Matchers.not(Matchers.empty())),
|
||||||
|
matchLinks(uuid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matcher for communities with multiple titles
|
||||||
|
// The title metadata for communities with multiple titles contains a list, so the matchers below can't be used
|
||||||
|
public static Matcher<? super Object> matchCommunityEntryMultipleTitles(List<String> titles, UUID uuid,
|
||||||
|
String handle) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.uuid", is(uuid.toString())),
|
||||||
|
hasJsonPath("$.name", is(titles.get(0))),
|
||||||
|
hasJsonPath("$.handle", is(handle)),
|
||||||
|
hasJsonPath("$.type", is("community")),
|
||||||
|
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
|
||||||
|
hasJsonPath("$._embedded.logo", Matchers.not(Matchers.empty())),
|
||||||
|
matchLinks(uuid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Matcher<? super Object> matchCommunityEntry(String name, UUID uuid, String handle) {
|
public static Matcher<? super Object> matchCommunityEntry(String name, UUID uuid, String handle) {
|
||||||
return allOf(
|
return allOf(
|
||||||
matchProperties(name, uuid, handle),
|
matchProperties(name, uuid, handle),
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.matcher;
|
||||||
|
|
||||||
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.hamcrest.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used for matching metadata configurations in JSON
|
||||||
|
*/
|
||||||
|
public class MetadataConfigsMatcher {
|
||||||
|
|
||||||
|
private MetadataConfigsMatcher() { }
|
||||||
|
|
||||||
|
public static Matcher<? super Object> matchMetadataConfigs(List<Map<String,String>> configs) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns a list of values, containing the values matching the key for each
|
||||||
|
* configuration (Map<String,String>) in the list. For example, getAllValues("id") returns
|
||||||
|
* a list with the ids of every configuration in the list.
|
||||||
|
*/
|
||||||
|
Function<String,List<String>> getAllValues = key -> configs.stream()
|
||||||
|
.map(x -> x.get(key))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.configs[*].id", is(getAllValues.apply("id"))),
|
||||||
|
hasJsonPath("$.configs[*].label", is(getAllValues.apply("label"))),
|
||||||
|
hasJsonPath("$.configs[*].namespace", is(getAllValues.apply("namespace"))),
|
||||||
|
hasJsonPath("$._links.self.href", endsWith("/api/config/harvestermetadata"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -8,7 +8,7 @@
|
|||||||
package org.dspace.app.rest.matcher;
|
package org.dspace.app.rest.matcher;
|
||||||
|
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
@@ -18,7 +18,8 @@ import org.hamcrest.Matcher;
|
|||||||
*/
|
*/
|
||||||
public class MetadataMatcher {
|
public class MetadataMatcher {
|
||||||
|
|
||||||
private MetadataMatcher() { }
|
private MetadataMatcher() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a matcher to ensure a given value is present among all values for a given metadata key.
|
* Gets a matcher to ensure a given value is present among all values for a given metadata key.
|
||||||
@@ -28,7 +29,7 @@ public class MetadataMatcher {
|
|||||||
* @return the matcher.
|
* @return the matcher.
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchMetadata(String key, String value) {
|
public static Matcher<? super Object> matchMetadata(String key, String value) {
|
||||||
return hasJsonPath("$.['" + key + "'][*].value", contains(value));
|
return hasJsonPath("$.['" + key + "'][*].value", hasItem(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -38,8 +38,8 @@ public class RelationshipTypeMatcher {
|
|||||||
String rightEntityTypeLabel) {
|
String rightEntityTypeLabel) {
|
||||||
|
|
||||||
return matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(relationshipType.getID(),
|
return matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(relationshipType.getID(),
|
||||||
relationshipType.getLeftLabel(),
|
relationshipType.getLeftwardType(),
|
||||||
relationshipType.getRightLabel(),
|
relationshipType.getRightwardType(),
|
||||||
relationshipType.getLeftMinCardinality(),
|
relationshipType.getLeftMinCardinality(),
|
||||||
relationshipType.getLeftMaxCardinality(),
|
relationshipType.getLeftMaxCardinality(),
|
||||||
relationshipType.getRightMinCardinality(),
|
relationshipType.getRightMinCardinality(),
|
||||||
@@ -49,10 +49,10 @@ public class RelationshipTypeMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Matcher<? super Object> matchExplicitRelationshipTypeValuesAndExplicitEntityType(int id,
|
private static Matcher<? super Object> matchExplicitRelationshipTypeValuesAndExplicitEntityType(int id,
|
||||||
String leftLabel, String rightLabel, Integer leftMinCardinality, Integer leftMaxCardinality,
|
String leftwardType, String rightwardType, Integer leftMinCardinality, Integer leftMaxCardinality,
|
||||||
Integer rightMinCardinality, Integer rightMaxCardinality,
|
Integer rightMinCardinality, Integer rightMaxCardinality,
|
||||||
EntityType leftEntityType, EntityType rightEntityType) {
|
EntityType leftEntityType, EntityType rightEntityType) {
|
||||||
return matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(id, leftLabel, rightLabel,
|
return matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(id, leftwardType, rightwardType,
|
||||||
leftMinCardinality, leftMaxCardinality,
|
leftMinCardinality, leftMaxCardinality,
|
||||||
rightMinCardinality,
|
rightMinCardinality,
|
||||||
rightMaxCardinality,
|
rightMaxCardinality,
|
||||||
@@ -63,13 +63,13 @@ public class RelationshipTypeMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Matcher<? super Object> matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(int id,
|
private static Matcher<? super Object> matchExplicitRelationshipTypeValuesAndExplicitEntityTypeValues(int id,
|
||||||
String leftLabel, String rightLabel, Integer leftMinCardinality, Integer leftMaxCardinality,
|
String leftwardType, String rightwardType, Integer leftMinCardinality, Integer leftMaxCardinality,
|
||||||
Integer rightMinCardinality, Integer rightMaxCardinality, int leftEntityTypeId, String leftEntityTypeLabel,
|
Integer rightMinCardinality, Integer rightMaxCardinality, int leftEntityTypeId, String leftEntityTypeLabel,
|
||||||
int rightEntityTypeId, String rightEntityTypeLabel) {
|
int rightEntityTypeId, String rightEntityTypeLabel) {
|
||||||
return allOf(
|
return allOf(
|
||||||
hasJsonPath("$.id", is(id)),
|
hasJsonPath("$.id", is(id)),
|
||||||
hasJsonPath("$.leftLabel", is(leftLabel)),
|
hasJsonPath("$.leftwardType", is(leftwardType)),
|
||||||
hasJsonPath("$.rightLabel", is(rightLabel)),
|
hasJsonPath("$.rightwardType", is(rightwardType)),
|
||||||
hasJsonPath("$.leftMinCardinality", is(leftMinCardinality)),
|
hasJsonPath("$.leftMinCardinality", is(leftMinCardinality)),
|
||||||
hasJsonPath("$.leftMaxCardinality", is(leftMaxCardinality)),
|
hasJsonPath("$.leftMaxCardinality", is(leftMaxCardinality)),
|
||||||
hasJsonPath("$.rightMinCardinality", is(rightMinCardinality)),
|
hasJsonPath("$.rightMinCardinality", is(rightMinCardinality)),
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.harvest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mock for the HarvestedCollectionService
|
||||||
|
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
|
||||||
|
*/
|
||||||
|
public class MockHarvestedCollectionServiceImpl extends HarvestedCollectionServiceImpl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> verifyOAIharvester(String oaiSource,
|
||||||
|
String oaiSetId, String metaPrefix, boolean testORE) {
|
||||||
|
|
||||||
|
if (metaPrefix.equals("dc")) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
return Arrays.asList("(Mock error) Incorrect metadataConfigID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -54,6 +54,7 @@
|
|||||||
<bean class="org.dspace.content.EntityTypeServiceImpl"/>
|
<bean class="org.dspace.content.EntityTypeServiceImpl"/>
|
||||||
<bean class="org.dspace.content.EntityServiceImpl"/>
|
<bean class="org.dspace.content.EntityServiceImpl"/>
|
||||||
<bean class="org.dspace.content.RelationshipTypeServiceImpl"/>
|
<bean class="org.dspace.content.RelationshipTypeServiceImpl"/>
|
||||||
|
<bean class="org.dspace.content.RelationshipMetadataServiceImpl"/>
|
||||||
|
|
||||||
<bean class="org.dspace.content.authority.ChoiceAuthorityServiceImpl"/>
|
<bean class="org.dspace.content.authority.ChoiceAuthorityServiceImpl"/>
|
||||||
<bean class="org.dspace.content.authority.MetadataAuthorityServiceImpl" lazy-init="true"/>
|
<bean class="org.dspace.content.authority.MetadataAuthorityServiceImpl" lazy-init="true"/>
|
||||||
|
@@ -59,6 +59,7 @@
|
|||||||
<value>, </value>
|
<value>, </value>
|
||||||
</property>
|
</property>
|
||||||
<property name="useForPlace" value="true"/>
|
<property name="useForPlace" value="true"/>
|
||||||
|
<property name="populateWithNameVariant" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Config like this will tell our VirtualMetadataPopulator to include the virtual metadata field
|
<!-- Config like this will tell our VirtualMetadataPopulator to include the virtual metadata field
|
||||||
|
86
dspace/src/main/docker-compose/README.md
Normal file
86
dspace/src/main/docker-compose/README.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Docker Compose Resources
|
||||||
|
|
||||||
|
## root directory Resources
|
||||||
|
- docker-compose.yml
|
||||||
|
- Docker compose file to orchestrate DSpace 7 REST components
|
||||||
|
- docker-compose-cli
|
||||||
|
- Docker compose file to run DSpace CLI tasks within a running DSpace instance in Docker
|
||||||
|
|
||||||
|
## dspace/src/main/docker-compose resources
|
||||||
|
|
||||||
|
- cli.assetstore.yml
|
||||||
|
- Docker compose file that will download and install a default assetstore.
|
||||||
|
- cli.ingest.yml
|
||||||
|
- Docker compose file that will run an AIP ingest into DSpace 7.
|
||||||
|
- db.entities.yml
|
||||||
|
- Docker compose file that pre-populate a database instance using a SQL dump. The default dataset is the configurable entities test dataset.
|
||||||
|
- local.cfg
|
||||||
|
- Sets the environment used across containers run with docker-compose
|
||||||
|
- docker-compose-angular.yml
|
||||||
|
- Docker compose file that will start a published DSpace angular container that interacts with the branch.
|
||||||
|
- environment.dev.js
|
||||||
|
- Default angular environment when testing DSpace-angular from this repo
|
||||||
|
|
||||||
|
## To refresh / pull DSpace images from Dockerhub
|
||||||
|
```
|
||||||
|
docker-compose -f docker-compose.yml -f docker-compose-cli.yml pull
|
||||||
|
```
|
||||||
|
|
||||||
|
## To build DSpace images using code in your branch
|
||||||
|
```
|
||||||
|
docker-compose -f docker-compose.yml -f docker-compose-cli.yml build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run DSpace 7 REST from your current branch
|
||||||
|
```
|
||||||
|
docker-compose -p d7 up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run DSpace 7 REST and Angular from your branch
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-angular.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run DSpace 7 REST and Angular from local branches
|
||||||
|
|
||||||
|
_The system will be started in 2 steps. Each step shares the same docker network._
|
||||||
|
|
||||||
|
From DSpace/DSpace
|
||||||
|
```
|
||||||
|
docker-compose -p d7 up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
From DSpace/DSpace-angular (build as needed)
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker/docker-compose.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ingest Option 1: Ingesting test content from AIP files into a running DSpace 7 instance
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
- Start DSpace 7 using one of the options listed above
|
||||||
|
- Build the DSpace CLI image if needed. See the instructions above.
|
||||||
|
|
||||||
|
Create an admin account. By default, the dspace-cli container runs the dspace command.
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en
|
||||||
|
```
|
||||||
|
|
||||||
|
Download a Zip file of AIP content and ingest test data
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ingest Option 2: Ingest Entities Test Data
|
||||||
|
_Remove your d7 volumes if you already ingested content into your docker volumes_
|
||||||
|
|
||||||
|
Start DSpace REST with a postgres database dump downloaded from the internet.
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker-compose.yml -f dspace/src/main/docker-compose/db.entities.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Download an assetstore from a tar file on the internet.
|
||||||
|
```
|
||||||
|
docker-compose -p d7 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.assetstore.yml run dspace-cli
|
||||||
|
```
|
28
dspace/src/main/docker-compose/cli.assetstore.yml
Normal file
28
dspace/src/main/docker-compose/cli.assetstore.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# 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/
|
||||||
|
#
|
||||||
|
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
dspace-cli:
|
||||||
|
environment:
|
||||||
|
- LOADASSETS=https://www.dropbox.com/s/zv7lj8j2lp3egjs/assetstore.tar.gz?dl=1
|
||||||
|
entrypoint:
|
||||||
|
- /bin/bash
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
if [ ! -z $${LOADASSETS} ]
|
||||||
|
then
|
||||||
|
curl $${LOADASSETS} -L -s --output /tmp/assetstore.tar.gz
|
||||||
|
cd /dspace
|
||||||
|
tar xvfz /tmp/assetstore.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
/dspace/bin/dspace index-discovery
|
||||||
|
/dspace/bin/dspace oai import
|
||||||
|
/dspace/bin/dspace oai clean-cache
|
34
dspace/src/main/docker-compose/cli.ingest.yml
Normal file
34
dspace/src/main/docker-compose/cli.ingest.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# 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/
|
||||||
|
#
|
||||||
|
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
dspace-cli:
|
||||||
|
environment:
|
||||||
|
- AIPZIP=https://github.com/DSpace-Labs/AIP-Files/raw/master/dogAndReport.zip
|
||||||
|
- ADMIN_EMAIL=test@test.edu
|
||||||
|
- AIPDIR=/tmp/aip-dir
|
||||||
|
entrypoint:
|
||||||
|
- /bin/bash
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
rm -rf $${AIPDIR}
|
||||||
|
mkdir $${AIPDIR} /dspace/upload
|
||||||
|
cd $${AIPDIR}
|
||||||
|
pwd
|
||||||
|
curl $${AIPZIP} -L -s --output aip.zip
|
||||||
|
unzip aip.zip
|
||||||
|
cd $${AIPDIR}
|
||||||
|
|
||||||
|
/dspace/bin/dspace packager -r -a -t AIP -e $${ADMIN_EMAIL} -f -u SITE*.zip
|
||||||
|
/dspace/bin/dspace database update-sequences
|
||||||
|
touch /dspace/solr/search/conf/reindex.flag
|
||||||
|
|
||||||
|
/dspace/bin/dspace oai import
|
||||||
|
/dspace/bin/dspace oai clean-cache
|
16
dspace/src/main/docker-compose/db.entities.yml
Normal file
16
dspace/src/main/docker-compose/db.entities.yml
Normal file
@@ -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/
|
||||||
|
#
|
||||||
|
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
dspacedb:
|
||||||
|
image: dspace/dspace-postgres-pgcrypto:loadsql
|
||||||
|
environment:
|
||||||
|
# Double underbars in env names will be replaced with periods for apache commons
|
||||||
|
- LOADSQL=https://www.dropbox.com/s/xh3ack0vg0922p2/configurable-entities-2019-05-08.sql?dl=1
|
33
dspace/src/main/docker-compose/docker-compose-angular.yml
Normal file
33
dspace/src/main/docker-compose/docker-compose-angular.yml
Normal file
@@ -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/
|
||||||
|
#
|
||||||
|
|
||||||
|
version: '3.7'
|
||||||
|
networks:
|
||||||
|
dspacenet:
|
||||||
|
services:
|
||||||
|
dspace-angular:
|
||||||
|
container_name: dspace-angular
|
||||||
|
depends_on:
|
||||||
|
- dspace
|
||||||
|
environment:
|
||||||
|
DSPACE_HOST: dspace-angular
|
||||||
|
DSPACE_NAMESPACE: /
|
||||||
|
DSPACE_PORT: '3000'
|
||||||
|
DSPACE_SSL: "false"
|
||||||
|
image: dspace/dspace-angular:latest
|
||||||
|
networks:
|
||||||
|
dspacenet: {}
|
||||||
|
ports:
|
||||||
|
- published: 3000
|
||||||
|
target: 3000
|
||||||
|
- published: 9876
|
||||||
|
target: 9876
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- ./dspace/src/main/docker-compose/environment.dev.js:/app/config/environment.dev.js
|
16
dspace/src/main/docker-compose/environment.dev.js
Normal file
16
dspace/src/main/docker-compose/environment.dev.js
Normal file
@@ -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/
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
rest: {
|
||||||
|
ssl: false,
|
||||||
|
host: 'localhost',
|
||||||
|
port: 8080,
|
||||||
|
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||||
|
nameSpace: '/server/api'
|
||||||
|
}
|
||||||
|
};
|
6
dspace/src/main/docker-compose/local.cfg
Normal file
6
dspace/src/main/docker-compose/local.cfg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
dspace.dir=/dspace
|
||||||
|
db.url=jdbc:postgresql://dspacedb:5432/dspace
|
||||||
|
dspace.hostname=dspace
|
||||||
|
dspace.baseUrl=http://localhost:8080
|
||||||
|
dspace.name=DSpace Started with Docker Compose
|
||||||
|
solr.server=http://dspacesolr:8983/solr
|
122
dspace/src/main/docker/README.md
Normal file
122
dspace/src/main/docker/README.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# Docker images supporting DSpace
|
||||||
|
|
||||||
|
## Dockerfile.dependencies
|
||||||
|
|
||||||
|
This dockerfile is used to pre-cache maven downloads that will be used in subsequent DSpace docker builds.
|
||||||
|
```
|
||||||
|
docker build -t dspace/dspace-dependencies:dspace-7_x -f Dockerfile.dependencies .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built manually. It should be rebuilt each year or after each major release in order to refresh the cache of jars.
|
||||||
|
|
||||||
|
A corresponding image exists for DSpace 4-6.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace-dependencies:dspace-7_x
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dockerfile.jdk8-test
|
||||||
|
|
||||||
|
This dockefile builds a DSpace 7 tomcat image. The legacy REST api will be deployed without requiring https access.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker build -t dspace/dspace:dspace-7_x-jdk8-test -f Dockerfile.jdk8-test .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built automatically after each commit is made to the master branch.
|
||||||
|
|
||||||
|
A corresponding image exists for DSpace 4-6.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace:dspace-7_x-jdk8-test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dockerfile.jdk8
|
||||||
|
|
||||||
|
This dockefile builds a DSpace 7 tomcat image.
|
||||||
|
```
|
||||||
|
docker build -t dspace/dspace:dspace-7_x-jdk8 -f Dockerfile.jdk8 .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built automatically after each commit is made to the master branch.
|
||||||
|
|
||||||
|
A corresponding image exists for DSpace 4-6.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace:dspace-7_x-jdk8
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dockefile.cli.jdk8
|
||||||
|
|
||||||
|
This dockerfile builds a DSpace 7 CLI image.
|
||||||
|
```
|
||||||
|
docker build -t dspace/dspace-cli:dspace-7_x -f Dockerfile.cli.jdk8 .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built automatically after each commit is made to the master branch.
|
||||||
|
|
||||||
|
A corresponding image exists for DSpace 6.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace-cli:dspace-7_x
|
||||||
|
```
|
||||||
|
|
||||||
|
## dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile
|
||||||
|
|
||||||
|
This is a postgres docker image containing the pgcrypto extension used in DSpace 6 and DSpace 7.
|
||||||
|
```
|
||||||
|
cd dspace/src/main/docker/dspace-postgres-pgcrypto
|
||||||
|
docker build -t dspace/dspace-postgres-pgcrypto .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built manually. It should be rebuilt as needed.
|
||||||
|
|
||||||
|
A copy of this file exists in the DSpace 6 branch. A specialized version of this file exists for DSpace 4 in DSpace-Docker-Images.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace-postgres-pgcrypto
|
||||||
|
```
|
||||||
|
|
||||||
|
## dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile
|
||||||
|
|
||||||
|
This is a postgres docker image containing the pgcrypto extension used in DSpace 6 and DSpace 7.
|
||||||
|
This image also contains curl. The image is pre-configured to load a postgres database dump on initialization.
|
||||||
|
```
|
||||||
|
cd dspace/src/main/docker/dspace-postgres-pgcrypto-curl
|
||||||
|
docker build -t dspace/dspace-postgres-pgcrypto:loadsql .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built manually. It should be rebuilt as needed.
|
||||||
|
|
||||||
|
A copy of this file exists in the DSpace 6 branch.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace-postgres-pgcrypto:loadsql
|
||||||
|
```
|
||||||
|
|
||||||
|
## dspace/src/main/docker/solr/Dockerfile
|
||||||
|
|
||||||
|
This is a standalone solr image containing DSpace solr schemas used in DSpace 7.
|
||||||
|
```
|
||||||
|
cd dspace/src/main/docker/solr
|
||||||
|
docker build -t dspace/dspace-solr .
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is built manually. It should be rebuilt as solr schemas change or as new releases of solr are incorporated.
|
||||||
|
|
||||||
|
This file was introduced for DSpace 7.
|
||||||
|
|
||||||
|
Admins to our DockerHub repo can publish with the following command.
|
||||||
|
```
|
||||||
|
docker push dspace/dspace-solr
|
||||||
|
```
|
||||||
|
|
||||||
|
## local.cfg and test/ folder
|
||||||
|
|
||||||
|
These resources are bundled into the _dspace/dspace_ image at build time.
|
@@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
# The contents of this file are subject to the license and copyright
|
||||||
|
# detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
# tree and available online at
|
||||||
|
#
|
||||||
|
# http://www.dspace.org/license/
|
||||||
|
#
|
||||||
|
|
||||||
|
# This will be deployed as dspace/dspace-postgres-pgcrpyto:loadsql
|
||||||
|
FROM postgres
|
||||||
|
|
||||||
|
ENV POSTGRES_DB dspace
|
||||||
|
ENV POSTGRES_USER dspace
|
||||||
|
ENV POSTGRES_PASSWORD dspace
|
||||||
|
|
||||||
|
# Load a SQL dump. Set LOADSQL to a URL for the sql dump file.
|
||||||
|
RUN apt-get update && apt-get install -y curl
|
||||||
|
|
||||||
|
COPY install-pgcrypto.sh /docker-entrypoint-initdb.d/
|
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# 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/
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
CHECKFILE=/pgdata/ingest.hasrun.flag
|
||||||
|
|
||||||
|
if [ ! -f $CHECKFILE -a ! -z ${LOADSQL} ]
|
||||||
|
then
|
||||||
|
curl ${LOADSQL} -L -s --output /tmp/dspace.sql
|
||||||
|
psql -U $POSTGRES_USER < /tmp/dspace.sql
|
||||||
|
|
||||||
|
touch $CHECKFILE
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||||
|
-- Create a new schema in this database named "extensions" (or whatever you want to name it)
|
||||||
|
CREATE SCHEMA extensions;
|
||||||
|
-- Enable this extension in this new schema
|
||||||
|
CREATE EXTENSION pgcrypto SCHEMA extensions;
|
||||||
|
-- Update your database's "search_path" to also search the new "extensions" schema.
|
||||||
|
-- You are just appending it on the end of the existing comma-separated list.
|
||||||
|
ALTER DATABASE dspace SET search_path TO "\$user",public,extensions;
|
||||||
|
-- Grant rights to call functions in the extensions schema to your dspace user
|
||||||
|
GRANT USAGE ON SCHEMA extensions TO $POSTGRES_USER;
|
||||||
|
EOSQL
|
18
dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile
Normal file
18
dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# 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/
|
||||||
|
#
|
||||||
|
|
||||||
|
# This will be deployed as dspace/dspace-postgres-pgcrpyto:latest
|
||||||
|
FROM postgres
|
||||||
|
|
||||||
|
ENV POSTGRES_DB dspace
|
||||||
|
ENV POSTGRES_USER dspace
|
||||||
|
ENV POSTGRES_PASSWORD dspace
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY install-pgcrypto.sh /docker-entrypoint-initdb.d/
|
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# 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/
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||||
|
-- Create a new schema in this database named "extensions" (or whatever you want to name it)
|
||||||
|
CREATE SCHEMA extensions;
|
||||||
|
-- Enable this extension in this new schema
|
||||||
|
CREATE EXTENSION pgcrypto SCHEMA extensions;
|
||||||
|
-- Update your database's "search_path" to also search the new "extensions" schema.
|
||||||
|
-- You are just appending it on the end of the existing comma-separated list.
|
||||||
|
ALTER DATABASE dspace SET search_path TO "\$user",public,extensions;
|
||||||
|
-- Grant rights to call functions in the extensions schema to your dspace user
|
||||||
|
GRANT USAGE ON SCHEMA extensions TO $POSTGRES_USER;
|
||||||
|
EOSQL
|
Reference in New Issue
Block a user