mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge remote-tracking branch 'dspace/master' into feature-external-sources
This commit is contained in:
@@ -3,4 +3,9 @@
|
||||
.settings/
|
||||
*/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/
|
||||
|
@@ -54,7 +54,13 @@ EXPOSE 8080 8009
|
||||
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||
ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||
ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||
# and the v6.x (deprecated) REST API off the "/rest" path
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||
# Please note that server webapp should only run on one path at a time.
|
||||
#RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||
# ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||
# ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
@@ -54,11 +54,17 @@ EXPOSE 8080 8009
|
||||
|
||||
ENV JAVA_OPTS=-Xmx2000m
|
||||
|
||||
RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||
ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||
ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||
# Run the "server" webapp off the /server path (e.g. http://localhost:8080/server/)
|
||||
# and the v6.x (deprecated) REST API off the "/rest" path
|
||||
RUN ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \
|
||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||
# If you wish to run "server" webapp off the ROOT path, then comment out the above RUN, and uncomment the below RUN.
|
||||
# You also MUST update the URL in dspace/src/main/docker/local.cfg
|
||||
# Please note that server webapp should only run on one path at a time.
|
||||
#RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||
# ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \
|
||||
# ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||
|
||||
# Overwrite the v6.x (deprecated) REST API's web.xml, so that we can run it on HTTP (defaults to requiring HTTPS)
|
||||
COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||
|
||||
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
28
README.md
28
README.md
@@ -3,12 +3,12 @@
|
||||
|
||||
[](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 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)
|
||||
|
||||
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.
|
||||
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.
|
||||
* 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
|
||||
|
||||
|
||||
**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.
|
||||
@@ -31,21 +31,21 @@ Past releases are all available via GitHub at https://github.com/DSpace/DSpace/r
|
||||
|
||||
## Documentation / Installation
|
||||
|
||||
Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.duraspace.org/display/DSDOC/).
|
||||
Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.duraspace.org/display/DSDOC/).
|
||||
|
||||
The latest DSpace Installation instructions are available at:
|
||||
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.
|
||||
More information about these and all other prerequisites can be found in the Installation instructions above.
|
||||
|
||||
## Dockerfile Usage
|
||||
See the [DSpace Docker Tutorial](https://dspace-labs.github.io/DSpace-Docker-Images/).
|
||||
## Running DSpace 7 in Docker
|
||||
See [Running DSpace 7 with Docker Compose](dspace/src/main/docker-compose/README.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
[Registered Service Providers](http://www.dspace.org/service-providers).
|
||||
|
||||
## 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
|
||||
# NOTE: testClassName is just the class name, do not include package
|
||||
mvn clean test -Dmaven.test.skip=false -Dtest=[testClassName]
|
||||
|
||||
|
||||
# Run one test method in a specific test class
|
||||
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: testClassName is just the class name, do not include package
|
||||
mvn clean verify -Dmaven.test.skip=false -DskipITs=false -Dit.test=[testClassName]
|
||||
|
||||
|
||||
# Run one test method in a specific test class
|
||||
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
|
||||
cd [dspace-src]
|
||||
mvn clean install
|
||||
|
||||
|
||||
# Then, move into a module subdirectory, and run the test command
|
||||
cd [dspace-src]/dspace-server-webapp
|
||||
# Choose your test command from the lists above
|
||||
|
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:
|
@@ -17,8 +17,8 @@ import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -38,7 +38,6 @@ import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Entity;
|
||||
import org.dspace.content.EntityType;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
@@ -106,19 +105,44 @@ public class MetadataImport {
|
||||
protected static final String AC_PREFIX = "authority.controlled.";
|
||||
|
||||
/**
|
||||
* Map of field:value to csv row number, used to resolve indirect entity references.
|
||||
* Map of field:value to csv row number, used to resolve indirect entity target references.
|
||||
*
|
||||
* @see #populateRefAndRowMap(DSpaceCSVLine, int, UUID)
|
||||
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||
*/
|
||||
protected HashMap<String, Set<Integer>> csvRefMap = new HashMap<>();
|
||||
protected Map<String, Set<Integer>> csvRefMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map of csv row number to UUID, used to resolve indirect entity references.
|
||||
* Map of csv row number to UUID, used to resolve indirect entity target references.
|
||||
*
|
||||
* @see #populateRefAndRowMap(DSpaceCSVLine, int, UUID)
|
||||
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||
*/
|
||||
protected HashMap<Integer, UUID> csvRowMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map of UUIDs to their entity types.
|
||||
*
|
||||
* @see #populateRefAndRowMap(DSpaceCSVLine, UUID)
|
||||
*/
|
||||
protected static HashMap<UUID, String> entityTypeMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map of UUIDs to their relations that are referenced within any import with their referers.
|
||||
*
|
||||
* @see #populateEntityRelationMap(String, String, String)
|
||||
*/
|
||||
protected static HashMap<String, HashMap<String, ArrayList<String>>> entityRelationMap = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Collection of errors generated during relation validation process.
|
||||
*/
|
||||
protected ArrayList<String> relationValidationErrors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Counter of rows proccssed in a CSV.
|
||||
*/
|
||||
protected Integer rowCount = 1;
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
@@ -169,7 +193,7 @@ public class MetadataImport {
|
||||
* @param workflowNotify If the workflows should be used, whether to send notifications or not
|
||||
* @param useTemplate Use collection template if create new item
|
||||
* @return An array of BulkEditChange elements representing the items that have changed
|
||||
* @throws MetadataImportException if something goes wrong
|
||||
* @throws MetadataImportException if something goes wrong
|
||||
*/
|
||||
public List<BulkEditChange> runImport(boolean change,
|
||||
boolean useWorkflow,
|
||||
@@ -184,10 +208,10 @@ public class MetadataImport {
|
||||
c.setMode(Context.Mode.BATCH_EDIT);
|
||||
|
||||
// Process each change
|
||||
int rowCount = 1;
|
||||
rowCount = 1;
|
||||
for (DSpaceCSVLine line : toImport) {
|
||||
//Resolve references to other items
|
||||
populateRefAndRowMap(line, rowCount, null);
|
||||
// Resolve target references to other items
|
||||
populateRefAndRowMap(line, line.getID());
|
||||
line = resolveEntityRefs(line);
|
||||
// Get the DSpace item to compare with
|
||||
UUID id = line.getID();
|
||||
@@ -201,7 +225,7 @@ public class MetadataImport {
|
||||
WorkflowItem wfItem = null;
|
||||
Item item = null;
|
||||
|
||||
// Is this a new item?
|
||||
// Is this an existing item?
|
||||
if (id != null) {
|
||||
// Get the item
|
||||
item = itemService.find(c, id);
|
||||
@@ -238,9 +262,8 @@ public class MetadataImport {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compare
|
||||
compare(item, fromCSV, change, md, whatHasChanged, line);
|
||||
compareAndUpdate(item, fromCSV, change, md, whatHasChanged, line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,30 +401,25 @@ public class MetadataImport {
|
||||
item = wsItem.getItem();
|
||||
|
||||
// Add the metadata to the item
|
||||
List<BulkEditMetadataValue> relationships = new LinkedList<>();
|
||||
for (BulkEditMetadataValue dcv : whatHasChanged.getAdds()) {
|
||||
if (!StringUtils.equals(dcv.getSchema(), MetadataSchemaEnum.RELATION.getName())) {
|
||||
itemService.addMetadata(c, item, dcv.getSchema(),
|
||||
dcv.getElement(),
|
||||
dcv.getQualifier(),
|
||||
dcv.getLanguage(),
|
||||
dcv.getValue(),
|
||||
dcv.getAuthority(),
|
||||
dcv.getConfidence());
|
||||
}
|
||||
}
|
||||
//Add relations after all metadata has been processed
|
||||
for (BulkEditMetadataValue dcv : whatHasChanged.getAdds()) {
|
||||
if (StringUtils.equals(dcv.getSchema(), MetadataSchemaEnum.RELATION.getName())) {
|
||||
|
||||
if (!StringUtils.equals(dcv.getElement(), "type")) {
|
||||
relationships.add(dcv);
|
||||
} else {
|
||||
handleRelationshipMetadataValueFromBulkEditMetadataValue(item, dcv);
|
||||
}
|
||||
|
||||
} else {
|
||||
itemService.addMetadata(c, item, dcv.getSchema(),
|
||||
dcv.getElement(),
|
||||
dcv.getQualifier(),
|
||||
dcv.getLanguage(),
|
||||
dcv.getValue(),
|
||||
dcv.getAuthority(),
|
||||
dcv.getConfidence());
|
||||
addRelationship(c, item, dcv.getElement(), dcv.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (BulkEditMetadataValue relationship : relationships) {
|
||||
handleRelationshipMetadataValueFromBulkEditMetadataValue(item, relationship);
|
||||
}
|
||||
|
||||
// Should the workflow be used?
|
||||
if (useWorkflow) {
|
||||
WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService();
|
||||
@@ -424,8 +442,6 @@ public class MetadataImport {
|
||||
}
|
||||
}
|
||||
|
||||
// Commit changes to the object
|
||||
// c.commit();
|
||||
whatHasChanged.setItem(item);
|
||||
}
|
||||
|
||||
@@ -439,7 +455,7 @@ public class MetadataImport {
|
||||
c.uncacheEntity(wfItem);
|
||||
c.uncacheEntity(item);
|
||||
}
|
||||
populateRefAndRowMap(line, rowCount, item == null ? null : item.getID());
|
||||
populateRefAndRowMap(line, item == null ? null : item.getID());
|
||||
// keep track of current rows processed
|
||||
rowCount++;
|
||||
}
|
||||
@@ -452,32 +468,14 @@ public class MetadataImport {
|
||||
}
|
||||
|
||||
// Return the changes
|
||||
if (!change ) {
|
||||
validateExpressedRelations();
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This metod handles the BulkEditMetadataValue objects that correspond to Relationship metadatavalues
|
||||
* @param item The item to which this metadatavalue will belong
|
||||
* @param dcv The BulkEditMetadataValue to be processed
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
private void handleRelationshipMetadataValueFromBulkEditMetadataValue(Item item, BulkEditMetadataValue dcv)
|
||||
throws SQLException, AuthorizeException, MetadataImportException {
|
||||
LinkedList<String> values = new LinkedList<>();
|
||||
values.add(dcv.getValue());
|
||||
LinkedList<String> authorities = new LinkedList<>();
|
||||
authorities.add(dcv.getAuthority());
|
||||
LinkedList<Integer> confidences = new LinkedList<>();
|
||||
confidences.add(dcv.getConfidence());
|
||||
handleRelationMetadata(c, item, dcv.getSchema(), dcv.getElement(),
|
||||
dcv.getQualifier(),
|
||||
dcv.getLanguage(), values, authorities, confidences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare an item metadata with a line from CSV, and optionally update the item
|
||||
* Compare an item metadata with a line from CSV, and optionally update the item.
|
||||
*
|
||||
* @param item The current item metadata
|
||||
* @param fromCSV The metadata from the CSV file
|
||||
@@ -487,9 +485,10 @@ public class MetadataImport {
|
||||
* @param line line in CSV file
|
||||
* @throws SQLException if there is a problem accessing a Collection from the database, from its handle
|
||||
* @throws AuthorizeException if there is an authorization problem with permissions
|
||||
* @throws MetadataImportException custom exception for error handling within metadataimport
|
||||
*/
|
||||
protected void compare(Item item, String[] fromCSV, boolean change,
|
||||
String md, BulkEditChange changes, DSpaceCSVLine line)
|
||||
protected void compareAndUpdate(Item item, String[] fromCSV, boolean change,
|
||||
String md, BulkEditChange changes, DSpaceCSVLine line)
|
||||
throws SQLException, AuthorizeException, MetadataImportException {
|
||||
// Log what metadata element we're looking at
|
||||
String all = "";
|
||||
@@ -663,10 +662,9 @@ public class MetadataImport {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName())) {
|
||||
List<RelationshipType> relationshipTypeList = relationshipTypeService
|
||||
.findByLeftOrRightLabel(c, element);
|
||||
.findByLeftwardOrRightwardTypeName(c, element);
|
||||
for (RelationshipType relationshipType : relationshipTypeList) {
|
||||
for (Relationship relationship : relationshipService
|
||||
.findByItemAndRelationshipType(c, item, relationshipType)) {
|
||||
@@ -674,7 +672,7 @@ public class MetadataImport {
|
||||
relationshipService.update(c, relationship);
|
||||
}
|
||||
}
|
||||
handleRelationMetadata(c, item, schema, element, qualifier, language, values, authorities, confidences);
|
||||
addRelationships(c, item, element, values);
|
||||
} else {
|
||||
itemService.clearMetadata(c, item, schema, element, qualifier, language);
|
||||
itemService.addMetadata(c, item, schema, element, qualifier,
|
||||
@@ -685,47 +683,35 @@ public class MetadataImport {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method decides whether the metadatavalue is of type relation.type or if it corresponds to
|
||||
* a relationship and handles it accordingly to their respective methods
|
||||
*
|
||||
* Adds multiple relationships with a matching typeName to an item.
|
||||
*
|
||||
* @param c The relevant DSpace context
|
||||
* @param item The item to which this metadatavalue belongs to
|
||||
* @param schema The schema for the metadatavalue
|
||||
* @param element The element for the metadatavalue
|
||||
* @param qualifier The qualifier for the metadatavalue
|
||||
* @param language The language for the metadatavalue
|
||||
* @param values The values for the metadatavalue
|
||||
* @param authorities The authorities for the metadatavalue
|
||||
* @param confidences The confidences for the metadatavalue
|
||||
* @param typeName The element for the metadatavalue
|
||||
* @param values to iterate over
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
private void handleRelationMetadata(Context c, Item item, String schema, String element, String qualifier,
|
||||
String language, List<String> values, List<String> authorities,
|
||||
List<Integer> confidences) throws SQLException, AuthorizeException,
|
||||
private void addRelationships(Context c, Item item, String typeName, List<String> values)
|
||||
throws SQLException, AuthorizeException,
|
||||
MetadataImportException {
|
||||
|
||||
if (StringUtils.equals(element, "type") && StringUtils.isBlank(qualifier)) {
|
||||
handleRelationTypeMetadata(c, item, schema, element, qualifier, language, values, authorities, confidences);
|
||||
|
||||
} else {
|
||||
for (String value : values) {
|
||||
handleRelationOtherMetadata(c, item, element, value);
|
||||
}
|
||||
for (String value : values) {
|
||||
addRelationship(c, item, typeName, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an existing entity from a reference.
|
||||
* Gets an existing entity from a target reference.
|
||||
*
|
||||
* @param context the context to use.
|
||||
* @param reference the reference which may be a UUID, metadata reference, or rowName reference.
|
||||
* @param targetReference the target reference which may be a UUID, metadata reference, or rowName reference.
|
||||
* @return the entity, which is guaranteed to exist.
|
||||
* @throws MetadataImportException if the reference is badly formed or refers to a non-existing item.
|
||||
* @throws MetadataImportException if the target reference is badly formed or refers to a non-existing item.
|
||||
*/
|
||||
private Entity getEntity(Context context, String reference) throws MetadataImportException {
|
||||
private Entity getEntity(Context context, String targetReference) throws MetadataImportException {
|
||||
Entity entity = null;
|
||||
UUID uuid = resolveEntityRef(context, reference);
|
||||
UUID uuid = resolveEntityRef(context, targetReference);
|
||||
// At this point, we have a uuid, so we can get an entity
|
||||
try {
|
||||
entity = entityService.findByItemId(context, uuid);
|
||||
@@ -734,205 +720,73 @@ public class MetadataImport {
|
||||
}
|
||||
return entity;
|
||||
} catch (SQLException sqle) {
|
||||
throw new MetadataImportException("Unable to find entity using reference: " + reference, sqle);
|
||||
throw new MetadataImportException("Unable to find entity using reference: " + targetReference, sqle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes the item, element and values to determine what relationships should be built
|
||||
* for these parameters and calls on the method to construct them
|
||||
*
|
||||
* Creates a relationship for the given item
|
||||
*
|
||||
* @param c The relevant DSpace context
|
||||
* @param item The item that the relationships will be made for
|
||||
* @param element The string determining which relationshiptype is to be used
|
||||
* @param typeName The relationship typeName
|
||||
* @param value The value for the relationship
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
private void handleRelationOtherMetadata(Context c, Item item, String element, String value)
|
||||
private void addRelationship(Context c, Item item, String typeName, String value)
|
||||
throws SQLException, AuthorizeException, MetadataImportException {
|
||||
if (value.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Entity entity = entityService.findByItemId(c, item.getID());
|
||||
boolean left = false;
|
||||
List<RelationshipType> acceptableRelationshipTypes = new LinkedList<>();
|
||||
|
||||
// Get entity from target reference
|
||||
Entity relationEntity = getEntity(c, value);
|
||||
// Get relationship type of entity and item
|
||||
String relationEntityRelationshipType = itemService.getMetadata(relationEntity.getItem(),
|
||||
"relationship", "type",
|
||||
null, Item.ANY).get(0).getValue();
|
||||
String itemRelationshipType = itemService.getMetadata(item, "relationship", "type",
|
||||
null, Item.ANY).get(0).getValue();
|
||||
|
||||
List<RelationshipType> leftRelationshipTypesForEntity = entityService.getLeftRelationshipTypes(c, entity);
|
||||
List<RelationshipType> rightRelationshipTypesForEntity = entityService.getRightRelationshipTypes(c, entity);
|
||||
// Get the correct RelationshipType based on typeName
|
||||
List<RelationshipType> relType = relationshipTypeService.findByLeftwardOrRightwardTypeName(c, typeName);
|
||||
RelationshipType foundRelationshipType = matchRelationshipType(relType,
|
||||
relationEntityRelationshipType, itemRelationshipType, typeName);
|
||||
|
||||
for (RelationshipType relationshipType : entityService.getAllRelationshipTypes(c, entity)) {
|
||||
if (StringUtils.equalsIgnoreCase(relationshipType.getLeftLabel(), element)) {
|
||||
left = handleLeftLabelEqualityRelationshipTypeElement(c, entity, relationEntity, left,
|
||||
acceptableRelationshipTypes,
|
||||
leftRelationshipTypesForEntity,
|
||||
relationshipType);
|
||||
} else if (StringUtils.equalsIgnoreCase(relationshipType.getRightLabel(), element)) {
|
||||
left = handleRightLabelEqualityRelationshipTypeElement(c, entity, relationEntity, left,
|
||||
acceptableRelationshipTypes,
|
||||
rightRelationshipTypesForEntity,
|
||||
relationshipType);
|
||||
}
|
||||
if (foundRelationshipType == null) {
|
||||
throw new MetadataImportException("Error on CSV row " + rowCount + ":" + "\n" +
|
||||
"No Relationship type found for:\n" +
|
||||
"Target type: " + relationEntityRelationshipType + "\n" +
|
||||
"Origin referer type: " + itemRelationshipType + "\n" +
|
||||
"with typeName: " + typeName);
|
||||
}
|
||||
|
||||
if (acceptableRelationshipTypes.size() > 1) {
|
||||
log.error("Ambiguous relationship_types were found");
|
||||
return;
|
||||
}
|
||||
if (acceptableRelationshipTypes.size() == 0) {
|
||||
log.error("no relationship_types were found");
|
||||
return;
|
||||
if (foundRelationshipType.getLeftwardType().equalsIgnoreCase(typeName)) {
|
||||
left = true;
|
||||
}
|
||||
|
||||
//There is exactly one
|
||||
buildRelationObject(c, item, relationEntity.getItem(), left, acceptableRelationshipTypes.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates the relationship for the item and stores it in the database
|
||||
* @param c The relevant DSpace context
|
||||
* @param item The item for which this relationship will be constructed
|
||||
* @param otherItem The item for the relationship
|
||||
* @param left A boolean indicating whether the item is the leftItem or the rightItem
|
||||
* @param acceptedRelationshipType The acceptable relationship type
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
private void buildRelationObject(Context c, Item item, Item otherItem, boolean left,
|
||||
RelationshipType acceptedRelationshipType)
|
||||
throws SQLException, AuthorizeException {
|
||||
// Placeholder items for relation placing
|
||||
Item leftItem = null;
|
||||
Item rightItem = null;
|
||||
if (left) {
|
||||
leftItem = item;
|
||||
rightItem = otherItem;
|
||||
rightItem = relationEntity.getItem();
|
||||
} else {
|
||||
leftItem = relationEntity.getItem();
|
||||
rightItem = item;
|
||||
leftItem = otherItem;
|
||||
}
|
||||
RelationshipType relationshipType = acceptedRelationshipType;
|
||||
int leftPlace = relationshipService.findLeftPlaceByLeftItem(c, leftItem) + 1;
|
||||
int rightPlace = relationshipService.findRightPlaceByRightItem(c, rightItem) + 1;
|
||||
|
||||
// Create the relationship
|
||||
int leftPlace = relationshipService.findNextLeftPlaceByLeftItem(c, leftItem);
|
||||
int rightPlace = relationshipService.findNextRightPlaceByRightItem(c, rightItem);
|
||||
Relationship persistedRelationship = relationshipService.create(c, leftItem, rightItem,
|
||||
relationshipType, leftPlace, rightPlace);
|
||||
foundRelationshipType, leftPlace, rightPlace);
|
||||
relationshipService.update(c, persistedRelationship);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will add RelationshipType objects to the acceptableRelationshipTypes list
|
||||
* if applicable and valid RelationshipType objects are found. It will also return a boolean indicating
|
||||
* whether we're dealing with a left Relationship or not
|
||||
* @param c The relevant DSpace context
|
||||
* @param entity The Entity for which the RelationshipType has to be checked
|
||||
* @param relationEntity The other Entity of the Relationship
|
||||
* @param left Boolean indicating whether the Relationship is left or not
|
||||
* @param acceptableRelationshipTypes The list of RelationshipType objects that will be added to
|
||||
* @param rightRelationshipTypesForEntity The list of RelationshipType objects that are possible
|
||||
* for the right entity
|
||||
* @param relationshipType The RelationshipType object that we want to check whether it's
|
||||
* valid to be added or not
|
||||
* @return A boolean indicating whether the relationship is left or right, will
|
||||
* be false in this case
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
private boolean handleRightLabelEqualityRelationshipTypeElement(Context c, Entity entity, Entity relationEntity,
|
||||
boolean left,
|
||||
List<RelationshipType> acceptableRelationshipTypes,
|
||||
List<RelationshipType>
|
||||
rightRelationshipTypesForEntity,
|
||||
RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
||||
relationshipType.getRightType().getLabel()) &&
|
||||
StringUtils.equalsIgnoreCase(entityService.getType(c, relationEntity).getLabel(),
|
||||
relationshipType.getLeftType().getLabel())) {
|
||||
|
||||
for (RelationshipType rightRelationshipType : rightRelationshipTypesForEntity) {
|
||||
if (StringUtils.equalsIgnoreCase(rightRelationshipType.getLeftType().getLabel(),
|
||||
relationshipType.getLeftType().getLabel()) ||
|
||||
StringUtils.equalsIgnoreCase(rightRelationshipType.getRightType().getLabel(),
|
||||
relationshipType.getLeftType().getLabel())) {
|
||||
left = false;
|
||||
acceptableRelationshipTypes.add(relationshipType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will add RelationshipType objects to the acceptableRelationshipTypes list
|
||||
* if applicable and valid RelationshipType objects are found. It will also return a boolean indicating
|
||||
* whether we're dealing with a left Relationship or not
|
||||
* @param c The relevant DSpace context
|
||||
* @param entity The Entity for which the RelationshipType has to be checked
|
||||
* @param relationEntity The other Entity of the Relationship
|
||||
* @param left Boolean indicating whether the Relationship is left or not
|
||||
* @param acceptableRelationshipTypes The list of RelationshipType objects that will be added to
|
||||
* @param leftRelationshipTypesForEntity The list of RelationshipType objects that are possible
|
||||
* for the left entity
|
||||
* @param relationshipType The RelationshipType object that we want to check whether it's
|
||||
* valid to be added or not
|
||||
* @return A boolean indicating whether the relationship is left or right, will
|
||||
* be true in this case
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
private boolean handleLeftLabelEqualityRelationshipTypeElement(Context c, Entity entity, Entity relationEntity,
|
||||
boolean left,
|
||||
List<RelationshipType> acceptableRelationshipTypes,
|
||||
List<RelationshipType>
|
||||
leftRelationshipTypesForEntity,
|
||||
RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
if (StringUtils.equalsIgnoreCase(entityService.getType(c, entity).getLabel(),
|
||||
relationshipType.getLeftType().getLabel()) &&
|
||||
StringUtils.equalsIgnoreCase(entityService.getType(c, relationEntity).getLabel(),
|
||||
relationshipType.getRightType().getLabel())) {
|
||||
for (RelationshipType leftRelationshipType : leftRelationshipTypesForEntity) {
|
||||
if (StringUtils.equalsIgnoreCase(leftRelationshipType.getRightType().getLabel(),
|
||||
relationshipType.getRightType().getLabel()) ||
|
||||
StringUtils.equalsIgnoreCase(leftRelationshipType.getLeftType().getLabel(),
|
||||
relationshipType.getRightType().getLabel())) {
|
||||
left = true;
|
||||
acceptableRelationshipTypes.add(relationshipType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will add the relationship.type metadata to the item if an EntityType can be found for the value in
|
||||
* the values list.
|
||||
* @param c The relevant DSpace context
|
||||
* @param item The item to which this metadatavalue will be added
|
||||
* @param schema The schema for the metadatavalue to be added
|
||||
* @param element The element for the metadatavalue to be added
|
||||
* @param qualifier The qualifier for the metadatavalue to be added
|
||||
* @param language The language for the metadatavalue to be added
|
||||
* @param values The value on which we'll search for EntityType object and it's the value
|
||||
* for the metadatavalue that will be created
|
||||
* @param authorities The authority for the metadatavalue. This will be filled with the ID
|
||||
* of the found EntityType for the value if it exists
|
||||
* @param confidences The confidence for the metadatavalue
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
private void handleRelationTypeMetadata(Context c, Item item, String schema, String element, String qualifier,
|
||||
String language, List<String> values, List<String> authorities,
|
||||
List<Integer> confidences)
|
||||
throws SQLException, AuthorizeException {
|
||||
EntityType entityType = entityTypeService.findByEntityType(c, values.get(0));
|
||||
if (entityType != null) {
|
||||
authorities.add(String.valueOf(entityType.getID()));
|
||||
itemService.clearMetadata(c, item, schema, element, qualifier, language);
|
||||
itemService.addMetadata(c, item, schema, element, qualifier, language,
|
||||
values, authorities, confidences);
|
||||
itemService.update(c, item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare changes between an items owning collection and mapped collections
|
||||
* and what is in the CSV file
|
||||
@@ -1573,9 +1427,6 @@ public class MetadataImport {
|
||||
|
||||
// Display the changes
|
||||
displayChanges(changes, true);
|
||||
|
||||
// Commit the change to the DB
|
||||
// c.commit();
|
||||
}
|
||||
|
||||
// Finsh off and tidy up
|
||||
@@ -1590,24 +1441,28 @@ public class MetadataImport {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a copy of the given csv line with all entity references resolved to UUID strings.
|
||||
* Gets a copy of the given csv line with all entity target references resolved to UUID strings.
|
||||
* Keys being iterated over represent metadatafields or special columns to be processed.
|
||||
*
|
||||
* @param line the csv line to process.
|
||||
* @return a copy, with all references resolved.
|
||||
* @throws MetadataImportException if there is an error resolving any entity reference.
|
||||
* @throws MetadataImportException if there is an error resolving any entity target reference.
|
||||
*/
|
||||
public DSpaceCSVLine resolveEntityRefs(DSpaceCSVLine line) throws MetadataImportException {
|
||||
DSpaceCSVLine newLine = new DSpaceCSVLine(line.getID());
|
||||
UUID originId = evaluateOriginId(line.getID());
|
||||
for (String key : line.keys()) {
|
||||
// If a key represents a relation field attempt to resolve the reference from the csvRefMap
|
||||
// If a key represents a relation field attempt to resolve the target reference from the csvRefMap
|
||||
if (key.split("\\.")[0].equalsIgnoreCase("relation")) {
|
||||
if (line.get(key).size() > 0) {
|
||||
for (String val : line.get(key)) {
|
||||
// Attempt to resolve the relation reference
|
||||
// These can be a UUID, metadata reference or rowName reference
|
||||
// Attempt to resolve the relation target reference
|
||||
// These can be a UUID, metadata target reference or rowName target reference
|
||||
String uuid = resolveEntityRef(c, val).toString();
|
||||
newLine.add(key, uuid);
|
||||
//Entity refs have been resolved / placeholdered
|
||||
//Populate the EntityRelationMap
|
||||
populateEntityRelationMap(uuid, key, originId.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1622,27 +1477,59 @@ public class MetadataImport {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the csvRefMap and csvRowMap for the given csv line.
|
||||
* Populate the entityRelationMap with all target references and it's asscoiated typeNames
|
||||
* to their respective origins
|
||||
*
|
||||
* @param refUUID the target reference UUID for the relation
|
||||
* @param relationField the field of the typeNames to relate from
|
||||
*/
|
||||
private void populateEntityRelationMap(String refUUID, String relationField, String originId) {
|
||||
HashMap<String, ArrayList<String>> typeNames = null;
|
||||
if (entityRelationMap.get(refUUID) == null) {
|
||||
typeNames = new HashMap<>();
|
||||
ArrayList<String> originIds = new ArrayList<>();
|
||||
originIds.add(originId);
|
||||
typeNames.put(relationField, originIds);
|
||||
entityRelationMap.put(refUUID, typeNames);
|
||||
} else {
|
||||
typeNames = entityRelationMap.get(refUUID);
|
||||
if (typeNames.get(relationField) == null) {
|
||||
ArrayList<String> originIds = new ArrayList<>();
|
||||
originIds.add(originId);
|
||||
typeNames.put(relationField, originIds);
|
||||
} else {
|
||||
ArrayList<String> originIds = typeNames.get(relationField);
|
||||
originIds.add(originId);
|
||||
typeNames.put(relationField, originIds);
|
||||
}
|
||||
entityRelationMap.put(refUUID, typeNames);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the csvRefMap, csvRowMap, and entityTypeMap for the given csv line.
|
||||
*
|
||||
* The csvRefMap is an index that keeps track of which rows have a specific value for
|
||||
* a specific metadata field or the special "rowName" column. This is used to help resolve indirect
|
||||
* entity references in the same CSV.
|
||||
* entity target references in the same CSV.
|
||||
*
|
||||
* The csvRowMap is a row number to UUID map, and contains an entry for every row that has
|
||||
* been processed so far which has a known (minted) UUID for its item. This is used to help complete
|
||||
* the resolution after the row number has been determined.
|
||||
*
|
||||
* @param line the csv line.
|
||||
* @param rowNumber the row number.
|
||||
* @param uuid the uuid of the item, which may be null if it has not been minted yet.
|
||||
*/
|
||||
private void populateRefAndRowMap(DSpaceCSVLine line, int rowNumber, @Nullable UUID uuid) {
|
||||
private void populateRefAndRowMap(DSpaceCSVLine line, @Nullable UUID uuid) {
|
||||
if (uuid != null) {
|
||||
csvRowMap.put(rowNumber, uuid);
|
||||
csvRowMap.put(rowCount, uuid);
|
||||
} else {
|
||||
csvRowMap.put(rowCount, new UUID(0, rowCount));
|
||||
}
|
||||
for (String key : line.keys()) {
|
||||
if (key.contains(".") && !key.split("\\.")[0].equalsIgnoreCase("relation") ||
|
||||
@@ -1654,22 +1541,31 @@ public class MetadataImport {
|
||||
rowNums = new HashSet<>();
|
||||
csvRefMap.put(valueKey, rowNums);
|
||||
}
|
||||
rowNums.add(rowNumber);
|
||||
rowNums.add(rowCount);
|
||||
}
|
||||
}
|
||||
//Populate entityTypeMap
|
||||
if (key.equalsIgnoreCase("relationship.type") && line.get(key).size() > 0) {
|
||||
if (uuid == null) {
|
||||
entityTypeMap.put(new UUID(0, rowCount), line.get(key).get(0));
|
||||
} else {
|
||||
entityTypeMap.put(uuid, line.get(key).get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the UUID of the item indicated by the given reference, which may be a direct UUID string, a row reference
|
||||
* Gets the UUID of the item indicated by the given target reference,
|
||||
* which may be a direct UUID string, a row reference
|
||||
* of the form rowName:VALUE, or a metadata value reference of the form schema.element[.qualifier]:VALUE.
|
||||
*
|
||||
* The reference may refer to a previously-processed item in the CSV or an item in the database.
|
||||
*
|
||||
* @param context the context to use.
|
||||
* @param reference the reference which may be a UUID, metadata reference, or rowName reference.
|
||||
* @param reference the target reference which may be a UUID, metadata reference, or rowName reference.
|
||||
* @return the uuid.
|
||||
* @throws MetadataImportException if the reference is malformed or ambiguous (refers to multiple items).
|
||||
* @throws MetadataImportException if the target reference is malformed or ambiguous (refers to multiple items).
|
||||
*/
|
||||
private UUID resolveEntityRef(Context context, String reference) throws MetadataImportException {
|
||||
// value reference
|
||||
@@ -1679,7 +1575,8 @@ public class MetadataImport {
|
||||
try {
|
||||
return UUID.fromString(reference);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new MetadataImportException("Not a UUID or indirect entity reference: '" + reference + "'");
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Not a UUID or indirect entity reference: '" + reference + "'");
|
||||
}
|
||||
} else if (!reference.startsWith("rowName:") ) { // Not a rowName ref; so it's a metadata value reference
|
||||
MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
||||
@@ -1689,7 +1586,8 @@ public class MetadataImport {
|
||||
String mfValue = reference.substring(i + 1);
|
||||
String mf[] = reference.substring(0, i).split("\\.");
|
||||
if (mf.length < 2) {
|
||||
throw new MetadataImportException("Bad metadata field in reference: '" + reference
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Bad metadata field in reference: '" + reference
|
||||
+ "' (expected syntax is schema.element[.qualifier])");
|
||||
}
|
||||
String schema = mf[0];
|
||||
@@ -1702,11 +1600,13 @@ public class MetadataImport {
|
||||
MetadataValue mdvVal = mdv.next();
|
||||
uuid = mdvVal.getDSpaceObject().getID();
|
||||
if (mdv.hasNext()) {
|
||||
throw new MetadataImportException("Ambiguous reference; multiple matches in db: " + reference);
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Ambiguous reference; multiple matches in db: " + reference);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new MetadataImportException("Error looking up item by metadata reference: " + reference, e);
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Error looking up item by metadata reference: " + reference, e);
|
||||
}
|
||||
}
|
||||
// Lookup UUIDs that may have already been processed into the csvRefMap
|
||||
@@ -1714,20 +1614,23 @@ public class MetadataImport {
|
||||
// See getMatchingCSVUUIDs() for how the reference param is sourced from the csvRefMap
|
||||
Set<UUID> csvUUIDs = getMatchingCSVUUIDs(reference);
|
||||
if (csvUUIDs.size() > 1) {
|
||||
throw new MetadataImportException("Ambiguous reference; multiple matches in csv: " + reference);
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Ambiguous reference; multiple matches in csv: " + reference);
|
||||
} else if (csvUUIDs.size() == 1) {
|
||||
UUID csvUUID = csvUUIDs.iterator().next();
|
||||
if (csvUUID.equals(uuid)) {
|
||||
return uuid; // one match from csv and db (same item)
|
||||
} else if (uuid != null) {
|
||||
throw new MetadataImportException("Ambiguous reference; multiple matches in db and csv: " + reference);
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"Ambiguous reference; multiple matches in db and csv: " + reference);
|
||||
} else {
|
||||
return csvUUID; // one match from csv
|
||||
}
|
||||
} else { // size == 0; the reference does not exist throw an error
|
||||
if (uuid == null) {
|
||||
throw new MetadataImportException("No matches found for reference: " + reference
|
||||
+ ", Keep in mind you can only reference entries that are listed before " +
|
||||
throw new MetadataImportException("Error in CSV row " + rowCount + ":\n" +
|
||||
"No matches found for reference: " + reference
|
||||
+ "\nKeep in mind you can only reference entries that are listed before " +
|
||||
"this one within the CSV.");
|
||||
} else {
|
||||
return uuid; // one match from db
|
||||
@@ -1767,4 +1670,187 @@ public class MetadataImport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a UUID of the origin in process or a placeholder for the origin to be evaluated later
|
||||
*
|
||||
* @param originId UUID of the origin
|
||||
* @return the UUID of the item or UUID placeholder
|
||||
*/
|
||||
private UUID evaluateOriginId(@Nullable UUID originId) {
|
||||
if (originId != null) {
|
||||
return originId;
|
||||
} else {
|
||||
return new UUID(0, rowCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate every relation modification expressed in the CSV.
|
||||
*
|
||||
*/
|
||||
private void validateExpressedRelations() throws MetadataImportException {
|
||||
for (String targetUUID : entityRelationMap.keySet()) {
|
||||
String targetType = null;
|
||||
try {
|
||||
// Get the type of reference. Attempt lookup in processed map first before looking in archive.
|
||||
if (entityTypeMap.get(UUID.fromString(targetUUID)) != null) {
|
||||
targetType = entityTypeService.
|
||||
findByEntityType(c, entityTypeMap.get(UUID.fromString(targetUUID))).getLabel();
|
||||
} else {
|
||||
// Target item may be archived; check there.
|
||||
// Add to errors if Realtionship.type cannot be derived
|
||||
Item targetItem = null;
|
||||
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
|
||||
targetItem = itemService.find(c, UUID.fromString(targetUUID));
|
||||
List<MetadataValue> relTypes = itemService.
|
||||
getMetadata(targetItem, "relationship", "type", null, Item.ANY);
|
||||
String relTypeValue = null;
|
||||
if (relTypes.size() > 0) {
|
||||
relTypeValue = relTypes.get(0).getValue();
|
||||
targetType = entityTypeService.findByEntityType(c, relTypeValue).getLabel();
|
||||
} else {
|
||||
relationValidationErrors.add("Cannot resolve Entity type for target UUID: " +
|
||||
targetUUID);
|
||||
}
|
||||
} else {
|
||||
relationValidationErrors.add("Cannot resolve Entity type for target UUID: " +
|
||||
targetUUID);
|
||||
}
|
||||
}
|
||||
if (targetType == null) {
|
||||
continue;
|
||||
}
|
||||
// Get typeNames for each origin referer of this target.
|
||||
for (String typeName : entityRelationMap.get(targetUUID).keySet()) {
|
||||
// Resolve Entity Type for each origin referer.
|
||||
for (String originRefererUUID : entityRelationMap.get(targetUUID).get(typeName)) {
|
||||
// Evaluate row number for origin referer.
|
||||
String originRow = "N/A";
|
||||
if (csvRowMap.containsValue(UUID.fromString(originRefererUUID))) {
|
||||
for (int key : csvRowMap.keySet()) {
|
||||
if (csvRowMap.get(key).toString().equalsIgnoreCase(originRefererUUID)) {
|
||||
originRow = key + "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String originType = "";
|
||||
// Validate target type and origin type pairing with typeName or add to errors.
|
||||
// Attempt lookup in processed map first before looking in archive.
|
||||
if (entityTypeMap.get(UUID.fromString(originRefererUUID)) != null) {
|
||||
originType = entityTypeMap.get(UUID.fromString(originRefererUUID));
|
||||
validateTypesByTypeByTypeName(targetType, originType, typeName, originRow);
|
||||
} else {
|
||||
// Origin item may be archived; check there.
|
||||
// Add to errors if Realtionship.type cannot be derived.
|
||||
Item originItem = null;
|
||||
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
|
||||
originItem = itemService.find(c, UUID.fromString(originRefererUUID));
|
||||
List<MetadataValue> relTypes = itemService.
|
||||
getMetadata(originItem, "relationship", "type", null, Item.ANY);
|
||||
String relTypeValue = null;
|
||||
if (relTypes.size() > 0) {
|
||||
relTypeValue = relTypes.get(0).getValue();
|
||||
originType = entityTypeService.findByEntityType(c, relTypeValue).getLabel();
|
||||
validateTypesByTypeByTypeName(targetType, originType, typeName, originRow);
|
||||
} else {
|
||||
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||
"Cannot resolve Entity type for reference: "
|
||||
+ originRefererUUID);
|
||||
}
|
||||
|
||||
} else {
|
||||
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||
"Cannot resolve Entity type for reference: "
|
||||
+ originRefererUUID + " in row: " + originRow );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException sqle) {
|
||||
throw new MetadataImportException("Error interacting with database!", sqle);
|
||||
}
|
||||
|
||||
} // If relationValidationErrors is empty all described relationships are valid.
|
||||
if (!relationValidationErrors.isEmpty()) {
|
||||
StringBuilder errors = new StringBuilder();
|
||||
for (String error : relationValidationErrors) {
|
||||
errors.append(error + "\n");
|
||||
}
|
||||
throw new MetadataImportException("Error validating relationships: \n" + errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of potenital Relationship Types given a typeName and attempts to match the given
|
||||
* targetType and originType to a Relationship Type in the list.
|
||||
*
|
||||
* @param targetType entity type of target.
|
||||
* @param originType entity type of origin referer.
|
||||
* @param typeName left or right typeName of the respective Relationship.
|
||||
* @return the UUID of the item.
|
||||
*/
|
||||
private void validateTypesByTypeByTypeName(String targetType, String originType, String typeName, String originRow)
|
||||
throws MetadataImportException {
|
||||
try {
|
||||
RelationshipType foundRelationshipType = null;
|
||||
List<RelationshipType> relationshipTypeList = relationshipTypeService.
|
||||
findByLeftwardOrRightwardTypeName(c, typeName.split("\\.")[1]);
|
||||
// Validate described relationship form the CSV.
|
||||
foundRelationshipType = matchRelationshipType(relationshipTypeList, targetType, originType, typeName);
|
||||
if (foundRelationshipType == null) {
|
||||
relationValidationErrors.add("Error on CSV row " + originRow + ":" + "\n" +
|
||||
"No Relationship type found for:\n" +
|
||||
"Target type: " + targetType + "\n" +
|
||||
"Origin referer type: " + originType + "\n" +
|
||||
"with typeName: " + typeName + " for type: " + originType);
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
throw new MetadataImportException("Error interacting with database!", sqle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches two Entity types to a Relationship Type from a set of Relationship Types.
|
||||
*
|
||||
* @param relTypes set of Relationship Types.
|
||||
* @param targetType entity type of target.
|
||||
* @param originType entity type of origin referer.
|
||||
* @return null or matched Relationship Type.
|
||||
*/
|
||||
private RelationshipType matchRelationshipType(List<RelationshipType> relTypes,
|
||||
String targetType, String originType, String originTypeName) {
|
||||
RelationshipType foundRelationshipType = null;
|
||||
if (originTypeName.split("\\.").length > 1) {
|
||||
originTypeName = originTypeName.split("\\.")[1];
|
||||
}
|
||||
for (RelationshipType relationshipType : relTypes) {
|
||||
// Is origin type leftward or righward
|
||||
boolean isLeft = false;
|
||||
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(originType)) {
|
||||
isLeft = true;
|
||||
}
|
||||
if (isLeft) {
|
||||
// Validate typeName reference
|
||||
if (!relationshipType.getLeftwardType().equalsIgnoreCase(originTypeName)) {
|
||||
continue;
|
||||
}
|
||||
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(originType) &&
|
||||
relationshipType.getRightType().getLabel().equalsIgnoreCase(targetType)) {
|
||||
foundRelationshipType = relationshipType;
|
||||
}
|
||||
} else {
|
||||
if (!relationshipType.getRightwardType().equalsIgnoreCase(originTypeName)) {
|
||||
continue;
|
||||
}
|
||||
if (relationshipType.getLeftType().getLabel().equalsIgnoreCase(targetType) &&
|
||||
relationshipType.getRightType().getLabel().equalsIgnoreCase(originType)) {
|
||||
foundRelationshipType = relationshipType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundRelationshipType;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -272,9 +272,8 @@ public class Harvest {
|
||||
targetCollection = (Collection) dso;
|
||||
}
|
||||
} else {
|
||||
// not a handle, try and treat it as an integer collection database ID
|
||||
System.out.println("Looking up by id: " + collectionID + ", parsed as '" + Integer
|
||||
.parseInt(collectionID) + "', " + "in context: " + context);
|
||||
// not a handle, try and treat it as an collection database UUID
|
||||
System.out.println("Looking up by UUID: " + collectionID + ", " + "in context: " + context);
|
||||
targetCollection = collectionService.find(context, UUID.fromString(collectionID));
|
||||
}
|
||||
}
|
||||
@@ -460,7 +459,7 @@ public class Harvest {
|
||||
List<String> errors;
|
||||
|
||||
System.out.print("Testing basic PMH access: ");
|
||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
||||
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||
(null != metadataFormat) ? metadataFormat : "dc", false);
|
||||
if (errors.isEmpty()) {
|
||||
System.out.println("OK");
|
||||
@@ -471,7 +470,7 @@ public class Harvest {
|
||||
}
|
||||
|
||||
System.out.print("Testing ORE support: ");
|
||||
errors = OAIHarvester.verifyOAIharvester(server, set,
|
||||
errors = harvestedCollectionService.verifyOAIharvester(server, set,
|
||||
(null != metadataFormat) ? metadataFormat : "dc", true);
|
||||
if (errors.isEmpty()) {
|
||||
System.out.println("OK");
|
||||
|
@@ -13,6 +13,12 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||
import org.dspace.services.RequestService;
|
||||
@@ -27,6 +33,9 @@ import org.jdom.input.SAXBuilder;
|
||||
* @author Mark Diggory
|
||||
*/
|
||||
public class ScriptLauncher {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ScriptLauncher.class);
|
||||
|
||||
/**
|
||||
* The service manager kernel
|
||||
*/
|
||||
@@ -76,8 +85,9 @@ public class ScriptLauncher {
|
||||
}
|
||||
|
||||
// Look up command in the configuration, and execute.
|
||||
int status;
|
||||
status = runOneCommand(commandConfigs, args);
|
||||
|
||||
CommandLineDSpaceRunnableHandler commandLineDSpaceRunnableHandler = new CommandLineDSpaceRunnableHandler();
|
||||
int status = handleScript(args, commandConfigs, commandLineDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
// Destroy the service kernel if it is still alive
|
||||
if (kernelImpl != null) {
|
||||
@@ -86,6 +96,50 @@ public class ScriptLauncher {
|
||||
}
|
||||
|
||||
System.exit(status);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will take the arguments from a commandline input and it'll find the script that the first argument
|
||||
* refers to and it'll execute this script.
|
||||
* It can return a 1 or a 0 depending on whether the script failed or passed respectively
|
||||
* @param args The arguments for the script and the script as first one in the array
|
||||
* @param commandConfigs The Document
|
||||
* @param dSpaceRunnableHandler The DSpaceRunnableHandler for this execution
|
||||
* @param kernelImpl The relevant DSpaceKernelImpl
|
||||
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||
*/
|
||||
public static int handleScript(String[] args, Document commandConfigs,
|
||||
DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||
DSpaceKernelImpl kernelImpl) {
|
||||
int status;
|
||||
DSpaceRunnable script = ScriptServiceFactory.getInstance().getScriptService().getScriptForName(args[0]);
|
||||
if (script != null) {
|
||||
status = executeScript(args, dSpaceRunnableHandler, script);
|
||||
} else {
|
||||
status = runOneCommand(commandConfigs, args, kernelImpl);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will simply execute the script
|
||||
* @param args The arguments of the script with the script name as first place in the array
|
||||
* @param dSpaceRunnableHandler The relevant DSpaceRunnableHandler
|
||||
* @param script The script to be executed
|
||||
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||
*/
|
||||
private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||
DSpaceRunnable script) {
|
||||
try {
|
||||
script.initialize(args, dSpaceRunnableHandler);
|
||||
script.run();
|
||||
return 0;
|
||||
} catch (ParseException e) {
|
||||
script.printHelp();
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected static int runOneCommand(Document commandConfigs, String[] args) {
|
||||
@@ -98,7 +152,7 @@ public class ScriptLauncher {
|
||||
* @param commandConfigs Document
|
||||
* @param args the command line arguments given
|
||||
*/
|
||||
public static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) {
|
||||
protected static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) {
|
||||
String request = args[0];
|
||||
Element root = commandConfigs.getRootElement();
|
||||
List<Element> commands = root.getChildren("command");
|
||||
|
@@ -89,6 +89,11 @@ public class DCInput {
|
||||
*/
|
||||
private boolean repeatable = false;
|
||||
|
||||
/**
|
||||
* should name-variants be used?
|
||||
*/
|
||||
private boolean nameVariants = false;
|
||||
|
||||
/**
|
||||
* 'hint' text to display
|
||||
*/
|
||||
@@ -183,6 +188,9 @@ public class DCInput {
|
||||
String repStr = fieldMap.get("repeatable");
|
||||
repeatable = "true".equalsIgnoreCase(repStr)
|
||||
|| "yes".equalsIgnoreCase(repStr);
|
||||
String nameVariantsString = fieldMap.get("name-variants");
|
||||
nameVariants = (StringUtils.isNotBlank(nameVariantsString)) ?
|
||||
nameVariantsString.equalsIgnoreCase("true") : false;
|
||||
label = fieldMap.get("label");
|
||||
inputType = fieldMap.get("input-type");
|
||||
// these types are list-controlled
|
||||
@@ -269,6 +277,15 @@ public class DCInput {
|
||||
return isRepeatable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nameVariants flag for this row
|
||||
*
|
||||
* @return the nameVariants flag
|
||||
*/
|
||||
public boolean areNameVariantsAllowed() {
|
||||
return nameVariants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input type for this row
|
||||
*
|
||||
|
@@ -128,8 +128,8 @@ public class InitializeEntities {
|
||||
|
||||
String leftType = eElement.getElementsByTagName("leftType").item(0).getTextContent();
|
||||
String rightType = eElement.getElementsByTagName("rightType").item(0).getTextContent();
|
||||
String leftLabel = eElement.getElementsByTagName("leftLabel").item(0).getTextContent();
|
||||
String rightLabel = eElement.getElementsByTagName("rightLabel").item(0).getTextContent();
|
||||
String leftwardType = eElement.getElementsByTagName("leftwardType").item(0).getTextContent();
|
||||
String rightwardType = eElement.getElementsByTagName("rightwardType").item(0).getTextContent();
|
||||
|
||||
|
||||
NodeList leftCardinalityList = eElement.getElementsByTagName("leftCardinality");
|
||||
@@ -154,7 +154,7 @@ public class InitializeEntities {
|
||||
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
||||
|
||||
}
|
||||
populateRelationshipType(context, leftType, rightType, leftLabel, rightLabel,
|
||||
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
||||
leftCardinalityMin, leftCardinalityMax,
|
||||
rightCardinalityMin, rightCardinalityMax);
|
||||
|
||||
@@ -173,8 +173,8 @@ public class InitializeEntities {
|
||||
return leftCardinalityMin;
|
||||
}
|
||||
|
||||
private void populateRelationshipType(Context context, String leftType, String rightType, String leftLabel,
|
||||
String rightLabel, String leftCardinalityMin, String leftCardinalityMax,
|
||||
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
||||
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||
String rightCardinalityMin, String rightCardinalityMax)
|
||||
throws SQLException, AuthorizeException {
|
||||
|
||||
@@ -211,9 +211,9 @@ public class InitializeEntities {
|
||||
rightCardinalityMaxInteger = null;
|
||||
}
|
||||
RelationshipType relationshipType = relationshipTypeService
|
||||
.findbyTypesAndLabels(context, leftEntityType, rightEntityType, leftLabel, rightLabel);
|
||||
.findbyTypesAndTypeName(context, leftEntityType, rightEntityType, leftwardType, rightwardType);
|
||||
if (relationshipType == null) {
|
||||
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftLabel, rightLabel,
|
||||
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftwardType, rightwardType,
|
||||
leftCardinalityMinInteger, leftCardinalityMaxInteger,
|
||||
rightCardinalityMinInteger, rightCardinalityMaxInteger);
|
||||
} else {
|
||||
|
@@ -13,6 +13,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrClient;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
@@ -39,9 +40,9 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
||||
/**
|
||||
* Non-Static CommonsHttpSolrServer for processing indexing events.
|
||||
*/
|
||||
protected HttpSolrClient solr = null;
|
||||
protected SolrClient solr = null;
|
||||
|
||||
protected HttpSolrClient getSolr()
|
||||
protected SolrClient getSolr()
|
||||
throws MalformedURLException, SolrServerException, IOException {
|
||||
if (solr == null) {
|
||||
|
||||
@@ -49,12 +50,14 @@ public class AuthoritySolrServiceImpl implements AuthorityIndexingService, Autho
|
||||
|
||||
log.debug("Solr authority URL: " + solrService);
|
||||
|
||||
solr = new HttpSolrClient.Builder(solrService).build();
|
||||
solr.setBaseURL(solrService);
|
||||
HttpSolrClient solrServer = new HttpSolrClient.Builder(solrService).build();
|
||||
solrServer.setBaseURL(solrService);
|
||||
|
||||
SolrQuery solrQuery = new SolrQuery().setQuery("*:*");
|
||||
|
||||
solr.query(solrQuery);
|
||||
solrServer.query(solrQuery);
|
||||
|
||||
solr = solrServer;
|
||||
}
|
||||
|
||||
return solr;
|
||||
|
@@ -275,7 +275,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity<Integer>
|
||||
return false;
|
||||
}
|
||||
final BitstreamFormat otherBitstreamFormat = (BitstreamFormat) other;
|
||||
if (this.getID() != otherBitstreamFormat.getID()) {
|
||||
if (!this.getID().equals(otherBitstreamFormat.getID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,10 @@
|
||||
*/
|
||||
package org.dspace.content;
|
||||
|
||||
import static org.dspace.core.Constants.ADD;
|
||||
import static org.dspace.core.Constants.REMOVE;
|
||||
import static org.dspace.core.Constants.WRITE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
@@ -268,6 +272,81 @@ public class BundleServiceImpl extends DSpaceObjectServiceImpl<Bundle> implement
|
||||
return authorizeService.getPolicies(context, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBitstreamOrder(Context context, Bundle bundle, int from, int to)
|
||||
throws AuthorizeException, SQLException {
|
||||
List<Bitstream> bitstreams = bundle.getBitstreams();
|
||||
if (bitstreams.size() < 1 || from >= bitstreams.size() || to >= bitstreams.size() || from < 0 || to < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid 'from' and 'to' arguments supplied for moving a bitstream within bundle " +
|
||||
bundle.getID() + ". from: " + from + "; to: " + to
|
||||
);
|
||||
}
|
||||
List<UUID> bitstreamIds = new LinkedList<>();
|
||||
for (Bitstream bitstream : bitstreams) {
|
||||
bitstreamIds.add(bitstream.getID());
|
||||
}
|
||||
if (from < to) {
|
||||
bitstreamIds.add(to + 1, bitstreamIds.get(from));
|
||||
bitstreamIds.remove(from);
|
||||
} else {
|
||||
bitstreamIds.add(to, bitstreamIds.get(from));
|
||||
bitstreamIds.remove(from + 1);
|
||||
}
|
||||
setOrder(context, bundle, bitstreamIds.toArray(new UUID[bitstreamIds.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveBitstreamToBundle(Context context, Bundle targetBundle, Bitstream bitstream)
|
||||
throws SQLException, AuthorizeException, IOException {
|
||||
List<Bundle> bundles = new LinkedList<>();
|
||||
bundles.addAll(bitstream.getBundles());
|
||||
|
||||
if (hasSufficientMovePermissions(context, bundles, targetBundle)) {
|
||||
this.addBitstream(context, targetBundle, bitstream);
|
||||
this.update(context, targetBundle);
|
||||
for (Bundle bundle : bundles) {
|
||||
this.removeBitstream(context, bundle, bitstream);
|
||||
this.update(context, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies if the context (user) has sufficient rights to the bundles in order to move a bitstream
|
||||
*
|
||||
* @param context The context
|
||||
* @param bundles The current bundles in which the bitstream resides
|
||||
* @param targetBundle The target bundle
|
||||
* @return true when the context has sufficient rights
|
||||
* @throws AuthorizeException When one of the necessary rights is not present
|
||||
*/
|
||||
private boolean hasSufficientMovePermissions(final Context context, final List<Bundle> bundles,
|
||||
final Bundle targetBundle) throws SQLException, AuthorizeException {
|
||||
for (Bundle bundle : bundles) {
|
||||
if (!authorizeService.authorizeActionBoolean(context, bundle, WRITE) || !authorizeService
|
||||
.authorizeActionBoolean(context, bundle, REMOVE)) {
|
||||
throw new AuthorizeException(
|
||||
"The current user does not have WRITE and REMOVE access to the current bundle: " + bundle
|
||||
.getID());
|
||||
}
|
||||
}
|
||||
if (!authorizeService.authorizeActionBoolean(context, targetBundle, WRITE) || !authorizeService
|
||||
.authorizeActionBoolean(context, targetBundle, ADD)) {
|
||||
throw new AuthorizeException(
|
||||
"The current user does not have WRITE and ADD access to the target bundle: " + targetBundle
|
||||
.getID());
|
||||
}
|
||||
for (Item item : targetBundle.getItems()) {
|
||||
if (!authorizeService.authorizeActionBoolean(context, item, WRITE)) {
|
||||
throw new AuthorizeException(
|
||||
"The current user does not have WRITE access to the target bundle's item: " + item.getID());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(Context context, Bundle bundle, UUID[] bitstreamIds) throws AuthorizeException, SQLException {
|
||||
authorizeService.authorizeAction(context, bundle, Constants.WRITE);
|
||||
|
@@ -146,7 +146,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
public List<MetadataValue> getMetadataByMetadataString(T dso, String mdString) {
|
||||
StringTokenizer dcf = new StringTokenizer(mdString, ".");
|
||||
|
||||
String[] tokens = { "", "", "" };
|
||||
String[] tokens = {"", "", ""};
|
||||
int i = 0;
|
||||
while (dcf.hasMoreTokens()) {
|
||||
tokens[i] = dcf.nextToken().trim();
|
||||
@@ -250,8 +250,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
}
|
||||
}
|
||||
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
|
||||
//Set place to list length
|
||||
metadataValue.setPlace(this.getMetadata(dso, Item.ANY, Item.ANY, Item.ANY, Item.ANY).size());
|
||||
//Set place to list length of all metadatavalues for the given schema.element.qualifier combination.
|
||||
// Subtract one to adhere to the 0 as first element rule
|
||||
metadataValue.setPlace(
|
||||
this.getMetadata(dso, metadataField.getMetadataSchema().getName(), metadataField.getElement(),
|
||||
metadataField.getQualifier(), Item.ANY).size() - 1);
|
||||
|
||||
metadataValue.setLanguage(lang == null ? null : lang.trim());
|
||||
|
||||
@@ -533,7 +536,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
protected String[] getMDValueByField(String field) {
|
||||
StringTokenizer dcf = new StringTokenizer(field, ".");
|
||||
|
||||
String[] tokens = { "", "", "" };
|
||||
String[] tokens = {"", "", ""};
|
||||
int i = 0;
|
||||
while (dcf.hasMoreTokens()) {
|
||||
tokens[i] = dcf.nextToken().trim();
|
||||
@@ -571,7 +574,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
if (compare == 0) {
|
||||
if (o1 instanceof RelationshipMetadataValue) {
|
||||
return 1;
|
||||
} else if (o2 instanceof RelationshipMetadataValue) {
|
||||
} else if (o2 instanceof RelationshipMetadataValue) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.content.service.EntityService;
|
||||
import org.dspace.content.service.EntityTypeService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
@@ -37,8 +36,15 @@ public class EntityServiceImpl implements EntityService {
|
||||
|
||||
@Override
|
||||
public Entity findByItemId(Context context, UUID itemId) throws SQLException {
|
||||
|
||||
return findByItemId(context, itemId, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity findByItemId(Context context, UUID itemId, Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
Item item = itemService.find(context, itemId);
|
||||
List<Relationship> relationshipList = relationshipService.findByItem(context, item);
|
||||
List<Relationship> relationshipList = relationshipService.findByItem(context, item, limit, offset);
|
||||
return new Entity(item, relationshipList);
|
||||
}
|
||||
|
||||
@@ -78,65 +84,61 @@ public class EntityServiceImpl implements EntityService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> getRelationsByLabel(Context context, String label) throws SQLException {
|
||||
List<Relationship> listToReturn = new LinkedList<>();
|
||||
List<Relationship> relationshipList = relationshipService.findAll(context);
|
||||
for (Relationship relationship : relationshipList) {
|
||||
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||
if (StringUtils.equals(relationshipType.getLeftLabel(),label) ||
|
||||
StringUtils.equals(relationshipType.getRightLabel(),label)) {
|
||||
listToReturn.add(relationship);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
public List<Relationship> getRelationsByTypeName(Context context, String typeName) throws SQLException {
|
||||
return getRelationsByTypeName(context, typeName, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> getRelationsByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
return relationshipService.findByTypeName(context, typeName, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||
EntityType entityType = this.getType(context, entity);
|
||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||
if (relationshipType.getLeftType().getID() == entityType.getID() ||
|
||||
relationshipType.getRightType().getID() == entityType.getID()) {
|
||||
listToReturn.add(relationshipType);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
|
||||
return getAllRelationshipTypes(context, entity, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||
EntityType entityType = this.getType(context, entity);
|
||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||
if (relationshipType.getLeftType().getID() == entityType.getID()) {
|
||||
listToReturn.add(relationshipType);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
|
||||
return getLeftRelationshipTypes(context, entity, true, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), isLeft, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity) throws SQLException {
|
||||
EntityType entityType = this.getType(context, entity);
|
||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||
if (relationshipType.getRightType().getID() == entityType.getID()) {
|
||||
listToReturn.add(relationshipType);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
|
||||
return getRightRelationshipTypes(context, entity, false, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getRelationshipTypesByLabel(Context context, String label) throws SQLException {
|
||||
List<RelationshipType> listToReturn = new LinkedList<>();
|
||||
for (RelationshipType relationshipType : relationshipTypeService.findAll(context)) {
|
||||
if (StringUtils.equals(relationshipType.getLeftLabel(),label) ||
|
||||
StringUtils.equals(relationshipType.getRightLabel(),label)) {
|
||||
listToReturn.add(relationshipType);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
public List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
return relationshipTypeService.findByEntityType(context, this.getType(context, entity), isLeft, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getRelationshipTypesByTypeName(Context context, String type) throws SQLException {
|
||||
return getRelationshipTypesByTypeName(context, type, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> getRelationshipTypesByTypeName(Context context, String typeName,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
return relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName, limit, offset);
|
||||
}
|
||||
}
|
||||
|
@@ -28,13 +28,20 @@ public class EntityTypeServiceImpl implements EntityTypeService {
|
||||
protected AuthorizeService authorizeService;
|
||||
|
||||
@Override
|
||||
public EntityType findByEntityType(Context context,String entityType) throws SQLException {
|
||||
public EntityType findByEntityType(Context context, String entityType) throws SQLException {
|
||||
return entityTypeDAO.findByEntityType(context, entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntityType> findAll(Context context) throws SQLException {
|
||||
return entityTypeDAO.findAll(context, EntityType.class);
|
||||
|
||||
return findAll(context, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntityType> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
return entityTypeDAO.findAll(context, EntityType.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -13,11 +13,9 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
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.RelationshipService;
|
||||
import org.dspace.content.service.WorkspaceItemService;
|
||||
import org.dspace.content.virtual.VirtualMetadataConfiguration;
|
||||
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
@@ -117,6 +114,9 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
||||
@Autowired(required = true)
|
||||
protected VirtualMetadataPopulator virtualMetadataPopulator;
|
||||
|
||||
@Autowired(required = true)
|
||||
private RelationshipMetadataService relationshipMetadataService;
|
||||
|
||||
protected ItemServiceImpl() {
|
||||
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);
|
||||
}
|
||||
|
||||
@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
|
||||
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
|
||||
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
|
||||
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<>();
|
||||
for (MetadataValue metadataValue : relationMetadata) {
|
||||
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<>();
|
||||
if (enableVirtualMetadata) {
|
||||
fullMetadataValueList.addAll(getRelationshipMetadata(item, true));
|
||||
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
|
||||
|
||||
}
|
||||
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,
|
||||
* MetadataField Qualifier and MetadataField Place in that order.
|
||||
* @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) {
|
||||
Comparator<MetadataValue> comparator = Comparator.comparing(
|
||||
@@ -1427,137 +1407,5 @@ prevent the generation of resource policy entry values with null dspace_object a
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content;
|
||||
|
||||
/**
|
||||
* This Enum holds a representation of all the possible states that a Process can be in
|
||||
*/
|
||||
public enum ProcessStatus {
|
||||
SCHEDULED,
|
||||
RUNNING,
|
||||
COMPLETED,
|
||||
FAILED
|
||||
|
||||
}
|
@@ -77,6 +77,18 @@ public class Relationship implements ReloadableEntity<Integer> {
|
||||
@Column(name = "right_place")
|
||||
private int rightPlace;
|
||||
|
||||
/**
|
||||
* A String containing an alternative value (name variant) for the left side
|
||||
*/
|
||||
@Column(name = "leftward_value")
|
||||
private String leftwardValue;
|
||||
|
||||
/**
|
||||
* A String containing an alternative value (name variant) for the right side
|
||||
*/
|
||||
@Column(name = "rightward_value")
|
||||
private String rightwardValue;
|
||||
|
||||
/**
|
||||
* Protected constructor, create object using:
|
||||
* {@link org.dspace.content.service.RelationshipService#create(Context)} }
|
||||
@@ -170,6 +182,38 @@ public class Relationship implements ReloadableEntity<Integer> {
|
||||
this.rightPlace = rightPlace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard getter for the leftwardValue String in this Relationship
|
||||
* @return the leftwardValue String for this relationship
|
||||
*/
|
||||
public String getLeftwardValue() {
|
||||
return leftwardValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard setter for the leftwardValue String in this Relationship
|
||||
* @param leftwardValue the leftwardValue String that will be used in this relationship
|
||||
*/
|
||||
public void setLeftwardValue(String leftwardValue) {
|
||||
this.leftwardValue = leftwardValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard getter for the rightwardValue String in this Relationship
|
||||
* @return the rightwardValue string for this relationship
|
||||
*/
|
||||
public String getRightwardValue() {
|
||||
return rightwardValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard setter for the rightwardValue String in this Relationship
|
||||
* @param rightwardValue the rightwardValue String that will be used in this relationship
|
||||
*/
|
||||
public void setRightwardValue(String rightwardValue) {
|
||||
this.rightwardValue = rightwardValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard getter for the ID for this Relationship
|
||||
* @return The ID of this relationship
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -10,7 +10,6 @@ package org.dspace.content;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
@@ -59,12 +58,21 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
@Override
|
||||
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||
int leftPlace, int rightPlace) throws AuthorizeException, SQLException {
|
||||
return create(c, leftItem, rightItem, relationshipType, leftPlace, rightPlace, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||
int leftPlace, int rightPlace, String leftwardValue, String rightwardValue)
|
||||
throws AuthorizeException, SQLException {
|
||||
Relationship relationship = new Relationship();
|
||||
relationship.setLeftItem(leftItem);
|
||||
relationship.setRightItem(rightItem);
|
||||
relationship.setRelationshipType(relationshipType);
|
||||
relationship.setLeftPlace(leftPlace);
|
||||
relationship.setRightPlace(rightPlace);
|
||||
relationship.setLeftwardValue(leftwardValue);
|
||||
relationship.setRightwardValue(rightwardValue);
|
||||
return create(c, relationship);
|
||||
}
|
||||
|
||||
@@ -73,8 +81,12 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
if (isRelationshipValidToCreate(context, relationship)) {
|
||||
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
|
||||
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||
updatePlaceInRelationship(context, relationship, true);
|
||||
return relationshipDAO.create(context, relationship);
|
||||
// This order of execution should be handled in the creation (create, updateplace, update relationship)
|
||||
// for a proper place allocation
|
||||
Relationship relationshipToReturn = relationshipDAO.create(context, relationship);
|
||||
updatePlaceInRelationship(context, relationshipToReturn);
|
||||
update(context, relationshipToReturn);
|
||||
return relationshipToReturn;
|
||||
} else {
|
||||
throw new AuthorizeException(
|
||||
"You do not have write rights on this relationship's items");
|
||||
@@ -86,20 +98,36 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlaceInRelationship(Context context, Relationship relationship, boolean isCreation)
|
||||
public void updatePlaceInRelationship(Context context, Relationship relationship)
|
||||
throws SQLException, AuthorizeException {
|
||||
Item leftItem = relationship.getLeftItem();
|
||||
// Max value is used to ensure that these will get added to the back of the list and thus receive the highest
|
||||
// (last) place as it's set to a -1 for creation
|
||||
if (relationship.getLeftPlace() == -1) {
|
||||
relationship.setLeftPlace(Integer.MAX_VALUE);
|
||||
}
|
||||
Item rightItem = relationship.getRightItem();
|
||||
if (relationship.getRightPlace() == -1) {
|
||||
relationship.setRightPlace(Integer.MAX_VALUE);
|
||||
}
|
||||
List<Relationship> leftRelationships = findByItemAndRelationshipType(context,
|
||||
leftItem,
|
||||
relationship.getRelationshipType(), true);
|
||||
Item rightItem = relationship.getRightItem();
|
||||
List<Relationship> rightRelationships = findByItemAndRelationshipType(context,
|
||||
rightItem,
|
||||
relationship.getRelationshipType(),
|
||||
false);
|
||||
|
||||
// These relationships are only deleted from the temporary lists incase they're present in them so that we can
|
||||
// properly perform our place calculation later down the line in this method.
|
||||
if (leftRelationships.contains(relationship)) {
|
||||
leftRelationships.remove(relationship);
|
||||
}
|
||||
if (rightRelationships.contains(relationship)) {
|
||||
rightRelationships.remove(relationship);
|
||||
}
|
||||
context.turnOffAuthorisationSystem();
|
||||
//If useForPlace for the 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.
|
||||
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), true)) {
|
||||
if (!leftRelationships.isEmpty()) {
|
||||
@@ -116,7 +144,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.
|
||||
if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), false)) {
|
||||
if (!rightRelationships.isEmpty()) {
|
||||
@@ -133,10 +161,6 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
updateItem(context, rightItem);
|
||||
|
||||
}
|
||||
|
||||
if (isCreation) {
|
||||
handleCreationPlaces(context, relationship);
|
||||
}
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
}
|
||||
@@ -148,43 +172,14 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
itemService.update(context, relatedItem);
|
||||
}
|
||||
|
||||
|
||||
//Sets the places for the Relationship properly if the updatePlaceInRelationship was called for a new creation
|
||||
//of this Relationship
|
||||
private void handleCreationPlaces(Context context, Relationship relationship) throws SQLException {
|
||||
List<Relationship> leftRelationships;
|
||||
List<Relationship> rightRelationships;
|
||||
leftRelationships = findByItemAndRelationshipType(context,
|
||||
relationship.getLeftItem(),
|
||||
relationship.getRelationshipType(), true);
|
||||
rightRelationships = findByItemAndRelationshipType(context,
|
||||
relationship.getRightItem(),
|
||||
relationship.getRelationshipType(),
|
||||
false);
|
||||
leftRelationships.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
|
||||
rightRelationships.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
|
||||
|
||||
if (!leftRelationships.isEmpty()) {
|
||||
relationship.setLeftPlace(leftRelationships.get(0).getLeftPlace() + 1);
|
||||
} else {
|
||||
relationship.setLeftPlace(0);
|
||||
}
|
||||
|
||||
if (!rightRelationships.isEmpty()) {
|
||||
relationship.setRightPlace(rightRelationships.get(0).getRightPlace() + 1);
|
||||
} else {
|
||||
relationship.setRightPlace(0);
|
||||
}
|
||||
@Override
|
||||
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||
return relationshipDAO.findNextLeftPlaceByLeftItem(context, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||
return relationshipDAO.findLeftPlaceByLeftItem(context, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||
return relationshipDAO.findRightPlaceByRightItem(context, item);
|
||||
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||
return relationshipDAO.findNextRightPlaceByRightItem(context, item);
|
||||
}
|
||||
|
||||
private boolean isRelationshipValidToCreate(Context context, Relationship relationship) throws SQLException {
|
||||
@@ -221,8 +216,8 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
|
||||
private void logRelationshipTypeDetailsForError(RelationshipType relationshipType) {
|
||||
log.warn("The relationshipType's ID is: " + relationshipType.getID());
|
||||
log.warn("The relationshipType's left label is: " + relationshipType.getLeftLabel());
|
||||
log.warn("The relationshipType's right label is: " + relationshipType.getRightLabel());
|
||||
log.warn("The relationshipType's leftward type is: " + relationshipType.getLeftwardType());
|
||||
log.warn("The relationshipType's rightward type is: " + relationshipType.getRightwardType());
|
||||
log.warn("The relationshipType's left entityType label is: " + relationshipType.getLeftType().getLabel());
|
||||
log.warn("The relationshipType's right entityType label is: " + relationshipType.getRightType().getLabel());
|
||||
log.warn("The relationshipType's left min cardinality is: " + relationshipType.getLeftMinCardinality());
|
||||
@@ -259,11 +254,18 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
@Override
|
||||
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
|
||||
|
||||
List<Relationship> list = relationshipDAO.findByItem(context, item);
|
||||
return findByItem(context, item, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
|
||||
List<Relationship> list = relationshipDAO.findByItem(context, item, limit, offset);
|
||||
|
||||
list.sort((o1, o2) -> {
|
||||
int relationshipType = o1.getRelationshipType().getLeftLabel()
|
||||
.compareTo(o2.getRelationshipType().getLeftLabel());
|
||||
int relationshipType = o1.getRelationshipType().getLeftwardType()
|
||||
.compareTo(o2.getRelationshipType().getLeftwardType());
|
||||
if (relationshipType != 0) {
|
||||
return relationshipType;
|
||||
} else {
|
||||
@@ -279,7 +281,12 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
|
||||
@Override
|
||||
public List<Relationship> findAll(Context context) throws SQLException {
|
||||
return relationshipDAO.findAll(context, Relationship.class);
|
||||
return findAll(context, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||
return relationshipDAO.findAll(context, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -311,7 +318,7 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
|
||||
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
|
||||
relationshipDAO.delete(context, relationship);
|
||||
updatePlaceInRelationship(context, relationship, false);
|
||||
updatePlaceInRelationship(context, relationship);
|
||||
} else {
|
||||
throw new AuthorizeException(
|
||||
"You do not have write rights on this relationship's items");
|
||||
@@ -359,8 +366,8 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
private boolean checkMinCardinality(Context context, Item item,
|
||||
Relationship relationship,
|
||||
Integer minCardinality, boolean isLeft) throws SQLException {
|
||||
List<Relationship> list = this
|
||||
.findByItemAndRelationshipType(context, item, relationship.getRelationshipType(), isLeft);
|
||||
List<Relationship> list = this.findByItemAndRelationshipType(context, item, relationship.getRelationshipType(),
|
||||
isLeft, -1, -1);
|
||||
if (minCardinality != null && !(list.size() > minCardinality)) {
|
||||
return false;
|
||||
}
|
||||
@@ -369,46 +376,83 @@ public class RelationshipServiceImpl implements RelationshipService {
|
||||
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, boolean isLeft)
|
||||
|
||||
throws SQLException {
|
||||
List<Relationship> list = this.findByItem(context, item);
|
||||
List<Relationship> listToReturn = new LinkedList<>();
|
||||
for (Relationship relationship : list) {
|
||||
if (isLeft) {
|
||||
if (StringUtils
|
||||
.equals(relationship.getRelationshipType().getLeftLabel(), relationshipType.getLeftLabel())) {
|
||||
listToReturn.add(relationship);
|
||||
}
|
||||
} else {
|
||||
if (StringUtils
|
||||
.equals(relationship.getRelationshipType().getRightLabel(), relationshipType.getRightLabel())) {
|
||||
listToReturn.add(relationship);
|
||||
}
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
return this.findByItemAndRelationshipType(context, item, relationshipType, isLeft, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType)
|
||||
|
||||
throws SQLException {
|
||||
List<Relationship> list = this.findByItem(context, item);
|
||||
List<Relationship> listToReturn = new LinkedList<>();
|
||||
for (Relationship relationship : list) {
|
||||
if (relationship.getRelationshipType().equals(relationshipType)) {
|
||||
listToReturn.add(relationship);
|
||||
}
|
||||
}
|
||||
return listToReturn;
|
||||
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, int limit, int offset)
|
||||
throws SQLException {
|
||||
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, boolean isLeft,
|
||||
int limit, int offset)
|
||||
throws SQLException {
|
||||
return relationshipDAO.findByItemAndRelationshipType(context, item, relationshipType, isLeft, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
return relationshipDAO.findByRelationshipType(context, relationshipType);
|
||||
|
||||
return findByRelationshipType(context, relationshipType, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException {
|
||||
return relationshipDAO.findByRelationshipType(context, relationshipType, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByTypeName(Context context, String typeName)
|
||||
throws SQLException {
|
||||
return this.findByTypeName(context, typeName, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
return relationshipDAO.findByTypeName(context, typeName, limit, offset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int countTotal(Context context) throws SQLException {
|
||||
return relationshipDAO.countRows(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByItem(Context context, Item item) throws SQLException {
|
||||
return relationshipDAO.countByItem(context, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException {
|
||||
return relationshipDAO.countByRelationshipType(context, relationshipType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
return relationshipDAO.countByItemAndRelationshipType(context, item, relationshipType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByTypeName(Context context, String typeName)
|
||||
throws SQLException {
|
||||
return relationshipDAO.countByTypeName(context, typeName);
|
||||
}
|
||||
}
|
||||
|
@@ -26,8 +26,8 @@ import org.dspace.core.ReloadableEntity;
|
||||
* Class representing a RelationshipType
|
||||
* This class contains an Integer ID that will be the unique value and primary key in the database.
|
||||
* This key is automatically generated
|
||||
* It also has a leftType and rightType EntityType that describes the relationshipType together with a leftLabel and
|
||||
* rightLabel.
|
||||
* It also has a leftType and rightType EntityType that describes the relationshipType together with a leftwardType and
|
||||
* rightwardType.
|
||||
* The cardinality properties describe how many of each relations this relationshipType can support
|
||||
*/
|
||||
@Entity
|
||||
@@ -61,20 +61,20 @@ public class RelationshipType implements ReloadableEntity<Integer> {
|
||||
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 a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||
*/
|
||||
@Column(name = "left_label", nullable = false)
|
||||
private String leftLabel;
|
||||
@Column(name = "leftward_type", nullable = false)
|
||||
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 a textual representation of the name of the relationship that this RelationshipType is connected to
|
||||
*/
|
||||
@Column(name = "right_label", nullable = false)
|
||||
private String rightLabel;
|
||||
@Column(name = "rightward_type", nullable = false)
|
||||
private String rightwardType;
|
||||
|
||||
/**
|
||||
* The minimum amount of relations for the leftItem that need to be present at all times
|
||||
@@ -149,35 +149,35 @@ public class RelationshipType implements ReloadableEntity<Integer> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard getter for the leftLabel String for this RelationshipType
|
||||
* @return The leftLabel String of this RelationshipType
|
||||
* Standard getter for the leftwardType String for this RelationshipType
|
||||
* @return The leftwardType String of this RelationshipType
|
||||
*/
|
||||
public String getLeftLabel() {
|
||||
return leftLabel;
|
||||
public String getLeftwardType() {
|
||||
return leftwardType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard setter for the leftLabel String for this RelationshipType
|
||||
* @param leftLabel The leftLabel String that this RelationshipType should receive
|
||||
* Standard setter for the leftwardType String for this RelationshipType
|
||||
* @param leftwardType The leftwardType String that this RelationshipType should receive
|
||||
*/
|
||||
public void setLeftLabel(String leftLabel) {
|
||||
this.leftLabel = leftLabel;
|
||||
public void setLeftwardType(String leftwardType) {
|
||||
this.leftwardType = leftwardType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard getter for the rightLabel String for this RelationshipType
|
||||
* @return The rightLabel String of this RelationshipType
|
||||
* Standard getter for the rightwardType String for this RelationshipType
|
||||
* @return The rightwardType String of this RelationshipType
|
||||
*/
|
||||
public String getRightLabel() {
|
||||
return rightLabel;
|
||||
public String getRightwardType() {
|
||||
return rightwardType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard setter for the rightLabel String for this RelationshipType
|
||||
* @param rightLabel The rightLabel String that this RelationshipType should receive
|
||||
* Standard setter for the rightwardType String for this RelationshipType
|
||||
* @param rightwardType The rightwardType String that this RelationshipType should receive
|
||||
*/
|
||||
public void setRightLabel(String rightLabel) {
|
||||
this.rightLabel = rightLabel;
|
||||
public void setRightwardType(String rightwardType) {
|
||||
this.rightwardType = rightwardType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -47,37 +47,69 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
||||
String leftLabel,String rightLabel) throws SQLException {
|
||||
return relationshipTypeDAO.findByTypesAndLabels(context, leftType, rightType, leftLabel, rightLabel);
|
||||
public RelationshipType findbyTypesAndTypeName(Context context,EntityType leftType,EntityType rightType,
|
||||
String leftwardType,String rightwardType) throws SQLException {
|
||||
return relationshipTypeDAO.findbyTypesAndTypeName(context, leftType, rightType, leftwardType, rightwardType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findAll(Context context) throws SQLException {
|
||||
return relationshipTypeDAO.findAll(context, RelationshipType.class);
|
||||
return findAll(context, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException {
|
||||
return relationshipTypeDAO.findByLeftOrRightLabel(context, label);
|
||||
public List<RelationshipType> findAll(Context context, Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
return relationshipTypeDAO.findAll(context, RelationshipType.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName)
|
||||
throws SQLException {
|
||||
return findByLeftwardOrRightwardTypeName(context, typeName, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException {
|
||||
return relationshipTypeDAO.findByLeftwardOrRightwardTypeName(context, typeName, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException {
|
||||
return relationshipTypeDAO.findByEntityType(context, entityType);
|
||||
return findByEntityType(context, entityType, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
return relationshipTypeDAO.findByEntityType(context, entityType, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft)
|
||||
throws SQLException {
|
||||
return findByEntityType(context, entityType, isLeft, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
return relationshipTypeDAO.findByEntityType(context, entityType, isLeft, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||
String leftLabel, String rightLabel, Integer leftCardinalityMinInteger,
|
||||
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
|
||||
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
||||
Integer rightCardinalityMaxInteger)
|
||||
throws SQLException, AuthorizeException {
|
||||
RelationshipType relationshipType = new RelationshipType();
|
||||
relationshipType.setLeftType(leftEntityType);
|
||||
relationshipType.setRightType(rightEntityType);
|
||||
relationshipType.setLeftLabel(leftLabel);
|
||||
relationshipType.setRightLabel(rightLabel);
|
||||
relationshipType.setLeftwardType(leftwardType);
|
||||
relationshipType.setRightwardType(rightwardType);
|
||||
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
|
||||
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
|
||||
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);
|
||||
|
@@ -220,6 +220,11 @@ public final class ChoiceAuthorityServiceImpl implements ChoiceAuthorityService
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
controller.clear();
|
||||
authorities.clear();
|
||||
}
|
||||
private void loadChoiceAuthorityConfigurations() {
|
||||
// Get all configuration keys starting with a given prefix
|
||||
List<String> propKeys = configurationService.getPropertyKeys(CHOICES_PLUGIN_PREFIX);
|
||||
|
@@ -241,7 +241,7 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
|
||||
} catch (XPathExpressionException e) {
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
return new Choice("", "", "");
|
||||
return null;
|
||||
}
|
||||
|
||||
private void readNode(String[] authorities, String[] values, String[] labels, String[] parent, String[] notes,
|
||||
|
@@ -65,7 +65,7 @@ public class InputFormSelfRegisterWrapperAuthority implements ChoiceAuthority {
|
||||
}
|
||||
}
|
||||
if (!choices.isEmpty()) {
|
||||
Choice[] results = new Choice[choices.size() - 1];
|
||||
Choice[] results = new Choice[choices.size()];
|
||||
choices.toArray(results);
|
||||
return new Choices(results, 0, choices.size(), Choices.CF_AMBIGUOUS, false);
|
||||
}
|
||||
|
@@ -188,8 +188,8 @@ public class SolrAuthority implements ChoiceAuthority {
|
||||
}
|
||||
|
||||
private String toQuery(String searchField, String text) {
|
||||
return searchField + ":\"" + text.toLowerCase().replaceAll(":", "\\:") + "*\" or " + searchField + ":\"" + text
|
||||
.toLowerCase().replaceAll(":", "\\:") + "\"";
|
||||
return searchField + ":(" + text.toLowerCase().replaceAll(":", "\\:") + "*) or " + searchField + ":(" + text
|
||||
.toLowerCase().replaceAll(":", "\\:") + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -168,4 +168,9 @@ public interface ChoiceAuthorityService {
|
||||
|
||||
public ChoiceAuthority getChoiceAuthorityByAuthorityName(String authorityName);
|
||||
|
||||
/**
|
||||
* This method has been created to have a way of clearing the cache kept inside the service
|
||||
*/
|
||||
public void clearCache();
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.GenericDAO;
|
||||
import org.dspace.scripts.Process;
|
||||
|
||||
/**
|
||||
* This is the Data Access Object for the {@link Process} object
|
||||
*/
|
||||
public interface ProcessDAO extends GenericDAO<Process> {
|
||||
|
||||
/**
|
||||
* This method will return all the Process objects in the database in a list and it'll be sorted by script name
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of all Process objects in the database sorted on scriptname
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAllSortByScript(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return all the Process objects in the database in a list and it'll be sorted by start time.
|
||||
* The most recent one will be shown first
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of all Process objects in the database sorted by starttime
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAllSortByStartTime(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a list of all Process objects in the database
|
||||
* @param context The relevant DSpace context
|
||||
* @param limit The limit for the amount of Processes returned
|
||||
* @param offset The offset for the Processes to be returned
|
||||
* @return The list of all Process objects in the Database
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Process> findAll(Context context, int limit, int offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns the total amount of Process objects in the dataase
|
||||
* @param context The relevant DSpace context
|
||||
* @return An integer that describes the amount of Process objects in the database
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int countRows(Context context) throws SQLException;
|
||||
|
||||
}
|
@@ -34,29 +34,43 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
|
||||
* right item that is equal to the given item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByItem(Context context,Item item) throws SQLException;
|
||||
List<Relationship> findByItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns the highest leftplace integer for all the relationships where this
|
||||
* item is the leftitem so that we can set a proper leftplace attribute on the next relationship
|
||||
* This method returns a list of Relationship objects that have the given Item object
|
||||
* as a leftItem or a rightItem
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item that should be either a leftItem or a rightItem of all
|
||||
* the Relationship objects in the returned list
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of Relationship objects that contain either a left or a
|
||||
* right item that is equal to the given item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem
|
||||
*
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item to be matched on leftItem
|
||||
* @return The integer for the highest leftPlace value for all the relatonship objects
|
||||
* that have the given item as leftItem
|
||||
* @return The next integer to be used for the leftplace of a relationship with the given item
|
||||
* as a left item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int findLeftPlaceByLeftItem(Context context,Item item) throws SQLException;
|
||||
int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns the highest rightplace integer for all the relationships where this
|
||||
* item is the rightitem so that we can set a proper rightplace attribute on the next relationship
|
||||
* This method returns the next rightplace integer to use for a relationship with this item as the rightItem
|
||||
*
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item to be matched on rightItem
|
||||
* @return The integer for the highest rightPlace value for all the relatonship objects
|
||||
* that have the given item as rightItem
|
||||
* @return The next integer to be used for the rightplace of a relationship with the given item
|
||||
* as a right item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int findRightPlaceByRightItem(Context context,Item item) throws SQLException;
|
||||
int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||
@@ -69,4 +83,131 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||
* as the relationshipType property
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationshipType The RelationshipType object to be checked on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType,
|
||||
Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||
* as the relationshipType property
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationshipType The RelationshipType object to be checked on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @param item item to filter by
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType,
|
||||
Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given RelationshipType object.
|
||||
* It will construct a list of all Relationship objects that have the given RelationshipType object
|
||||
* as the relationshipType property
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationshipType The RelationshipType object to be checked on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @param item item to filter by
|
||||
* @param isLeft Is item left or right
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType,
|
||||
boolean isLeft, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given typeName
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The leftward or rightward typeName of the relationship type
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByTypeName(Context context, String typeName)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given typeName
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The leftward or rightward typeName of the relationship type
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table)
|
||||
*
|
||||
* @param context context
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countRows(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table) by a relationship type
|
||||
*
|
||||
* @param context context
|
||||
* @param relationshipType relationship type to filter by
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a count of Relationship objects that have the given Item object
|
||||
* as a leftItem or a rightItem
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item that should be either a leftItem or a rightItem of all
|
||||
* the Relationship objects in the returned list
|
||||
* @return The list of Relationship objects that contain either a left or a
|
||||
* right item that is equal to the given item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int countByItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table) by an item and a relationship type
|
||||
*
|
||||
* @param context context
|
||||
* @param relationshipType relationship type to filter by
|
||||
* @param item item to filter by
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table) given a typeName
|
||||
*
|
||||
* @param context context
|
||||
* @param typeName the relationship typeName to filter by
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByTypeName(Context context, String typeName)
|
||||
throws SQLException;
|
||||
}
|
||||
|
@@ -25,28 +25,44 @@ public interface RelationshipTypeDAO extends GenericDAO<RelationshipType> {
|
||||
|
||||
/**
|
||||
* This method is used to retrieve the RelationshipType object that has the same
|
||||
* leftType, rightType, leftLabel and rightLabel as given in the parameters
|
||||
* @param context The relevant DSpace context
|
||||
* @param leftType The leftType EntityType object to be matched in the query
|
||||
* @param rightType The rightType EntityType object to be matched in the query
|
||||
* @param leftLabel The leftLabel String to be matched in the query
|
||||
* @param rightLabel The rightLabel String to be matched in the query
|
||||
* @return The RelationshipType object that matches all the given parameters
|
||||
* leftType, rightType, leftwardType and rightwardType as given in the parameters
|
||||
* @param context The relevant DSpace context
|
||||
* @param leftType The leftType EntityType object to be matched in the query
|
||||
* @param rightType The rightType EntityType object to be matched in the query
|
||||
* @param leftwardType The leftwardType String to be matched in the query
|
||||
* @param rightwardType The rightwardType String to be matched in the query
|
||||
* @return The RelationshipType object that matches all the given parameters
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
RelationshipType findByTypesAndLabels(Context context,
|
||||
EntityType leftType,EntityType rightType,String leftLabel,String rightLabel)
|
||||
throws SQLException;
|
||||
RelationshipType findbyTypesAndTypeName(Context context, EntityType leftType,EntityType rightType,
|
||||
String leftwardType,
|
||||
String rightwardType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given label is equal to
|
||||
* either the leftwardType or rightwardType.
|
||||
* @param context The relevant DSpace context
|
||||
* @param type The label that will be used to check on
|
||||
* @return A list of RelationshipType objects that have the given label as either the leftwardType
|
||||
* or rightwardType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given label is equal to
|
||||
* either the leftLabel or rightLabel.
|
||||
* @param context The relevant DSpace context
|
||||
* @param label The label that will be used to check on
|
||||
* @param type The label that will be used to check on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return A list of RelationshipType objects that have the given label as either the leftLabel or rightLabel
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException;
|
||||
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
@@ -58,4 +74,50 @@ public interface RelationshipTypeDAO extends GenericDAO<RelationshipType> {
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
* to the leftType or rightType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entityType The EntityType object that will be used to check on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of RelationshipType objects that have the given EntityType object
|
||||
* as either a leftType or rightType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
* to the leftType or rightType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entityType The EntityType object that will be used to check on
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @return The list of RelationshipType objects that have the given EntityType object
|
||||
* as either a leftType or rightType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
* to the leftType or rightType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entityType The EntityType object that will be used to check on
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of RelationshipType objects that have the given EntityType object
|
||||
* as either a leftType or rightType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft,
|
||||
Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@ package org.dspace.content.dao.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -64,11 +63,20 @@ public class CollectionDAOImpl extends AbstractHibernateDSODAO<Collection> imple
|
||||
public List<Collection> findAll(Context context, MetadataField order, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
StringBuilder query = new StringBuilder();
|
||||
query.append("SELECT ").append(Collection.class.getSimpleName()).append(" FROM Collection as ")
|
||||
.append(Collection.class.getSimpleName()).append(" ");
|
||||
addMetadataLeftJoin(query, Collection.class.getSimpleName(), Arrays.asList(order));
|
||||
addMetadataSortQuery(query, Arrays.asList(order), null);
|
||||
|
||||
// The query has to be rather complex because we want to sort the retrieval of Collections based on the title
|
||||
// We'll join the Collections with the metadata fields on the sortfield specified in the parameters
|
||||
// then we'll sort on this metadata field (this is usually the title). We're also making sure that the place
|
||||
// is the lowest place in the metadata fields list so that we avoid the duplication bug
|
||||
query.append("SELECT c" +
|
||||
" FROM Collection c" +
|
||||
" left join c.metadata title on title.metadataField = :sortField and" +
|
||||
" title.dSpaceObject = c.id and" +
|
||||
" title.place = (select min(internal.place) " +
|
||||
"from c.metadata internal " +
|
||||
"where internal.metadataField = :sortField and" +
|
||||
" internal.dSpaceObject = c.id)" +
|
||||
" ORDER BY LOWER(title.value)");
|
||||
Query hibernateQuery = createQuery(context, query.toString());
|
||||
if (offset != null) {
|
||||
hibernateQuery.setFirstResult(offset);
|
||||
@@ -76,7 +84,7 @@ public class CollectionDAOImpl extends AbstractHibernateDSODAO<Collection> imple
|
||||
if (limit != null) {
|
||||
hibernateQuery.setMaxResults(limit);
|
||||
}
|
||||
hibernateQuery.setParameter(order.toString(), order.getID());
|
||||
hibernateQuery.setParameter("sortField", order);
|
||||
return list(hibernateQuery);
|
||||
}
|
||||
|
||||
|
@@ -8,8 +8,6 @@
|
||||
package org.dspace.content.dao.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
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)
|
||||
throws SQLException {
|
||||
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());
|
||||
if (offset != null) {
|
||||
query.setFirstResult(offset);
|
||||
@@ -74,7 +81,8 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
||||
if (limit != null) {
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
query.setParameter(sortField.toString(), sortField.getID());
|
||||
query.setParameter("sortField", sortField);
|
||||
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@@ -91,16 +99,26 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
|
||||
@Override
|
||||
public List<Community> findAllNoParent(Context context, MetadataField sortField) throws SQLException {
|
||||
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.setParameter(sortField.toString(), sortField.getID());
|
||||
query.setParameter("sortField", sortField);
|
||||
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
|
||||
|
||||
|
||||
return findMany(context, query);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.dao.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.dspace.content.dao.ProcessDAO;
|
||||
import org.dspace.core.AbstractHibernateDAO;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.Process;
|
||||
import org.dspace.scripts.Process_;
|
||||
|
||||
/**
|
||||
* Implementation class for {@link ProcessDAO}
|
||||
*/
|
||||
public class ProcessDAOImpl extends AbstractHibernateDAO<Process> implements ProcessDAO {
|
||||
|
||||
@Override
|
||||
public List<Process> findAllSortByScript(Context context) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||
criteriaQuery.select(processRoot);
|
||||
criteriaQuery.orderBy(criteriaBuilder.asc(processRoot.get(Process_.name)));
|
||||
|
||||
return list(context, criteriaQuery, false, Process.class, -1, -1);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAllSortByStartTime(Context context) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||
criteriaQuery.select(processRoot);
|
||||
criteriaQuery.orderBy(criteriaBuilder.desc(processRoot.get(Process_.startTime)),
|
||||
criteriaBuilder.desc(processRoot.get(Process_.processId)));
|
||||
|
||||
return list(context, criteriaQuery, false, Process.class, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAll(Context context, int limit, int offset) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||
criteriaQuery.select(processRoot);
|
||||
|
||||
return list(context, criteriaQuery, false, Process.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countRows(Context context) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||
criteriaQuery.select(processRoot);
|
||||
|
||||
return count(context, criteriaQuery, criteriaBuilder, processRoot);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package org.dspace.content.dao.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
@@ -18,6 +19,8 @@ import org.dspace.content.Relationship;
|
||||
import org.dspace.content.RelationshipType;
|
||||
import org.dspace.content.Relationship_;
|
||||
import org.dspace.content.dao.RelationshipDAO;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.RelationshipTypeService;
|
||||
import org.dspace.core.AbstractHibernateDAO;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
@@ -25,6 +28,14 @@ public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> impl
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
|
||||
|
||||
return findByItem(context, item, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
@@ -32,11 +43,25 @@ public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> impl
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.or(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||
return list(context, criteriaQuery, false, Relationship.class, -1, -1);
|
||||
return list(context, criteriaQuery, false, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||
public int countByItem(Context context, Item item)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.or(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
@@ -45,39 +70,165 @@ public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> impl
|
||||
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
|
||||
list.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
|
||||
if (!list.isEmpty()) {
|
||||
return list.get(0).getLeftPlace();
|
||||
return list.get(0).getLeftPlace() + 1;
|
||||
} else {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item));
|
||||
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
|
||||
list.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
|
||||
list.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
|
||||
if (!list.isEmpty()) {
|
||||
return list.get(0).getLeftPlace();
|
||||
return list.get(0).getRightPlace() + 1;
|
||||
} else {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
|
||||
return findByRelationshipType(context, relationshipType, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType), relationshipType));
|
||||
return list(context, criteriaQuery, true, Relationship.class, -1, -1);
|
||||
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||
relationshipType), criteriaBuilder.or
|
||||
(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, boolean isLeft,
|
||||
Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
if (isLeft) {
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||
relationshipType),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item));
|
||||
} else {
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||
relationshipType),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item));
|
||||
}
|
||||
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByTypeName(Context context, String typeName)
|
||||
throws SQLException {
|
||||
return this.findByTypeName(context, typeName, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException {
|
||||
RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||
.getRelationshipTypeService();
|
||||
List<RelationshipType> relTypes = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName);
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
for ( RelationshipType relationshipType : relTypes) {
|
||||
ids.add(relationshipType.getID());
|
||||
}
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.where(relationshipRoot.get(Relationship_.relationshipType).in(ids));
|
||||
return list(context, criteriaQuery, true, Relationship.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType), relationshipType));
|
||||
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countRows(Context context) throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.select(relationshipRoot);
|
||||
criteriaQuery
|
||||
.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.relationshipType),
|
||||
relationshipType), criteriaBuilder.or
|
||||
(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
|
||||
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
|
||||
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countByTypeName(Context context, String typeName)
|
||||
throws SQLException {
|
||||
RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||
.getRelationshipTypeService();
|
||||
List<RelationshipType> relTypes = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, typeName);
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
for ( RelationshipType relationshipType : relTypes) {
|
||||
ids.add(relationshipType.getID());
|
||||
}
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
|
||||
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
|
||||
criteriaQuery.where(relationshipRoot.get(Relationship_.relationshipType).in(ids));
|
||||
return count(context, criteriaQuery, criteriaBuilder, relationshipRoot);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -23,39 +23,55 @@ import org.dspace.core.Context;
|
||||
public class RelationshipTypeDAOImpl extends AbstractHibernateDAO<RelationshipType> implements RelationshipTypeDAO {
|
||||
|
||||
@Override
|
||||
public RelationshipType findByTypesAndLabels(Context context, EntityType leftType, EntityType rightType,
|
||||
String leftLabel, String rightLabel)
|
||||
public RelationshipType findbyTypesAndTypeName(Context context, EntityType leftType, EntityType rightType,
|
||||
String leftwardType, String rightwardType)
|
||||
throws SQLException {
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||
criteriaQuery.select(relationshipTypeRoot);
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.and(criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), leftType),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), rightType),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftLabel), leftLabel),
|
||||
criteriaBuilder
|
||||
.equal(relationshipTypeRoot.get(RelationshipType_.rightLabel), rightLabel)));
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), leftType),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), rightType),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), leftwardType),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), rightwardType)));
|
||||
return uniqueResult(context, criteriaQuery, false, RelationshipType.class, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException {
|
||||
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type) throws SQLException {
|
||||
|
||||
return findByLeftwardOrRightwardTypeName(context, type, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String type, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||
criteriaQuery.select(relationshipTypeRoot);
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftLabel), label),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightLabel), label)
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftwardType), type),
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightwardType), type)
|
||||
)
|
||||
);
|
||||
return list(context, criteriaQuery, true, RelationshipType.class, -1, -1);
|
||||
return list(context, criteriaQuery, true, RelationshipType.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException {
|
||||
return findByEntityType(context, entityType, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||
@@ -67,7 +83,32 @@ public class RelationshipTypeDAOImpl extends AbstractHibernateDAO<RelationshipTy
|
||||
.equal(relationshipTypeRoot.get(RelationshipType_.rightType), entityType)
|
||||
)
|
||||
);
|
||||
return list(context, criteriaQuery, false, RelationshipType.class, -1, -1);
|
||||
return list(context, criteriaQuery, false, RelationshipType.class, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft)
|
||||
throws SQLException {
|
||||
return findByEntityType(context, entityType, isLeft, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationshipType> findByEntityType(Context context, EntityType entityType, Boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException {
|
||||
|
||||
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, RelationshipType.class);
|
||||
Root<RelationshipType> relationshipTypeRoot = criteriaQuery.from(RelationshipType.class);
|
||||
criteriaQuery.select(relationshipTypeRoot);
|
||||
if (isLeft) {
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.leftType), entityType)
|
||||
);
|
||||
} else {
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.equal(relationshipTypeRoot.get(RelationshipType_.rightType), entityType)
|
||||
);
|
||||
}
|
||||
return list(context, criteriaQuery, false, RelationshipType.class, limit, offset);
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import java.util.List;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.InProgressSubmission;
|
||||
import org.dspace.content.RelationshipMetadataService;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.service.BitstreamFormatService;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
@@ -112,6 +113,8 @@ public abstract class ContentServiceFactory {
|
||||
*/
|
||||
public abstract EntityService getEntityService();
|
||||
|
||||
public abstract RelationshipMetadataService getRelationshipMetadataService();
|
||||
|
||||
public InProgressSubmissionService getInProgressSubmissionService(InProgressSubmission inProgressSubmission) {
|
||||
if (inProgressSubmission instanceof WorkspaceItem) {
|
||||
return getWorkspaceItemService();
|
||||
|
@@ -10,6 +10,7 @@ package org.dspace.content.factory;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.RelationshipMetadataService;
|
||||
import org.dspace.content.service.BitstreamFormatService;
|
||||
import org.dspace.content.service.BitstreamService;
|
||||
import org.dspace.content.service.BundleService;
|
||||
@@ -78,6 +79,8 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
||||
@Autowired(required = true)
|
||||
private RelationshipTypeService relationshipTypeService;
|
||||
@Autowired(required = true)
|
||||
private RelationshipMetadataService relationshipMetadataService;
|
||||
@Autowired(required = true)
|
||||
private EntityTypeService entityTypeService;
|
||||
@Autowired(required = true)
|
||||
private EntityService entityService;
|
||||
@@ -182,4 +185,8 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
|
||||
return entityService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationshipMetadataService getRelationshipMetadataService() {
|
||||
return relationshipMetadataService;
|
||||
}
|
||||
}
|
||||
|
@@ -109,6 +109,31 @@ public interface BundleService extends DSpaceObjectService<Bundle>, DSpaceObject
|
||||
|
||||
public List<ResourcePolicy> getBundlePolicies(Context context, Bundle bundle) throws SQLException;
|
||||
|
||||
/**
|
||||
* Moves a bitstream within a bundle from one place to another, shifting all other bitstreams in the process
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param bundle The bitstream bundle
|
||||
* @param from The index of the bitstream to move
|
||||
* @param to The index to move the bitstream to
|
||||
* @throws AuthorizeException when an SQL error has occurred (querying DSpace)
|
||||
* @throws SQLException If the user can't make the changes
|
||||
*/
|
||||
public void updateBitstreamOrder(Context context, Bundle bundle, int from, int to) throws AuthorizeException,
|
||||
SQLException;
|
||||
|
||||
/**
|
||||
* Moves a bitstream from its current bundle to a new target bundle
|
||||
* @param context DSpace Context
|
||||
* @param targetBundle The target bundle where bitstream will be moved to
|
||||
* @param bitstream The bitstream being moved
|
||||
* @throws SQLException if database error
|
||||
* @throws AuthorizeException if authorization error
|
||||
* @throws IOException if IO error
|
||||
*/
|
||||
public void moveBitstreamToBundle(Context context, Bundle targetBundle, Bitstream bitstream) throws SQLException,
|
||||
AuthorizeException, IOException;
|
||||
|
||||
/**
|
||||
* Changes bitstream order according to the array
|
||||
*
|
||||
|
@@ -36,6 +36,19 @@ public interface EntityService {
|
||||
*/
|
||||
Entity findByItemId(Context context, UUID itemId) throws SQLException;
|
||||
|
||||
/**
|
||||
* This will construct an Entity object that will be returned with the Item that matches the ItemID that was
|
||||
* passed along
|
||||
* as well as a list of relationships for that Item.
|
||||
* @param context The relevant DSpace context
|
||||
* @param itemId The ItemID for the Item that is to be used in the Entity object
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The constructed Entity object with the Item and the list of relationships
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
Entity findByItemId(Context context, UUID itemId, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns the EntityType for the Item that is attached to the Entity that is passed along to this method.
|
||||
* The EntityType String logic is in the Metadata for that Item and will be searched on in the EntityTypeService
|
||||
@@ -69,12 +82,26 @@ public interface EntityService {
|
||||
* Retrieves the list of relationships for which their relationshiptype has a left or right label that is
|
||||
* equal to the passed along label String
|
||||
* @param context The relevant DSpace context
|
||||
* @param label The label that needs to be in the relationshiptype of the relationship
|
||||
* @param typeName The label that needs to be in the relationshiptype of the relationship
|
||||
* @return The list of relationships that have a relationshiptype with a left or right label
|
||||
* that is equal to the label param
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> getRelationsByLabel(Context context, String label) throws SQLException;
|
||||
List<Relationship> getRelationsByTypeName(Context context, String typeName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships for which their relationshiptype has a left or right label that is
|
||||
* equal to the passed along label String
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The label that needs to be in the relationshiptype of the relationship
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationships that have a relationshiptype with a left or right label
|
||||
* that is equal to the label param
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> getRelationsByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
@@ -89,6 +116,22 @@ public interface EntityService {
|
||||
*/
|
||||
List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
* Entity
|
||||
* in either the leftEntityType or the rightEntityType variables
|
||||
* @param context The relevant DSpace context
|
||||
* @param entity The Entity for which the EntityType should be checked for relationships
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationships that each contain a relationshiptype in which there is a right or left
|
||||
* entity type that
|
||||
* is equal to the entity type for the given entity
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> getAllRelationshipTypes(Context context, Entity entity, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
* Entity
|
||||
@@ -101,6 +144,23 @@ public interface EntityService {
|
||||
*/
|
||||
List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
* Entity
|
||||
* in the leftEntityType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entity The Entity for which the EntityType should be checked for relationships
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationships that each contain a relationshiptype in which there is a left entity type that
|
||||
* is equal to the entity type for the given entity
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> getLeftRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
* Entity
|
||||
@@ -113,15 +173,46 @@ public interface EntityService {
|
||||
*/
|
||||
List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of relationships that have a relationshiptype that contains the EntityType for the given
|
||||
* Entity
|
||||
* in the rightEntityType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entity The Entity for which the EntityType should be checked for relationships
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationships that each contain a relationshiptype in which there is a right entity type that
|
||||
* is equal to the entity type for the given entity
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> getRightRelationshipTypes(Context context, Entity entity, boolean isLeft,
|
||||
Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves a list of RelationshipType objects for which either their left or right label is equal to the
|
||||
* label parameter that's being passed along
|
||||
* @param context The relevant DSpace context
|
||||
* @param label The label for which the relationshiptype's labels must be checked
|
||||
* @param typeName The typeName for which the relationshiptype's labels must be checked
|
||||
* @return The list of relationshiptypes that each contain a left or right label that is equal
|
||||
* to the given label parameter
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> getRelationshipTypesByLabel(Context context, String label) throws SQLException;
|
||||
List<RelationshipType> getRelationshipTypesByTypeName(Context context, String typeName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves a list of RelationshipType objects for which either their left or right label is equal to the
|
||||
* label parameter that's being passed along
|
||||
* @param context The relevant DSpace context
|
||||
* @param type The label for which the relationshiptype's labels must be checked
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationshiptypes that each contain a left or right label that is equal
|
||||
* to the given label parameter
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> getRelationshipTypesByTypeName(Context context, String type,
|
||||
Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
}
|
||||
|
@@ -37,6 +37,16 @@ public interface EntityTypeService extends DSpaceCRUDService<EntityType> {
|
||||
*/
|
||||
public List<EntityType> findAll(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves all the EntityType objects currently in the system
|
||||
* @param context The relevant DSpace context
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return A list of all EntityType objects
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<EntityType> findAll(Context context, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method creates an EntityType object in the database with the given entityTypeString as it's label
|
||||
* @param context The relevant DSpace context
|
||||
|
@@ -24,10 +24,8 @@ import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.RelationshipMetadataValue;
|
||||
import org.dspace.content.Thumbnail;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.virtual.VirtualMetadataPopulator;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
@@ -40,7 +38,7 @@ import org.dspace.eperson.Group;
|
||||
* @author kevinvandevelde at atmire.com
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -205,7 +203,7 @@ public interface ItemService
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
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.
|
||||
@@ -677,19 +675,6 @@ public interface ItemService
|
||||
*/
|
||||
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.
|
||||
* See <code>MetadataSchema</code> for more information about schemas.
|
||||
|
@@ -30,7 +30,19 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
* @return The list of relationships for which each relationship adheres to the above listed constraint
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Relationship> findByItem(Context context,Item item) throws SQLException;
|
||||
public List<Relationship> findByItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the list of Relationships currently in the system for which the given Item is either
|
||||
* a leftItem or a rightItem object
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The Item that has to be the left or right item for the relationship to be included in the list
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of relationships for which each relationship adheres to the above listed constraint
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the full list of relationships currently in the system
|
||||
@@ -40,6 +52,16 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
*/
|
||||
public List<Relationship> findAll(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the full list of relationships currently in the system
|
||||
* @param context The relevant DSpace context
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of all relationships currently in the system
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findAll(Context context, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method creates a relationship object in the database equal to the given relationship param
|
||||
* if this is a valid relationship
|
||||
@@ -52,26 +74,26 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
public Relationship create(Context context, Relationship relationship) throws SQLException, AuthorizeException;
|
||||
|
||||
/**
|
||||
* Retrieves the highest integer value for the leftplace property of a Relationship for all relationships
|
||||
* that have the given item as a left item
|
||||
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem
|
||||
*
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item that has to be the leftItem of a relationship for it to qualify
|
||||
* @return The integer value of the highest left place property of all relationships
|
||||
* that have the given item as a leftitem property
|
||||
* @return The next integer to be used for the leftplace of a relationship with the given item
|
||||
* as a left item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
|
||||
int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the highest integer value for the rightplace property of a Relationship for all relationships
|
||||
* that have the given item as a right item
|
||||
* This method returns the next rightplace integer to use for a relationship with this item as the rightItem
|
||||
*
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item that has to be the rightitem of a relationship for it to qualify
|
||||
* @return The integer value of the highest right place property of all relationships
|
||||
* that have the given item as a rightitem property
|
||||
* @return The next integer to be used for the rightplace of a relationship with the given item
|
||||
* as a right item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int findRightPlaceByRightItem(Context context, Item item) throws SQLException;
|
||||
int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationships for which the leftItem or rightItem is equal to the given
|
||||
@@ -87,18 +109,47 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
RelationshipType relationshipType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationships for which the leftItem or rightItem is equal to the given
|
||||
* Item object and for which the RelationshipType object is equal to the relationshipType property
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The Item object to be matched on the leftItem or rightItem for the relationship
|
||||
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
||||
* @return The list of Relationship objects that have the given Item object as leftItem or rightItem and
|
||||
* for which the relationshipType property is equal to the given RelationshipType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, int limit, int offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationships for which the leftItem or rightItem is equal to the given
|
||||
* Item object and for which the RelationshipType object is equal to the relationshipType property
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The Item object to be matched on the leftItem or rightItem for the relationship
|
||||
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
||||
* @param isLeft Is the item left or right
|
||||
* @return The list of Relationship objects that have the given Item object as leftItem or rightItem and
|
||||
* for which the relationshipType property is equal to the given RelationshipType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
|
||||
RelationshipType relationshipType, boolean isLeft,
|
||||
int limit, int offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* by the leftItem, rightItem and relationshipType of the given Relationship.
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationship The Relationship object that will have it's place updated and that will be used
|
||||
* to retrieve the other relationships whose place might need to be updated
|
||||
* @param isCreation Is the relationship new or did it already exist
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void updatePlaceInRelationship(Context context, Relationship relationship, boolean isCreation)
|
||||
public void updatePlaceInRelationship(Context context, Relationship relationship)
|
||||
throws SQLException, AuthorizeException;
|
||||
|
||||
/**
|
||||
@@ -116,7 +167,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
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
||||
@@ -126,6 +177,20 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
*/
|
||||
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objets for which the relationshipType property is equal to the given
|
||||
* RelationshipType object
|
||||
* @param context The relevant DSpace context
|
||||
* @param relationshipType The RelationshipType object that will be used to check the Relationship on
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of Relationship objects for which the given RelationshipType object is equal
|
||||
* to the relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType, Integer limit,
|
||||
Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method is used to construct a Relationship object with all it's variables
|
||||
* @param c The relevant DSpace context
|
||||
@@ -134,6 +199,26 @@ public interface RelationshipService extends DSpaceCRUDService<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
|
||||
* @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
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
* @throws SQLException If something goes wrong
|
||||
@@ -141,4 +226,82 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
|
||||
Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
|
||||
int leftPlace, int rightPlace)
|
||||
throws AuthorizeException, SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given typeName
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The leftward or rightward typeName of the relationship type
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByTypeName(Context context, String typeName) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a list of Relationship objects for the given typeName
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The leftward or rightward typeName of the relationship type
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return A list of Relationship objects that have the given RelationshipType object as the
|
||||
* relationshipType property
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* counts all relationships
|
||||
*
|
||||
* @param context DSpace context object
|
||||
* @return total relationships
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countTotal(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table) by a relationship type
|
||||
*
|
||||
* @param context context
|
||||
* @param relationshipType relationship type to filter by
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByRelationshipType(Context context, RelationshipType relationshipType) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method returns a count of Relationship objects that have the given Item object
|
||||
* as a leftItem or a rightItem
|
||||
* @param context The relevant DSpace context
|
||||
* @param item The item that should be either a leftItem or a rightItem of all
|
||||
* the Relationship objects in the returned list
|
||||
* @return The list of Relationship objects that contain either a left or a
|
||||
* right item that is equal to the given item
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int countByItem(Context context, Item item) throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table) by a relationship type
|
||||
*
|
||||
* @param context context
|
||||
* @param relationshipType relationship type to filter by
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Count total number of relationships (rows in relationship table)
|
||||
* by a relationship leftward or rightward typeName
|
||||
*
|
||||
* @param context context
|
||||
* @param typeName typeName of relationship
|
||||
* @return total count
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
int countByTypeName(Context context, String typeName)
|
||||
throws SQLException;
|
||||
}
|
@@ -29,20 +29,20 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong with authorizations
|
||||
*/
|
||||
RelationshipType create(Context context,RelationshipType relationshipType) throws SQLException, AuthorizeException;
|
||||
RelationshipType create(Context context, RelationshipType relationshipType) throws SQLException, AuthorizeException;
|
||||
|
||||
/**
|
||||
* Retrieves a RelationshipType for which the given parameters all match the one in the returned RelationshipType
|
||||
* @param context The relevant DSpace context
|
||||
* @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 leftLabel The leftLabel String that needs to match for the returned RelationshipType
|
||||
* @param rightLabel The rightLabel String that needs to match for the returned RelationshipType
|
||||
* @param leftwardType The leftwardType String that needs to match for the returned RelationshipType
|
||||
* @param rightwardType The rightwardType String that needs to match for the returned RelationshipType
|
||||
* @return
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
RelationshipType findbyTypesAndLabels(Context context,EntityType leftType,EntityType rightType,
|
||||
String leftLabel,String rightLabel)
|
||||
RelationshipType findbyTypesAndTypeName(Context context, EntityType leftType, EntityType rightType,
|
||||
String leftwardType, String rightwardType)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
@@ -54,15 +54,40 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
||||
List<RelationshipType> findAll(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves all RelationshipType objects that have a left or right label that is
|
||||
* Retrieves all RelationshipType objects currently in the system
|
||||
* @param context The relevant DSpace context
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of all RelationshipType objects currently in the system
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findAll(Context context, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves all RelationshipType objects that have a left or right type that is
|
||||
* equal to the given String
|
||||
* @param context The relevant DSpace context
|
||||
* @param label The label that has to match
|
||||
* @param typeName The label that has to match
|
||||
* @return The list of all RelationshipType objects that have a left or right label
|
||||
* that is equal to the given label param
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByLeftOrRightLabel(Context context, String label) throws SQLException;
|
||||
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves all RelationshipType objects that have a left or right label that is
|
||||
* equal to the given String
|
||||
* @param context The relevant DSpace context
|
||||
* @param typeName The typeName that has to match
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of all RelationshipType objects that have a left or right label
|
||||
* that is equal to the given label param
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByLeftwardOrRightwardTypeName(Context context, String typeName, Integer limit,
|
||||
Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a list of RelationshipType objects for which the given EntityType is equal to either the leftType
|
||||
@@ -75,13 +100,48 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType) throws SQLException;
|
||||
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
* to the leftType or rightType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entityType The EntityType object that will be used to check on
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @return The list of RelationshipType objects that have the given EntityType object
|
||||
* as either a leftType or rightType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* This method will return a list of RelationshipType objects for which the given EntityType object is equal
|
||||
* to the leftType or rightType
|
||||
* @param context The relevant DSpace context
|
||||
* @param entityType The EntityType object that will be used to check on
|
||||
* @param isLeft Boolean value used to filter by left_type or right_type. If true left_type results only
|
||||
* else right_type results.
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return The list of RelationshipType objects that have the given EntityType object
|
||||
* as either a leftType or rightType
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
List<RelationshipType> findByEntityType(Context context, EntityType entityType, boolean isLeft,
|
||||
Integer limit, Integer offset)
|
||||
throws SQLException;
|
||||
/**
|
||||
* This method will support the creation of a RelationshipType object with the given parameters
|
||||
* @param context The relevant DSpace context
|
||||
* @param leftEntityType The leftEntityType EntityType object for this relationshipType
|
||||
* @param rightEntityType The rightEntityType EntityType object for this relationshipType
|
||||
* @param leftLabel The leftLabel String object for this relationshipType
|
||||
* @param rightLabel The rightLabel String object for this relationshipType
|
||||
* @param leftwardType The leftwardType String object for this relationshipType
|
||||
* @param rightwardType The rightwardType String object for this relationshipType
|
||||
* @param leftCardinalityMinInteger The leftCardinalityMinInteger Integer object for this relationshipType
|
||||
* @param leftCardinalityMaxInteger The leftCardinalityMaxInteger Integer object for this relationshipType
|
||||
* @param rightCardinalityMinInteger The rightCardinalityMinInteger Integer object for this relationshipType
|
||||
@@ -90,8 +150,9 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
|
||||
* @throws SQLException If something goes wrong
|
||||
* @throws AuthorizeException If something goes wrong
|
||||
*/
|
||||
RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType, String leftLabel,
|
||||
String rightLabel, Integer leftCardinalityMinInteger, Integer leftCardinalityMaxInteger,
|
||||
Integer rightCardinalityMinInteger, Integer rightCardinalityMaxInteger)
|
||||
RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
|
||||
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
|
||||
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
|
||||
Integer rightCardinalityMaxInteger)
|
||||
throws SQLException, AuthorizeException;
|
||||
}
|
||||
|
@@ -65,6 +65,7 @@ public class Collected implements VirtualMetadataConfiguration {
|
||||
* Generic setter for the useForPlace property
|
||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||
*/
|
||||
@Override
|
||||
public void setUseForPlace(boolean useForPlace) {
|
||||
this.useForPlace = useForPlace;
|
||||
}
|
||||
@@ -73,10 +74,19 @@ public class Collected implements VirtualMetadataConfiguration {
|
||||
* Generic getter for the useForPlace property
|
||||
* @return The useForPlace to be used by this bean
|
||||
*/
|
||||
@Override
|
||||
public boolean getUseForPlace() {
|
||||
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
|
||||
* 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 populateWithNameVariant = false;
|
||||
/**
|
||||
* Generic getter for the fields property
|
||||
* @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
|
||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||
*/
|
||||
@Override
|
||||
public void setUseForPlace(boolean useForPlace) {
|
||||
this.useForPlace = useForPlace;
|
||||
}
|
||||
@@ -88,10 +90,21 @@ public class Concatenate implements VirtualMetadataConfiguration {
|
||||
* Generic getter for the useForPlace property
|
||||
* @return The useForPlace to be used by this bean
|
||||
*/
|
||||
@Override
|
||||
public boolean getUseForPlace() {
|
||||
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
|
||||
* 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
|
||||
* @return The String value for all of the retrieved metadatavalues combined with the separator
|
||||
*/
|
||||
@Override
|
||||
public List<String> getValues(Context context, Item item) {
|
||||
|
||||
List<String> resultValues = new LinkedList<>();
|
||||
|
@@ -120,6 +120,7 @@ public class Related implements VirtualMetadataConfiguration {
|
||||
* Generic setter for the useForPlace property
|
||||
* @param useForPlace The boolean value that the useForPlace property will be set to
|
||||
*/
|
||||
@Override
|
||||
public void setUseForPlace(boolean useForPlace) {
|
||||
this.useForPlace = useForPlace;
|
||||
}
|
||||
@@ -128,10 +129,19 @@ public class Related implements VirtualMetadataConfiguration {
|
||||
* Generic getter for the useForPlace property
|
||||
* @return The useForPlace to be used by this bean
|
||||
*/
|
||||
@Override
|
||||
public boolean getUseForPlace() {
|
||||
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
|
||||
* 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
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
@Override
|
||||
public List<String> getValues(Context context, Item item) throws SQLException {
|
||||
Entity entity = entityService.findByItemId(context, item.getID());
|
||||
EntityType entityType = entityService.getType(context, entity);
|
||||
@@ -149,8 +160,8 @@ public class Related implements VirtualMetadataConfiguration {
|
||||
List<RelationshipType> relationshipTypes = entityService.getAllRelationshipTypes(context, entity);
|
||||
List<RelationshipType> possibleRelationshipTypes = new LinkedList<>();
|
||||
for (RelationshipType relationshipType : relationshipTypes) {
|
||||
if (StringUtils.equals(relationshipType.getLeftLabel(), relationshipTypeString) || StringUtils
|
||||
.equals(relationshipType.getRightLabel(), relationshipTypeString)) {
|
||||
if (StringUtils.equals(relationshipType.getLeftwardType(), relationshipTypeString) || StringUtils
|
||||
.equals(relationshipType.getRightwardType(), relationshipTypeString)) {
|
||||
possibleRelationshipTypes.add(relationshipType);
|
||||
}
|
||||
}
|
||||
|
@@ -38,4 +38,12 @@ public class UUIDValue implements VirtualMetadataConfiguration {
|
||||
public boolean getUseForPlace() {
|
||||
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
|
||||
*/
|
||||
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
|
||||
* 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 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
|
||||
*/
|
||||
public boolean isUseForPlaceTrueForRelationshipType(RelationshipType relationshipType, boolean isLeft) {
|
||||
HashMap<String, VirtualMetadataConfiguration> hashMaps;
|
||||
if (isLeft) {
|
||||
hashMaps = this.getMap().get(relationshipType.getLeftLabel());
|
||||
hashMaps = this.getMap().get(relationshipType.getLeftwardType());
|
||||
} else {
|
||||
hashMaps = this.getMap().get(relationshipType.getRightLabel());
|
||||
hashMaps = this.getMap().get(relationshipType.getRightwardType());
|
||||
}
|
||||
if (hashMaps != null) {
|
||||
for (Map.Entry<String, VirtualMetadataConfiguration> entry : hashMaps.entrySet()) {
|
||||
|
@@ -66,10 +66,16 @@ public abstract class AbstractHibernateDAO<T> implements GenericDAO<T> {
|
||||
|
||||
@Override
|
||||
public List<T> findAll(Context context, Class<T> clazz) throws SQLException {
|
||||
|
||||
return findAll(context, clazz, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> findAll(Context context, Class<T> clazz, Integer limit, Integer offset) throws SQLException {
|
||||
CriteriaQuery criteriaQuery = getCriteriaQuery(getCriteriaBuilder(context), clazz);
|
||||
Root<T> root = criteriaQuery.from(clazz);
|
||||
criteriaQuery.select(root);
|
||||
return executeCriteriaQuery(context, criteriaQuery, false, -1, -1);
|
||||
return executeCriteriaQuery(context, criteriaQuery, false, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -58,6 +58,18 @@ public interface GenericDAO<T> {
|
||||
*/
|
||||
public List<T> findAll(Context context, Class<T> clazz) throws SQLException;
|
||||
|
||||
/**
|
||||
* Fetch all persisted instances of a given object type.
|
||||
*
|
||||
* @param context The relevant DSpace Context.
|
||||
* @param clazz the desired type.
|
||||
* @param limit paging limit
|
||||
* @param offset paging offset
|
||||
* @return list of DAOs of the same type as clazz
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
List<T> findAll(Context context, Class<T> clazz, Integer limit, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Execute a JPQL query returning a unique result.
|
||||
*
|
||||
|
@@ -360,6 +360,11 @@ public class LegacyPluginServiceImpl implements PluginService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNamedPluginClasses() {
|
||||
namedPluginClasses.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a plugin exists which implements the specified interface
|
||||
* and has a specified name. If a matching plugin is found to be configured,
|
||||
|
@@ -84,4 +84,9 @@ public interface PluginService {
|
||||
* @return instance of plugin
|
||||
*/
|
||||
public Object getSinglePlugin(Class interfaceClass);
|
||||
|
||||
/**
|
||||
* This method has been created to have a way of clearing the cache kept in the PluginService
|
||||
*/
|
||||
public void clearNamedPluginClasses();
|
||||
}
|
||||
|
@@ -13,11 +13,8 @@ import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
@@ -26,103 +23,26 @@ import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Class used to reindex dspace communities/collections/items into discovery
|
||||
*
|
||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||
* @author Mark Diggory (markd at atmire dot com)
|
||||
* @author Ben Bosman (ben at atmire dot com)
|
||||
*/
|
||||
public class IndexClient {
|
||||
public class IndexClient extends DSpaceRunnable {
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(IndexClient.class);
|
||||
private Context context;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
private IndexClient() { }
|
||||
@Autowired
|
||||
private IndexingService indexer;
|
||||
|
||||
/**
|
||||
* When invoked as a command-line tool, creates, updates, removes content
|
||||
* from the whole index
|
||||
*
|
||||
* @param args the command-line arguments, none used
|
||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
||||
* @throws SearchServiceException if something went wrong with querying the solr server
|
||||
*/
|
||||
public static void main(String[] args) throws SQLException, IOException, SearchServiceException {
|
||||
private IndexClientOptions indexClientOptions;
|
||||
|
||||
Context context = new Context(Context.Mode.READ_ONLY);
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
String usage = "org.dspace.discovery.IndexClient [-cbhf] | [-r <handle>] | [-i <handle>] or nothing to " +
|
||||
"update/clean an existing index.";
|
||||
Options options = new Options();
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
CommandLine line = null;
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.withArgName("handle to remove")
|
||||
.hasArg(true)
|
||||
.withDescription(
|
||||
"remove an Item, Collection or Community from index based on its handle")
|
||||
.create("r"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.withArgName("handle or uuid to add or update")
|
||||
.hasArg(true)
|
||||
.withDescription(
|
||||
"add or update an Item, Collection or Community based on its handle or uuid")
|
||||
.create("i"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.isRequired(false)
|
||||
.withDescription(
|
||||
"clean existing index removing any documents that no longer exist in the db")
|
||||
.create("c"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.isRequired(false)
|
||||
.withDescription(
|
||||
"(re)build index, wiping out current one if it exists")
|
||||
.create("b"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.isRequired(false)
|
||||
.withDescription(
|
||||
"Rebuild the spellchecker, can be combined with -b and -f.")
|
||||
.create("s"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.isRequired(false)
|
||||
.withDescription(
|
||||
"if updating existing index, force each handle to be reindexed even if uptodate")
|
||||
.create("f"));
|
||||
|
||||
options.addOption(OptionBuilder
|
||||
.isRequired(false)
|
||||
.withDescription(
|
||||
"print this help message")
|
||||
.create("h"));
|
||||
|
||||
options.addOption(OptionBuilder.isRequired(false).withDescription(
|
||||
"optimize search core").create("o"));
|
||||
|
||||
try {
|
||||
line = new PosixParser().parse(options, args);
|
||||
} catch (Exception e) {
|
||||
// automatically generate the help statement
|
||||
formatter.printHelp(usage, e.getMessage(), options, "");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (line.hasOption("h")) {
|
||||
// automatically generate the help statement
|
||||
formatter.printHelp(usage, options);
|
||||
System.exit(1);
|
||||
@Override
|
||||
public void internalRun() throws Exception {
|
||||
if (indexClientOptions == IndexClientOptions.HELP) {
|
||||
printHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
/** Acquire from dspace-services in future */
|
||||
@@ -130,28 +50,29 @@ public class IndexClient {
|
||||
* new DSpace.getServiceManager().getServiceByName("org.dspace.discovery.SolrIndexer");
|
||||
*/
|
||||
|
||||
IndexingService indexer = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(
|
||||
IndexingService.class.getName(),
|
||||
IndexingService.class
|
||||
);
|
||||
|
||||
if (line.hasOption("r")) {
|
||||
log.info("Removing " + line.getOptionValue("r") + " from Index");
|
||||
indexer.unIndexContent(context, line.getOptionValue("r"));
|
||||
} else if (line.hasOption("c")) {
|
||||
log.info("Cleaning Index");
|
||||
indexer.cleanIndex(line.hasOption("f"));
|
||||
} else if (line.hasOption("b")) {
|
||||
log.info("(Re)building index from scratch.");
|
||||
if (indexClientOptions == IndexClientOptions.REMOVE) {
|
||||
handler.logInfo("Removing " + commandLine.getOptionValue("r") + " from Index");
|
||||
indexer.unIndexContent(context, commandLine.getOptionValue("r"));
|
||||
} else if (indexClientOptions == IndexClientOptions.CLEAN) {
|
||||
handler.logInfo("Cleaning Index");
|
||||
indexer.cleanIndex(false);
|
||||
} else if (indexClientOptions == IndexClientOptions.FORCECLEAN) {
|
||||
handler.logInfo("Cleaning Index");
|
||||
indexer.cleanIndex(true);
|
||||
} else if (indexClientOptions == IndexClientOptions.BUILD ||
|
||||
indexClientOptions == IndexClientOptions.BUILDANDSPELLCHECK) {
|
||||
handler.logInfo("(Re)building index from scratch.");
|
||||
indexer.createIndex(context);
|
||||
checkRebuildSpellCheck(line, indexer);
|
||||
} else if (line.hasOption("o")) {
|
||||
log.info("Optimizing search core.");
|
||||
if (indexClientOptions == IndexClientOptions.BUILDANDSPELLCHECK) {
|
||||
checkRebuildSpellCheck(commandLine, indexer);
|
||||
}
|
||||
} else if (indexClientOptions == IndexClientOptions.OPTIMIZE) {
|
||||
handler.logInfo("Optimizing search core.");
|
||||
indexer.optimize();
|
||||
} else if (line.hasOption('s')) {
|
||||
checkRebuildSpellCheck(line, indexer);
|
||||
} else if (line.hasOption('i')) {
|
||||
final String param = line.getOptionValue('i');
|
||||
} else if (indexClientOptions == IndexClientOptions.SPELLCHECK) {
|
||||
checkRebuildSpellCheck(commandLine, indexer);
|
||||
} else if (indexClientOptions == IndexClientOptions.INDEX) {
|
||||
final String param = commandLine.getOptionValue('i');
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(param);
|
||||
@@ -171,24 +92,55 @@ public class IndexClient {
|
||||
}
|
||||
} else {
|
||||
dso = (IndexableObject) HandleServiceFactory.getInstance()
|
||||
.getHandleService().resolveToObject(context, param);
|
||||
.getHandleService().resolveToObject(context, param);
|
||||
}
|
||||
if (dso == null) {
|
||||
throw new IllegalArgumentException("Cannot resolve " + param + " to a DSpace object");
|
||||
}
|
||||
log.info("Indexing " + param + " force " + line.hasOption("f"));
|
||||
handler.logInfo("Indexing " + param + " force " + commandLine.hasOption("f"));
|
||||
final long startTimeMillis = System.currentTimeMillis();
|
||||
final long count = indexAll(indexer, ContentServiceFactory.getInstance().getItemService(), context, dso);
|
||||
final long count = indexAll(indexer, ContentServiceFactory.getInstance().getItemService(), context,
|
||||
dso);
|
||||
final long seconds = (System.currentTimeMillis() - startTimeMillis) / 1000;
|
||||
log.info("Indexed " + count + " object" + (count > 1 ? "s" : "") + " in " + seconds + " seconds");
|
||||
} else {
|
||||
log.info("Updating and Cleaning Index");
|
||||
indexer.cleanIndex(line.hasOption("f"));
|
||||
indexer.updateIndex(context, line.hasOption("f"));
|
||||
checkRebuildSpellCheck(line, indexer);
|
||||
handler.logInfo("Indexed " + count + " object" + (count > 1 ? "s" : "") + " in " + seconds + " seconds");
|
||||
} else if (indexClientOptions == IndexClientOptions.UPDATE ||
|
||||
indexClientOptions == IndexClientOptions.UPDATEANDSPELLCHECK) {
|
||||
handler.logInfo("Updating and Cleaning Index");
|
||||
indexer.cleanIndex(false);
|
||||
indexer.updateIndex(context, false);
|
||||
if (indexClientOptions == IndexClientOptions.UPDATEANDSPELLCHECK) {
|
||||
checkRebuildSpellCheck(commandLine, indexer);
|
||||
}
|
||||
} else if (indexClientOptions == IndexClientOptions.FORCEUPDATE ||
|
||||
indexClientOptions == IndexClientOptions.FORCEUPDATEANDSPELLCHECK) {
|
||||
handler.logInfo("Updating and Cleaning Index");
|
||||
indexer.cleanIndex(true);
|
||||
indexer.updateIndex(context, true);
|
||||
if (indexClientOptions == IndexClientOptions.FORCEUPDATEANDSPELLCHECK) {
|
||||
checkRebuildSpellCheck(commandLine, indexer);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Done with indexing");
|
||||
handler.logInfo("Done with indexing");
|
||||
}
|
||||
|
||||
public void setup() throws ParseException {
|
||||
try {
|
||||
context = new Context(Context.Mode.READ_ONLY);
|
||||
context.turnOffAuthorisationSystem();
|
||||
} catch (Exception e) {
|
||||
throw new ParseException("Unable to create a new DSpace Context: " + e.getMessage());
|
||||
}
|
||||
|
||||
indexClientOptions = IndexClientOptions.getIndexClientOption(commandLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for this class. This will ensure that the Options are created and set appropriately.
|
||||
*/
|
||||
private IndexClient() {
|
||||
Options options = IndexClientOptions.constructOptions();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,13 +225,12 @@ public class IndexClient {
|
||||
* @param line the command line options
|
||||
* @param indexer the solr indexer
|
||||
* @throws SearchServiceException in case of a solr exception
|
||||
* @throws java.io.IOException passed through
|
||||
* @throws IOException passed through
|
||||
*/
|
||||
protected static void checkRebuildSpellCheck(CommandLine line, IndexingService indexer)
|
||||
protected void checkRebuildSpellCheck(CommandLine line, IndexingService indexer)
|
||||
throws SearchServiceException, IOException {
|
||||
if (line.hasOption("s")) {
|
||||
log.info("Rebuilding spell checker.");
|
||||
indexer.buildSpellCheck();
|
||||
}
|
||||
handler.logInfo("Rebuilding spell checker.");
|
||||
indexer.buildSpellCheck();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.discovery;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Options;
|
||||
|
||||
/**
|
||||
* This Enum holds all the possible options and combinations for the Index discovery script
|
||||
*/
|
||||
public enum IndexClientOptions {
|
||||
REMOVE,
|
||||
CLEAN,
|
||||
FORCECLEAN,
|
||||
BUILD,
|
||||
BUILDANDSPELLCHECK,
|
||||
OPTIMIZE,
|
||||
SPELLCHECK,
|
||||
INDEX,
|
||||
UPDATE,
|
||||
FORCEUPDATE,
|
||||
UPDATEANDSPELLCHECK,
|
||||
FORCEUPDATEANDSPELLCHECK,
|
||||
HELP;
|
||||
|
||||
/**
|
||||
* This method resolves the CommandLine parameters to figure out which action the index-discovery script should
|
||||
* perform
|
||||
* @param commandLine The relevant CommandLine for the index-discovery script
|
||||
* @return The index-discovery option to be ran, parsed from the CommandLine
|
||||
*/
|
||||
protected static IndexClientOptions getIndexClientOption(CommandLine commandLine) {
|
||||
if (commandLine.hasOption("h")) {
|
||||
return IndexClientOptions.HELP;
|
||||
} else if (commandLine.hasOption("r")) {
|
||||
return IndexClientOptions.REMOVE;
|
||||
} else if (commandLine.hasOption("c")) {
|
||||
if (commandLine.hasOption("f")) {
|
||||
return IndexClientOptions.FORCECLEAN;
|
||||
} else {
|
||||
return IndexClientOptions.CLEAN;
|
||||
}
|
||||
} else if (commandLine.hasOption("b")) {
|
||||
if (commandLine.hasOption("s")) {
|
||||
return IndexClientOptions.BUILDANDSPELLCHECK;
|
||||
} else {
|
||||
return IndexClientOptions.BUILD;
|
||||
}
|
||||
} else if (commandLine.hasOption("o")) {
|
||||
return IndexClientOptions.OPTIMIZE;
|
||||
} else if (commandLine.hasOption("s")) {
|
||||
return IndexClientOptions.SPELLCHECK;
|
||||
} else if (commandLine.hasOption("i")) {
|
||||
return IndexClientOptions.INDEX;
|
||||
} else {
|
||||
if (commandLine.hasOption("f") && commandLine.hasOption("s")) {
|
||||
return IndexClientOptions.FORCEUPDATEANDSPELLCHECK;
|
||||
} else if (commandLine.hasOption("f")) {
|
||||
return IndexClientOptions.FORCEUPDATE;
|
||||
} else if (commandLine.hasOption("s")) {
|
||||
return IndexClientOptions.UPDATEANDSPELLCHECK;
|
||||
} else {
|
||||
return IndexClientOptions.UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static Options constructOptions() {
|
||||
Options options = new Options();
|
||||
|
||||
options
|
||||
.addOption("r", "remove", true, "remove an Item, Collection or Community from index based on its handle");
|
||||
options.getOption("r").setType(String.class);
|
||||
options.addOption("i", "index", true,
|
||||
"add or update an Item, Collection or Community based on its handle or uuid");
|
||||
options.getOption("i").setType(boolean.class);
|
||||
options.addOption("c", "clean", false,
|
||||
"clean existing index removing any documents that no longer exist in the db");
|
||||
options.getOption("c").setType(boolean.class);
|
||||
options.addOption("b", "build", false, "(re)build index, wiping out current one if it exists");
|
||||
options.getOption("b").setType(boolean.class);
|
||||
options.addOption("s", "spellchecker", false, "Rebuild the spellchecker, can be combined with -b and -f.");
|
||||
options.getOption("s").setType(boolean.class);
|
||||
options.addOption("f", "force", false,
|
||||
"if updating existing index, force each handle to be reindexed even if uptodate");
|
||||
options.getOption("f").setType(boolean.class);
|
||||
options.addOption("h", "help", false, "print this help message");
|
||||
options.getOption("h").setType(boolean.class);
|
||||
return options;
|
||||
}
|
||||
}
|
@@ -10,9 +10,9 @@ package org.dspace.discovery;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
@@ -140,26 +140,26 @@ public class SearchUtils {
|
||||
private static List<DiscoveryConfiguration> getAllDiscoveryConfigurations(String prefix,
|
||||
List<Collection> collections, Item item)
|
||||
throws SQLException {
|
||||
Map<String, DiscoveryConfiguration> result = new HashMap<String, DiscoveryConfiguration>();
|
||||
Set<DiscoveryConfiguration> result = new HashSet<>();
|
||||
|
||||
for (Collection collection : collections) {
|
||||
DiscoveryConfiguration configuration = getDiscoveryConfiguration(prefix, collection);
|
||||
if (!result.containsKey(configuration.getId())) {
|
||||
result.put(configuration.getId(), configuration);
|
||||
}
|
||||
result.add(configuration);
|
||||
}
|
||||
|
||||
//Add alwaysIndex configurations
|
||||
DiscoveryConfigurationService configurationService = getConfigurationService();
|
||||
result.addAll(configurationService.getIndexAlwaysConfigurations());
|
||||
|
||||
//Also add one for the default
|
||||
addConfigurationIfExists(result, prefix);
|
||||
|
||||
return Arrays.asList(result.values().toArray(new DiscoveryConfiguration[result.size()]));
|
||||
return Arrays.asList(result.toArray(new DiscoveryConfiguration[result.size()]));
|
||||
}
|
||||
|
||||
private static void addConfigurationIfExists(Map<String, DiscoveryConfiguration> result, String confName) {
|
||||
private static void addConfigurationIfExists(Set<DiscoveryConfiguration> result, String confName) {
|
||||
DiscoveryConfiguration configurationExtra = getDiscoveryConfigurationByName(confName);
|
||||
if (!result.containsKey(configurationExtra.getId())) {
|
||||
result.put(configurationExtra.getId(), configurationExtra);
|
||||
}
|
||||
result.add(configurationExtra);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -51,6 +51,22 @@ public class DiscoveryConfiguration implements InitializingBean {
|
||||
private DiscoveryHitHighlightingConfiguration hitHighlightingConfiguration;
|
||||
private DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration;
|
||||
private boolean spellCheckEnabled;
|
||||
private boolean indexAlways = false;
|
||||
|
||||
/**
|
||||
* The `indexAlways` property determines whether the configuration should always be included when indexing items.
|
||||
* The default value is false which implies the configuration is only used when it matches the collection or if
|
||||
* it's the default configuration
|
||||
* When set to true, the configuration is also used to index an item without a specific collection mapping
|
||||
* This can be used for displaying different facets depending on the type of item instead of the collection
|
||||
*/
|
||||
public boolean isIndexAlways() {
|
||||
return indexAlways;
|
||||
}
|
||||
|
||||
public void setIndexAlways(boolean indexAlways) {
|
||||
this.indexAlways = indexAlways;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
package org.dspace.discovery.configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -75,6 +76,22 @@ public class DiscoveryConfigurationService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of all DiscoveryConfiguration objects where
|
||||
* {@link org.dspace.discovery.configuration.DiscoveryConfiguration#isIndexAlways()} is true
|
||||
* These configurations should always be included when indexing
|
||||
*/
|
||||
public List<DiscoveryConfiguration> getIndexAlwaysConfigurations() {
|
||||
List<DiscoveryConfiguration> configs = new ArrayList<>();
|
||||
for (String key : map.keySet()) {
|
||||
DiscoveryConfiguration config = map.get(key);
|
||||
if (config.isIndexAlways()) {
|
||||
configs.add(config);
|
||||
}
|
||||
}
|
||||
return configs;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(DSpaceServicesFactory.getInstance().getServiceManager().getServicesNames().size());
|
||||
DiscoveryConfigurationService mainService = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||
|
@@ -13,11 +13,11 @@ import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.launcher.ScriptLauncher;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.MetadataValueService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexClient;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
@@ -139,7 +139,7 @@ public class UpdateHandlePrefix {
|
||||
|
||||
try {
|
||||
// Reinitialise the search and browse system
|
||||
IndexClient.main(new String[] {"-b"});
|
||||
ScriptLauncher.main(new String[] {"index-discovery", "-b"});
|
||||
System.out.println("Browse and search indexes are ready now.");
|
||||
// All done
|
||||
System.out.println("\nAll done successfully. Please check the DSpace logs!\n");
|
||||
|
@@ -7,16 +7,28 @@
|
||||
*/
|
||||
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.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
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.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.harvest.dao.HarvestedCollectionDAO;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -27,6 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
* @author kevinvandevelde at atmire.com
|
||||
*/
|
||||
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)
|
||||
protected HarvestedCollectionDAO harvestedCollectionDAO;
|
||||
|
||||
@@ -156,5 +172,94 @@ public class HarvestedCollectionServiceImpl implements HarvestedCollectionServic
|
||||
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.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
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.Identify;
|
||||
import ORG.oclc.oai.harvester2.verb.ListIdentifiers;
|
||||
import ORG.oclc.oai.harvester2.verb.ListMetadataFormats;
|
||||
import ORG.oclc.oai.harvester2.verb.ListRecords;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -102,7 +105,7 @@ public class OAIHarvester {
|
||||
protected BitstreamFormatService bitstreamFormatService;
|
||||
protected BundleService bundleService;
|
||||
protected CollectionService collectionService;
|
||||
protected HarvestedCollectionService harvestedCollection;
|
||||
protected HarvestedCollectionService harvestedCollectionService;
|
||||
protected InstallItemService installItemService;
|
||||
protected ItemService itemService;
|
||||
protected HandleService handleService;
|
||||
@@ -140,7 +143,7 @@ public class OAIHarvester {
|
||||
bundleService = ContentServiceFactory.getInstance().getBundleService();
|
||||
collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||
harvestedCollection = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
|
||||
harvestedCollectionService = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
|
||||
harvestedItemService = HarvestServiceFactory.getInstance().getHarvestedItemService();
|
||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
||||
installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||
@@ -150,7 +153,6 @@ public class OAIHarvester {
|
||||
|
||||
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
|
||||
|
||||
if (dso.getType() != Constants.COLLECTION) {
|
||||
throw new HarvestingException("OAIHarvester can only harvest collections");
|
||||
}
|
||||
@@ -159,7 +161,7 @@ public class OAIHarvester {
|
||||
targetCollection = (Collection) dso;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -188,7 +190,7 @@ public class OAIHarvester {
|
||||
*
|
||||
* @return Namespace of the supported ORE format. Returns null if not found.
|
||||
*/
|
||||
private static Namespace getORENamespace() {
|
||||
public static Namespace getORENamespace() {
|
||||
String ORESerializationString = null;
|
||||
String ORESeialKey = null;
|
||||
String oreString = "oai.harvester.oreSerializationFormat";
|
||||
@@ -213,7 +215,7 @@ public class OAIHarvester {
|
||||
* @param metadataKey
|
||||
* @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 metaString = "oai.harvester.metadataformats";
|
||||
|
||||
@@ -313,7 +315,7 @@ public class OAIHarvester {
|
||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_BUSY);
|
||||
harvestRow.setHarvestMessage("Collection harvesting is initializing...");
|
||||
harvestRow.setHarvestStartTime(startTime);
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
intermediateCommit();
|
||||
|
||||
// expiration timer starts
|
||||
@@ -354,7 +356,7 @@ public class OAIHarvester {
|
||||
harvestRow.setHarvestStartTime(new Date());
|
||||
harvestRow.setHarvestMessage("OAI server did not contain any updates");
|
||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
return;
|
||||
} else {
|
||||
throw new HarvestingException(errorSet.toString());
|
||||
@@ -411,7 +413,7 @@ public class OAIHarvester {
|
||||
harvestRow.setHarvestMessage(String
|
||||
.format("Collection is currently being harvested (item %d of %d)",
|
||||
currentRecord, totalListSize));
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
} finally {
|
||||
//In case of an exception, make sure to restore our authentication state to the previous state
|
||||
ourContext.restoreAuthSystemState();
|
||||
@@ -429,19 +431,19 @@ public class OAIHarvester {
|
||||
alertAdmin(HarvestedCollection.STATUS_OAI_ERROR, hex);
|
||||
}
|
||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_OAI_ERROR);
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
ourContext.complete();
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
harvestRow.setHarvestMessage("Unknown error occurred while generating an OAI response");
|
||||
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_UNKNOWN_ERROR);
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
alertAdmin(HarvestedCollection.STATUS_UNKNOWN_ERROR, ex);
|
||||
log.error("Error occurred while generating an OAI response: " + ex.getMessage() + " " + ex.getCause(), ex);
|
||||
ourContext.complete();
|
||||
return;
|
||||
} finally {
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
ourContext.turnOffAuthorisationSystem();
|
||||
collectionService.update(ourContext, targetCollection);
|
||||
ourContext.restoreAuthSystemState();
|
||||
@@ -456,7 +458,7 @@ public class OAIHarvester {
|
||||
log.info(
|
||||
"Harvest from " + oaiSource + " successful. The process took " + timeTaken + " milliseconds. Harvested "
|
||||
+ currentRecord + " items.");
|
||||
harvestedCollection.update(ourContext, harvestRow);
|
||||
harvestedCollectionService.update(ourContext, harvestRow);
|
||||
|
||||
ourContext.setMode(originalMode);
|
||||
}
|
||||
@@ -900,94 +902,44 @@ public class OAIHarvester {
|
||||
String oaiSetId = harvestRow.getOaiSetId();
|
||||
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
|
||||
* supporting the provided metadata formats.
|
||||
* Return all available 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.
|
||||
* @return a list containing a map for each supported metadata format
|
||||
*/
|
||||
public static List<String> verifyOAIharvester(String oaiSource,
|
||||
String oaiSetId, String metaPrefix, boolean testORE) {
|
||||
List<String> errorSet = new ArrayList<String>();
|
||||
public static List<Map<String,String>> getAvailableMetadataFormats() {
|
||||
List<Map<String,String>> configs = new ArrayList<>();
|
||||
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.
|
||||
try {
|
||||
new Identify(oaiSource);
|
||||
} catch (Exception ex) {
|
||||
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached.");
|
||||
return errorSet;
|
||||
}
|
||||
String id = key.substring(metaString.length());
|
||||
String label;
|
||||
String namespace = "";
|
||||
|
||||
// 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, 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");
|
||||
}
|
||||
}
|
||||
if (metadataString.indexOf(',') != -1) {
|
||||
label = metadataString.substring(metadataString.indexOf(',') + 2);
|
||||
namespace = metadataString.substring(0, metadataString.indexOf(','));
|
||||
} else {
|
||||
label = id + "(" + metadataString + ")";
|
||||
}
|
||||
} catch (RuntimeException re) {
|
||||
throw re;
|
||||
} catch (Exception e) {
|
||||
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached");
|
||||
return errorSet;
|
||||
|
||||
Map<String,String> config = new HashMap<>();
|
||||
config.put("id", id);
|
||||
config.put("label", label);
|
||||
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 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,108 @@
|
||||
/**
|
||||
* 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.scripts;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* This class serves as a representation of a command line parameter by holding a String name and a String value
|
||||
*/
|
||||
public class DSpaceCommandLineParameter {
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public static String SEPARATOR = "|||";
|
||||
|
||||
/**
|
||||
* This constructor will take a String key and String value and store them in their appriopriate fields
|
||||
* @param key The String value to be stored as the name of the parameter
|
||||
* @param value The String value to be stored as the value of the parameter
|
||||
*/
|
||||
public DSpaceCommandLineParameter(String key, String value) {
|
||||
this.name = key;
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
this.value = null;
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructors accepts a single parameter String that is defined as e.g. "-c test" and it'll parse this
|
||||
* String into the key "-c" and value "test" to then call the other constructor with those parameters
|
||||
* @param parameter The String parameter
|
||||
*/
|
||||
protected DSpaceCommandLineParameter(String parameter) {
|
||||
this(StringUtils.substringBefore(parameter, " "), StringUtils.substringAfter(parameter, " "));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String key) {
|
||||
this.name = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the DSpaceCommandLineParameter into a String format by concatenating the value and the name String
|
||||
* values by separating them with a space
|
||||
* @return The String representation of a DSpaceCommandlineParameter object
|
||||
*/
|
||||
public String toString() {
|
||||
String stringToReturn = "";
|
||||
stringToReturn += getName();
|
||||
if (StringUtils.isNotBlank(getValue())) {
|
||||
stringToReturn += " ";
|
||||
stringToReturn += getValue();
|
||||
}
|
||||
return stringToReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will convert a list of DSpaceCommandLineParameter objects into a single String. This is done by
|
||||
* calling the toString() method on each of the DSpaceCommandLineParameter objects in the list and concatenating
|
||||
* them with the Separator defined in this class
|
||||
* @param parameterList The list of DSpaceCommandLineParameter objects to be converted into a String
|
||||
* @return The resulting String
|
||||
*/
|
||||
public static String concatenate(List<DSpaceCommandLineParameter> parameterList) {
|
||||
if (parameterList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return parameterList.stream().map(parameter -> parameter.toString()).collect(Collectors.joining(SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return a boolean indicating whether the given param is equal to this object
|
||||
* @param other The other object
|
||||
* @return A boolean indicating equality
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (other.getClass() != DSpaceCommandLineParameter.class) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.equals(this.getName(), ((DSpaceCommandLineParameter) other).getName()) && StringUtils
|
||||
.equals(this.getValue(), ((DSpaceCommandLineParameter) other).getValue());
|
||||
}
|
||||
}
|
156
dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java
Normal file
156
dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* 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.scripts;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* This abstract class is the class that should be extended by each script.
|
||||
* it provides the basic variables to be hold by the script as well as the means to initialize, parse and run the script
|
||||
* Every DSpaceRunnable that is implemented in this way should be defined in the scripts.xml config file as a bean
|
||||
*/
|
||||
public abstract class DSpaceRunnable implements Runnable {
|
||||
|
||||
/**
|
||||
* The name of the script
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* The description of the script
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* The CommandLine object for the script that'll hold the information
|
||||
*/
|
||||
protected CommandLine commandLine;
|
||||
/**
|
||||
* The possible options for this script
|
||||
*/
|
||||
protected Options options;
|
||||
/**
|
||||
* The handler that deals with this script. This handler can currently either be a RestDSpaceRunnableHandler or
|
||||
* a CommandlineDSpaceRunnableHandler depending from where the script is called
|
||||
*/
|
||||
protected DSpaceRunnableHandler handler;
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Options getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will take the primitive array of String objects that represent the parameters given to the String
|
||||
* and it'll parse these into a CommandLine object that can be used by the script to retrieve the data
|
||||
* @param args The primitive array of Strings representing the parameters
|
||||
* @throws ParseException If something goes wrong
|
||||
*/
|
||||
private void parse(String[] args) throws ParseException {
|
||||
commandLine = new DefaultParser().parse(getOptions(), args);
|
||||
setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call upon the {@link DSpaceRunnableHandler#printHelp(Options, String)} method with the script's
|
||||
* options and name
|
||||
*/
|
||||
public void printHelp() {
|
||||
handler.printHelp(options, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the run() method from the Runnable interface that we implement. This method will handle the running
|
||||
* of the script and all the database modifications needed for the Process object that resulted from this script
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
handler.start();
|
||||
internalRun();
|
||||
handler.handleCompletion();
|
||||
} catch (Exception e) {
|
||||
handler.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHandler(DSpaceRunnableHandler dSpaceRunnableHandler) {
|
||||
this.handler = dSpaceRunnableHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the appropriate DSpaceRunnableHandler depending on where it was ran from and it parses
|
||||
* the arguments given to the script
|
||||
* @param args The arguments given to the script
|
||||
* @param dSpaceRunnableHandler The DSpaceRunnableHandler object that defines from where the script was ran
|
||||
* @throws ParseException If something goes wrong
|
||||
*/
|
||||
public void initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler) throws ParseException {
|
||||
this.setHandler(dSpaceRunnableHandler);
|
||||
this.parse(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method has to be included in every script and this will be the main execution block for the script that'll
|
||||
* contain all the logic needed
|
||||
* @throws Exception If something goes wrong
|
||||
*/
|
||||
public abstract void internalRun() throws Exception;
|
||||
|
||||
/**
|
||||
* This method has to be included in every script and handles the setup of the script by parsing the CommandLine
|
||||
* and setting the variables
|
||||
* @throws ParseException If something goes wrong
|
||||
*/
|
||||
public abstract void setup() throws ParseException;
|
||||
|
||||
/**
|
||||
* This method will return if the script is allowed to execute in the given context. This is by default set
|
||||
* to the currentUser in the context being an admin, however this can be overwritten by each script individually
|
||||
* if different rules apply
|
||||
* @param context The relevant DSpace context
|
||||
* @return A boolean indicating whether the script is allowed to execute or not
|
||||
*/
|
||||
public boolean isAllowedToExecute(Context context) {
|
||||
try {
|
||||
return authorizeService.isAdmin(context);
|
||||
} catch (SQLException e) {
|
||||
handler.logError("Error occured when trying to verify permissions for script: " + name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
242
dspace-api/src/main/java/org/dspace/scripts/Process.java
Normal file
242
dspace-api/src/main/java/org/dspace/scripts/Process.java
Normal file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
* 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.scripts;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.ProcessStatus;
|
||||
import org.dspace.core.ReloadableEntity;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
/**
|
||||
* This class is the DB Entity representation of the Process object to be stored in the Database
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "process")
|
||||
public class Process implements ReloadableEntity<Integer> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "process_id_seq")
|
||||
@SequenceGenerator(name = "process_id_seq", sequenceName = "process_id_seq", allocationSize = 1)
|
||||
@Column(name = "process_id", unique = true, nullable = false)
|
||||
private Integer processId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
private EPerson ePerson;
|
||||
|
||||
@Column(name = "start_time")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date startTime;
|
||||
|
||||
@Column(name = "finished_time")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date finishedTime;
|
||||
|
||||
@Column(name = "script", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "status")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ProcessStatus processStatus;
|
||||
|
||||
@Column(name = "parameters")
|
||||
private String parameters;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY)
|
||||
@JoinTable(
|
||||
name = "process2bitstream",
|
||||
joinColumns = {@JoinColumn(name = "process_id")},
|
||||
inverseJoinColumns = {@JoinColumn(name = "bitstream_id")}
|
||||
)
|
||||
private List<Bitstream> bitstreams;
|
||||
|
||||
@Column(name = "creation_time", nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date creationTime;
|
||||
|
||||
protected Process() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ID that the Process holds within the Database
|
||||
* @return The ID that the process holds within the database
|
||||
*/
|
||||
public Integer getID() {
|
||||
return processId;
|
||||
}
|
||||
|
||||
public void setProcessId(Integer processId) {
|
||||
this.processId = processId;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an EPerson object. This EPerson object is the EPerson that initially created the process
|
||||
* @return The EPerson that created the process
|
||||
*/
|
||||
public EPerson getEPerson() {
|
||||
return ePerson;
|
||||
}
|
||||
|
||||
public void setEPerson(EPerson ePerson) {
|
||||
this.ePerson = ePerson;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Start time for the Process. This reflects the time when the Process was actually started
|
||||
* @return The start time for the Process
|
||||
*/
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Date startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the time that Process was finished
|
||||
* @return The finished time for the Process
|
||||
*/
|
||||
public Date getFinishedTime() {
|
||||
return finishedTime;
|
||||
}
|
||||
|
||||
public void setFinishedTime(Date finishedTime) {
|
||||
this.finishedTime = finishedTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the name of the Process. For example filter-media
|
||||
* @return The name of the Process
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a ProcessStatus value that represents the current state of the Process. These values
|
||||
* can be found within the {@link ProcessStatus} enum
|
||||
* @return The status of the Process
|
||||
*/
|
||||
public ProcessStatus getProcessStatus() {
|
||||
return processStatus;
|
||||
}
|
||||
|
||||
public void setProcessStatus(ProcessStatus processStatus) {
|
||||
this.processStatus = processStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the parameters, use ProcessService.getParameters() to get a parsed list of DSpaceCommandLineParameters
|
||||
* This String representation is the parameter in an unparsed fashion. For example "-c test"
|
||||
*/
|
||||
protected String getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(String parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a list of Bitstreams that will be used or created by the Process. This list contains both
|
||||
* input and output bitstreams.
|
||||
* @return The Bitstreams that are used or created by the process
|
||||
*/
|
||||
public List<Bitstream> getBitstreams() {
|
||||
return bitstreams;
|
||||
}
|
||||
|
||||
public void setBitstreams(List<Bitstream> bitstreams) {
|
||||
this.bitstreams = bitstreams;
|
||||
}
|
||||
|
||||
public void removeBitstream(Bitstream bitstream) {
|
||||
getBitstreams().remove(bitstream);
|
||||
}
|
||||
|
||||
public void addBitstream(Bitstream bitstream) {
|
||||
getBitstreams().add(bitstream);
|
||||
}
|
||||
|
||||
public void setCreationTime(Date creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the time when the Process was created. Note that this is potentially different from
|
||||
* the StartTime (for example if the Process was queued)
|
||||
* @return The creation time of the Process
|
||||
*/
|
||||
public Date getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if <code>other</code> is the same Process
|
||||
* as this object, <code>false</code> otherwise
|
||||
*
|
||||
* @param other object to compare to
|
||||
* @return <code>true</code> if object passed in represents the same
|
||||
* collection as this object
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return (other instanceof Process &&
|
||||
new EqualsBuilder().append(this.getID(), ((Process) other).getID())
|
||||
.append(this.getName(), ((Process) other).getName())
|
||||
.append(this.getBitstreams(), ((Process) other).getBitstreams())
|
||||
.append(this.getProcessStatus(), ((Process) other).getProcessStatus())
|
||||
.append(this.getFinishedTime(), ((Process) other).getFinishedTime())
|
||||
.append(this.getStartTime(), ((Process) other).getStartTime())
|
||||
.append(this.getParameters(), ((Process) other).getParameters())
|
||||
.append(this.getCreationTime(), ((Process) other).getCreationTime())
|
||||
.append(this.getEPerson(), ((Process) other).getEPerson())
|
||||
.isEquals());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.append(this.getID())
|
||||
.append(this.getName())
|
||||
.append(this.getBitstreams())
|
||||
.append(this.getProcessStatus())
|
||||
.append(this.getFinishedTime())
|
||||
.append(this.getStartTime())
|
||||
.append(this.getParameters())
|
||||
.append(this.getCreationTime())
|
||||
.append(this.getEPerson())
|
||||
.toHashCode();
|
||||
}
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* 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.scripts;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.content.ProcessStatus;
|
||||
import org.dspace.content.dao.ProcessDAO;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.scripts.service.ProcessService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The implementation for the {@link ProcessService} class
|
||||
*/
|
||||
public class ProcessServiceImpl implements ProcessService {
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ProcessService.class);
|
||||
|
||||
@Autowired
|
||||
private ProcessDAO processDAO;
|
||||
|
||||
@Override
|
||||
public Process create(Context context, EPerson ePerson, String scriptName,
|
||||
List<DSpaceCommandLineParameter> parameters) throws SQLException {
|
||||
|
||||
Process process = new Process();
|
||||
process.setEPerson(ePerson);
|
||||
process.setName(scriptName);
|
||||
process.setParameters(DSpaceCommandLineParameter.concatenate(parameters));
|
||||
process.setCreationTime(new Date());
|
||||
Process createdProcess = processDAO.create(context, process);
|
||||
log.info(LogManager.getHeader(context, "process_create",
|
||||
"Process has been created for eperson with email " + ePerson.getEmail()
|
||||
+ " with ID " + createdProcess.getID() + " and scriptName " +
|
||||
scriptName + " and parameters " + parameters));
|
||||
return createdProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process find(Context context, int processId) throws SQLException {
|
||||
return processDAO.findByID(context, Process.class, processId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAll(Context context) throws SQLException {
|
||||
return processDAO.findAll(context, Process.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAll(Context context, int limit, int offset) throws SQLException {
|
||||
return processDAO.findAll(context, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAllSortByScript(Context context) throws SQLException {
|
||||
return processDAO.findAllSortByScript(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Process> findAllSortByStartTime(Context context) throws SQLException {
|
||||
List<Process> processes = findAll(context);
|
||||
Comparator<Process> comparing = Comparator
|
||||
.comparing(Process::getStartTime, Comparator.nullsLast(Comparator.naturalOrder()));
|
||||
comparing = comparing.thenComparing(Process::getID);
|
||||
processes.sort(comparing);
|
||||
return processes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Context context, Process process) throws SQLException {
|
||||
process.setProcessStatus(ProcessStatus.RUNNING);
|
||||
process.setStartTime(new Date());
|
||||
update(context, process);
|
||||
log.info(LogManager.getHeader(context, "process_start", "Process with ID " + process.getID()
|
||||
+ " and name " + process.getName() + " has started"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(Context context, Process process) throws SQLException {
|
||||
process.setProcessStatus(ProcessStatus.FAILED);
|
||||
process.setFinishedTime(new Date());
|
||||
update(context, process);
|
||||
log.info(LogManager.getHeader(context, "process_fail", "Process with ID " + process.getID()
|
||||
+ " and name " + process.getName() + " has failed"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Context context, Process process) throws SQLException {
|
||||
process.setProcessStatus(ProcessStatus.COMPLETED);
|
||||
process.setFinishedTime(new Date());
|
||||
update(context, process);
|
||||
log.info(LogManager.getHeader(context, "process_complete", "Process with ID " + process.getID()
|
||||
+ " and name " + process.getName() + " has been completed"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Context context, Process process) throws SQLException {
|
||||
processDAO.delete(context, process);
|
||||
log.info(LogManager.getHeader(context, "process_delete", "Process with ID " + process.getID()
|
||||
+ " and name " + process.getName() + " has been deleted"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Context context, Process process) throws SQLException {
|
||||
processDAO.save(context, process);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DSpaceCommandLineParameter> getParameters(Process process) {
|
||||
if (StringUtils.isBlank(process.getParameters())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String[] parameterArray = process.getParameters().split(Pattern.quote(DSpaceCommandLineParameter.SEPARATOR));
|
||||
List<DSpaceCommandLineParameter> parameterList = new ArrayList<>();
|
||||
|
||||
for (String parameter : parameterArray) {
|
||||
parameterList.add(new DSpaceCommandLineParameter(parameter));
|
||||
}
|
||||
|
||||
return parameterList;
|
||||
}
|
||||
|
||||
public int countTotal(Context context) throws SQLException {
|
||||
return processDAO.countRows(context);
|
||||
}
|
||||
|
||||
}
|
@@ -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.scripts;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.service.ScriptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The implementation for the {@link ScriptService}
|
||||
*/
|
||||
public class ScriptServiceImpl implements ScriptService {
|
||||
|
||||
@Autowired
|
||||
private List<DSpaceRunnable> dSpaceRunnables;
|
||||
|
||||
@Override
|
||||
public DSpaceRunnable getScriptForName(String name) {
|
||||
return dSpaceRunnables.stream()
|
||||
.filter(dSpaceRunnable -> StringUtils.equalsIgnoreCase(dSpaceRunnable.getName(), name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DSpaceRunnable> getDSpaceRunnables(Context context) {
|
||||
return dSpaceRunnables.stream().filter(
|
||||
dSpaceRunnable -> dSpaceRunnable.isAllowedToExecute(context)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.scripts.factory;
|
||||
|
||||
import org.dspace.scripts.service.ProcessService;
|
||||
import org.dspace.scripts.service.ScriptService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
/**
|
||||
* Abstract factory to get services for the Script workload, use ScriptServiceFactory.getInstance() to retrieve an
|
||||
* implementation
|
||||
*
|
||||
*/
|
||||
public abstract class ScriptServiceFactory {
|
||||
|
||||
/**
|
||||
* This method will return an instance of the ScriptService
|
||||
* @return An instance of the ScriptService
|
||||
*/
|
||||
public abstract ScriptService getScriptService();
|
||||
|
||||
/**
|
||||
* This method will return an instance of the ProcessService
|
||||
* @return An instance of the ProcessService
|
||||
*/
|
||||
public abstract ProcessService getProcessService();
|
||||
|
||||
/**
|
||||
* Use this method to retrieve an implementation of the ScriptServiceFactory to use to retrieve the different beans
|
||||
* @return An implementation of the ScriptServiceFactory
|
||||
*/
|
||||
public static ScriptServiceFactory getInstance() {
|
||||
return DSpaceServicesFactory.getInstance().getServiceManager()
|
||||
.getServiceByName("scriptServiceFactory", ScriptServiceFactory.class);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.scripts.factory.impl;
|
||||
|
||||
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||
import org.dspace.scripts.service.ProcessService;
|
||||
import org.dspace.scripts.service.ScriptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The implementation for the {@link ScriptServiceFactory}
|
||||
*/
|
||||
public class ScriptServiceFactoryImpl extends ScriptServiceFactory {
|
||||
|
||||
@Autowired(required = true)
|
||||
private ScriptService scriptService;
|
||||
|
||||
@Autowired(required = true)
|
||||
private ProcessService processService;
|
||||
|
||||
@Override
|
||||
public ScriptService getScriptService() {
|
||||
return scriptService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessService getProcessService() {
|
||||
return processService;
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.scripts.handler;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.cli.Options;
|
||||
|
||||
/**
|
||||
* This is an interface meant to be implemented by any DSpaceRunnableHandler to specify specific execution methods
|
||||
* of the script depending on where it was called from
|
||||
*/
|
||||
public interface DSpaceRunnableHandler {
|
||||
|
||||
/**
|
||||
* This method handles the start of the script
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void start() throws SQLException;
|
||||
|
||||
/**
|
||||
* This method handles the completion of the script
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void handleCompletion() throws SQLException;
|
||||
|
||||
/**
|
||||
* This method handles an exception thrown by the script
|
||||
* @param e The exception thrown by the script
|
||||
*/
|
||||
public void handleException(Exception e);
|
||||
|
||||
/**
|
||||
* This method handles an exception thrown by the script
|
||||
* @param message The String message for the exception thrown by the script
|
||||
*/
|
||||
public void handleException(String message);
|
||||
|
||||
/**
|
||||
* This method handles an exception thrown by the script
|
||||
* @param message The String message for the exception thrown by the script
|
||||
* @param e The exception thrown by the script
|
||||
*/
|
||||
public void handleException(String message, Exception e);
|
||||
|
||||
/**
|
||||
* This method will perform the debug logging of the message given
|
||||
* @param message The message to be logged as debug
|
||||
*/
|
||||
public void logDebug(String message);
|
||||
|
||||
/**
|
||||
* This method will perform the info logging of the message given
|
||||
* @param message The message to be logged as info
|
||||
*/
|
||||
public void logInfo(String message);
|
||||
|
||||
/**
|
||||
* This method will perform the warning logging of the message given
|
||||
* @param message The message to be logged as warning
|
||||
*/
|
||||
public void logWarning(String message);
|
||||
|
||||
/**
|
||||
* This method will perform the error logging of the message given
|
||||
* @param message The message to be logged as an error
|
||||
*/
|
||||
public void logError(String message);
|
||||
|
||||
/**
|
||||
* This method will print the help for the options and name
|
||||
* @param options The options for the script
|
||||
* @param name The name of the script
|
||||
*/
|
||||
public void printHelp(Options options, String name);
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 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.scripts.handler.impl;
|
||||
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
|
||||
/**
|
||||
* This is an implementation for the CommandLineDSpaceRunnables which means that these implementations
|
||||
* are used by DSpaceRunnables which are called from the CommandLine
|
||||
*/
|
||||
public class CommandLineDSpaceRunnableHandler implements DSpaceRunnableHandler {
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||
.getLogger(CommandLineDSpaceRunnableHandler.class);
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
System.out.println("The script has started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCompletion() {
|
||||
System.out.println("The script has completed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleException(Exception e) {
|
||||
handleException(null, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleException(String message) {
|
||||
handleException(message, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleException(String message, Exception e) {
|
||||
if (message != null) {
|
||||
System.err.println(message);
|
||||
log.error(message);
|
||||
}
|
||||
if (e != null) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logDebug(String message) {
|
||||
log.debug(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logInfo(String message) {
|
||||
System.out.println(message);
|
||||
log.info(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logWarning(String message) {
|
||||
System.out.println(message);
|
||||
log.warn(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logError(String message) {
|
||||
System.err.println(message);
|
||||
log.error(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHelp(Options options, String name) {
|
||||
if (options != null) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp(name, options);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.scripts.service;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.scripts.DSpaceCommandLineParameter;
|
||||
import org.dspace.scripts.Process;
|
||||
|
||||
/**
|
||||
* An interface for the ProcessService with methods regarding the Process workload
|
||||
*/
|
||||
public interface ProcessService {
|
||||
|
||||
/**
|
||||
* This method will create a Process object in the database
|
||||
* @param context The relevant DSpace context
|
||||
* @param ePerson The ePerson for which this process will be created on
|
||||
* @param scriptName The script name to be used for the process
|
||||
* @param parameters The parameters to be used for the process
|
||||
* @return The created process
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public Process create(Context context, EPerson ePerson, String scriptName,
|
||||
List<DSpaceCommandLineParameter> parameters) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will retrieve a Process object from the Database with the given ID
|
||||
* @param context The relevant DSpace context
|
||||
* @param processId The process id on which we'll search for in the database
|
||||
* @return The process that holds the given process id
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public Process find(Context context, int processId) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a list of all Process objects in the database
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of all Process objects in the Database
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAll(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a list of all Process objects in the database
|
||||
* @param context The relevant DSpace context
|
||||
* @param limit The limit for the amount of Processes returned
|
||||
* @param offset The offset for the Processes to be returned
|
||||
* @return The list of all Process objects in the Database
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAll(Context context, int limit, int offset) throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of all Process objects in the database sorted by script name
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of all Process objects in the database sorted by script name
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAllSortByScript(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a list of all Process objects in the database sorted by start time
|
||||
* The most recent one will be shown first
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of all Process objects sorted by start time
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public List<Process> findAllSortByStartTime(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will perform the logic needed to update the Process object in the database to represent a
|
||||
* started state. A started state refers to {@link org.dspace.content.ProcessStatus#RUNNING}
|
||||
* @param context The relevant DSpace context
|
||||
* @param process The Process object to be updated
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void start(Context context, Process process) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will perform the logic needed to update the Process object in the database to represent
|
||||
* a failed state
|
||||
* @param context The relevant DSpace context
|
||||
* @param process The Process object to be updated
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void fail(Context context, Process process) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will perform the logic needed to update the Process object in the database to represent
|
||||
* a complete state
|
||||
* @param context The relevant DSpace context
|
||||
* @param process The Process object to be updated
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void complete(Context context, Process process) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will delete the given Process object from the database
|
||||
* @param context The relevant DSpace context
|
||||
* @param process The Process object to be deleted
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void delete(Context context, Process process) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will be used to update the given Process object in the database
|
||||
* @param context The relevant DSpace context
|
||||
* @param process The Process object to be updated
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
public void update(Context context, Process process) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method will retrieve the list of parameters from the Process in its String format and it will parse
|
||||
* these parameters to a list of {@link DSpaceCommandLineParameter} objects for better usability throughout DSpace
|
||||
* @param process The Process object for which we'll return the parameters
|
||||
* @return The list of parsed parameters from the Process object
|
||||
*/
|
||||
public List<DSpaceCommandLineParameter> getParameters(Process process);
|
||||
|
||||
/**
|
||||
* Returns the total amount of Process objects in the dataase
|
||||
* @param context The relevant DSpace context
|
||||
* @return An integer that describes the amount of Process objects in the database
|
||||
* @throws SQLException If something goes wrong
|
||||
*/
|
||||
int countTotal(Context context) throws SQLException;
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.scripts.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
|
||||
/**
|
||||
* This service will deal with logic to handle DSpaceRunnable objects
|
||||
*/
|
||||
public interface ScriptService {
|
||||
|
||||
/**
|
||||
* This method will return the DSpaceRunnable that has the name that's equal to the name given in the parameters
|
||||
* @param name The name that the script has to match
|
||||
* @return The matching DSpaceRunnable script
|
||||
*/
|
||||
DSpaceRunnable getScriptForName(String name);
|
||||
|
||||
/**
|
||||
* This method will return a list of DSpaceRunnable objects for which the given Context is authorized to use them
|
||||
* @param context The relevant DSpace context
|
||||
* @return The list of accessible DSpaceRunnable scripts for this context
|
||||
*/
|
||||
List<DSpaceRunnable> getDSpaceRunnables(Context context);
|
||||
}
|
@@ -189,16 +189,19 @@ ALTER TABLE item2bundle add primary key (item_id,bundle_id);
|
||||
--Migrate Bundle2Bitsteam
|
||||
ALTER TABLE bundle2bitstream ALTER COLUMN bundle_id rename to bundle_legacy_id;
|
||||
ALTER TABLE bundle2bitstream ALTER COLUMN bitstream_id rename to bitstream_legacy_id;
|
||||
ALTER TABLE bundle2bitstream ALTER COLUMN bitstream_order rename to bitstream_order_legacy;
|
||||
ALTER TABLE bundle2bitstream ADD COLUMN bundle_id UUID NOT NULL;
|
||||
ALTER TABLE bundle2bitstream ADD CONSTRAINT bundle2bitstream_bundle_id_fk FOREIGN KEY (bundle_id) REFERENCES bundle;
|
||||
ALTER TABLE bundle2bitstream ADD COLUMN bitstream_id UUID NOT NULL;
|
||||
ALTER TABLE bundle2bitstream ADD CONSTRAINT bundle2bitstream_bitstream_id_fk FOREIGN KEY (bitstream_id) REFERENCES bitstream;
|
||||
ALTER TABLE bundle2bitstream ADD COLUMN bitstream_order INTEGER NOT NULL;
|
||||
UPDATE bundle2bitstream SET bundle_id = (SELECT bundle.uuid FROM bundle WHERE bundle2bitstream.bundle_legacy_id = bundle.bundle_id);
|
||||
UPDATE bundle2bitstream SET bitstream_id = (SELECT bitstream.uuid FROM bitstream WHERE bundle2bitstream.bitstream_legacy_id = bitstream.bitstream_id);
|
||||
ALTER TABLE bundle2bitstream DROP COLUMN bundle_legacy_id;
|
||||
ALTER TABLE bundle2bitstream DROP COLUMN bitstream_legacy_id;
|
||||
ALTER TABLE bundle2bitstream DROP COLUMN bitstream_order_legacy;
|
||||
ALTER TABLE bundle2bitstream DROP COLUMN id;
|
||||
ALTER TABLE bundle2bitstream add primary key (bitstream_id,bundle_id);
|
||||
ALTER TABLE bundle2bitstream add primary key (bitstream_id,bundle_id,bitstream_order);
|
||||
|
||||
|
||||
-- Migrate item
|
||||
|
@@ -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,40 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
-- ===============================================================
|
||||
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
--
|
||||
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||
-- http://flywaydb.org/
|
||||
-- ===============================================================
|
||||
CREATE SEQUENCE process_id_seq;
|
||||
|
||||
CREATE TABLE process
|
||||
(
|
||||
process_id INTEGER NOT NULL PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
start_time TIMESTAMP,
|
||||
finished_time TIMESTAMP,
|
||||
creation_time TIMESTAMP NOT NULL,
|
||||
script VARCHAR(256) NOT NULL,
|
||||
status VARCHAR(32),
|
||||
parameters VARCHAR(512)
|
||||
);
|
||||
|
||||
CREATE TABLE process2bitstream
|
||||
(
|
||||
process_id INTEGER REFERENCES process(process_id),
|
||||
bitstream_id UUID REFERENCES bitstream(uuid),
|
||||
CONSTRAINT PK_process2bitstream PRIMARY KEY (process_id, bitstream_id)
|
||||
);
|
||||
|
||||
CREATE INDEX process_user_id_idx ON process(user_id);
|
||||
CREATE INDEX process_status_idx ON process(status);
|
||||
CREATE INDEX process_name_idx on process(script);
|
||||
CREATE INDEX process_start_time_idx on process(start_time);
|
@@ -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,40 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
-- ===============================================================
|
||||
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
--
|
||||
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||
-- http://flywaydb.org/
|
||||
-- ===============================================================
|
||||
CREATE SEQUENCE process_id_seq;
|
||||
|
||||
CREATE TABLE process
|
||||
(
|
||||
process_id INTEGER NOT NULL PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL,
|
||||
start_time TIMESTAMP,
|
||||
finished_time TIMESTAMP,
|
||||
creation_time TIMESTAMP NOT NULL,
|
||||
script VARCHAR(256) NOT NULL,
|
||||
status VARCHAR(32),
|
||||
parameters VARCHAR(512)
|
||||
);
|
||||
|
||||
CREATE TABLE process2bitstream
|
||||
(
|
||||
process_id INTEGER REFERENCES process(process_id),
|
||||
bitstream_id RAW(16) REFERENCES bitstream(uuid),
|
||||
CONSTRAINT PK_process2bitstream PRIMARY KEY (process_id, bitstream_id)
|
||||
);
|
||||
|
||||
CREATE INDEX process_user_id_idx ON process(user_id);
|
||||
CREATE INDEX process_status_idx ON process(status);
|
||||
CREATE INDEX process_name_idx on process(script);
|
||||
CREATE INDEX process_start_time_idx on process(start_time);
|
@@ -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;
|
@@ -0,0 +1,40 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
-- ===============================================================
|
||||
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
--
|
||||
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||
-- http://flywaydb.org/
|
||||
-- ===============================================================
|
||||
CREATE SEQUENCE process_id_seq;
|
||||
|
||||
CREATE TABLE process
|
||||
(
|
||||
process_id INTEGER NOT NULL PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
start_time TIMESTAMP,
|
||||
finished_time TIMESTAMP,
|
||||
creation_time TIMESTAMP NOT NULL,
|
||||
script VARCHAR(256) NOT NULL,
|
||||
status VARCHAR(32),
|
||||
parameters VARCHAR(512)
|
||||
);
|
||||
|
||||
CREATE TABLE process2bitstream
|
||||
(
|
||||
process_id INTEGER REFERENCES process(process_id),
|
||||
bitstream_id UUID REFERENCES bitstream(uuid),
|
||||
CONSTRAINT PK_process2bitstream PRIMARY KEY (process_id, bitstream_id)
|
||||
);
|
||||
|
||||
CREATE INDEX process_user_id_idx ON process(user_id);
|
||||
CREATE INDEX process_status_idx ON process(status);
|
||||
CREATE INDEX process_name_idx on process(script);
|
||||
CREATE INDEX process_start_time_idx on process(start_time);
|
@@ -5,8 +5,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>Person</rightType>
|
||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
||||
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>10</min>
|
||||
</leftCardinality>
|
||||
@@ -17,8 +17,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>Project</rightType>
|
||||
<leftLabel>isProjectOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfProject</rightLabel>
|
||||
<leftwardType>isProjectOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfProject</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -29,8 +29,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -41,8 +41,8 @@
|
||||
<type>
|
||||
<leftType>Person</leftType>
|
||||
<rightType>Project</rightType>
|
||||
<leftLabel>isProjectOfPerson</leftLabel>
|
||||
<rightLabel>isPersonOfProject</rightLabel>
|
||||
<leftwardType>isProjectOfPerson</leftwardType>
|
||||
<rightwardType>isPersonOfProject</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -53,8 +53,8 @@
|
||||
<type>
|
||||
<leftType>Person</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfPerson</leftLabel>
|
||||
<rightLabel>isPersonOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfPerson</leftwardType>
|
||||
<rightwardType>isPersonOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -65,8 +65,8 @@
|
||||
<type>
|
||||
<leftType>Project</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfProject</leftLabel>
|
||||
<rightLabel>isProjectOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfProject</leftwardType>
|
||||
<rightwardType>isProjectOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -77,8 +77,8 @@
|
||||
<type>
|
||||
<leftType>Journal</leftType>
|
||||
<rightType>JournalVolume</rightType>
|
||||
<leftLabel>isVolumeOfJournal</leftLabel>
|
||||
<rightLabel>isJournalOfVolume</rightLabel>
|
||||
<leftwardType>isVolumeOfJournal</leftwardType>
|
||||
<rightwardType>isJournalOfVolume</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -89,8 +89,8 @@
|
||||
<type>
|
||||
<leftType>JournalVolume</leftType>
|
||||
<rightType>JournalIssue</rightType>
|
||||
<leftLabel>isIssueOfJournalVolume</leftLabel>
|
||||
<rightLabel>isJournalVolumeOfIssue</rightLabel>
|
||||
<leftwardType>isIssueOfJournalVolume</leftwardType>
|
||||
<rightwardType>isJournalVolumeOfIssue</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -102,8 +102,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
||||
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -114,8 +114,8 @@
|
||||
<type>
|
||||
<leftType>JournalIssue</leftType>
|
||||
<rightType>Publication</rightType>
|
||||
<leftLabel>isPublicationOfJournalIssue</leftLabel>
|
||||
<rightLabel>isJournalIssueOfPublication</rightLabel>
|
||||
<leftwardType>isPublicationOfJournalIssue</leftwardType>
|
||||
<rightwardType>isJournalIssueOfPublication</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
|
@@ -2,11 +2,11 @@
|
||||
|
||||
|
||||
<!ELEMENT relationships (type)*>
|
||||
<!ELEMENT type (leftType|rightType|leftLabel|rightLabel|leftCardinality|rightCardinality)*>
|
||||
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality)*>
|
||||
<!ELEMENT leftType (#PCDATA)>
|
||||
<!ELEMENT rightType (#PCDATA)>
|
||||
<!ELEMENT leftLabel (#PCDATA)>
|
||||
<!ELEMENT rightLabel (#PCDATA)>
|
||||
<!ELEMENT leftwardType (#PCDATA)>
|
||||
<!ELEMENT rightwardType (#PCDATA)>
|
||||
<!ELEMENT leftCardinality (min|max)*>
|
||||
<!ELEMENT min (#PCDATA)>
|
||||
<!ELEMENT rightCardinality (min|max)*>
|
||||
|
@@ -5,8 +5,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>Person</rightType>
|
||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
||||
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -17,8 +17,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>Project</rightType>
|
||||
<leftLabel>isProjectOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfProject</rightLabel>
|
||||
<leftwardType>isProjectOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfProject</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -29,8 +29,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -41,8 +41,8 @@
|
||||
<type>
|
||||
<leftType>Person</leftType>
|
||||
<rightType>Project</rightType>
|
||||
<leftLabel>isProjectOfPerson</leftLabel>
|
||||
<rightLabel>isPersonOfProject</rightLabel>
|
||||
<leftwardType>isProjectOfPerson</leftwardType>
|
||||
<rightwardType>isPersonOfProject</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -53,8 +53,8 @@
|
||||
<type>
|
||||
<leftType>Person</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfPerson</leftLabel>
|
||||
<rightLabel>isPersonOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfPerson</leftwardType>
|
||||
<rightwardType>isPersonOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -65,8 +65,8 @@
|
||||
<type>
|
||||
<leftType>Project</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isOrgUnitOfProject</leftLabel>
|
||||
<rightLabel>isProjectOfOrgUnit</rightLabel>
|
||||
<leftwardType>isOrgUnitOfProject</leftwardType>
|
||||
<rightwardType>isProjectOfOrgUnit</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -77,8 +77,8 @@
|
||||
<type>
|
||||
<leftType>Journal</leftType>
|
||||
<rightType>JournalVolume</rightType>
|
||||
<leftLabel>isVolumeOfJournal</leftLabel>
|
||||
<rightLabel>isJournalOfVolume</rightLabel>
|
||||
<leftwardType>isVolumeOfJournal</leftwardType>
|
||||
<rightwardType>isJournalOfVolume</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -89,8 +89,8 @@
|
||||
<type>
|
||||
<leftType>JournalVolume</leftType>
|
||||
<rightType>JournalIssue</rightType>
|
||||
<leftLabel>isIssueOfJournalVolume</leftLabel>
|
||||
<rightLabel>isJournalVolumeOfIssue</rightLabel>
|
||||
<leftwardType>isIssueOfJournalVolume</leftwardType>
|
||||
<rightwardType>isJournalVolumeOfIssue</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -102,8 +102,8 @@
|
||||
<type>
|
||||
<leftType>Publication</leftType>
|
||||
<rightType>OrgUnit</rightType>
|
||||
<leftLabel>isAuthorOfPublication</leftLabel>
|
||||
<rightLabel>isPublicationOfAuthor</rightLabel>
|
||||
<leftwardType>isAuthorOfPublication</leftwardType>
|
||||
<rightwardType>isPublicationOfAuthor</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
@@ -114,8 +114,8 @@
|
||||
<type>
|
||||
<leftType>JournalIssue</leftType>
|
||||
<rightType>Publication</rightType>
|
||||
<leftLabel>isPublicationOfJournalIssue</leftLabel>
|
||||
<rightLabel>isJournalIssueOfPublication</rightLabel>
|
||||
<leftwardType>isPublicationOfJournalIssue</leftwardType>
|
||||
<rightwardType>isJournalIssueOfPublication</rightwardType>
|
||||
<leftCardinality>
|
||||
<min>0</min>
|
||||
</leftCardinality>
|
||||
|
@@ -25,6 +25,9 @@
|
||||
# SERVER CONFIGURATION #
|
||||
##########################
|
||||
|
||||
# Spring boot test by default mock the server on the localhost (80)
|
||||
dspace.baseUrl = http://localhost
|
||||
|
||||
# DSpace installation directory.
|
||||
# This is the location where you want to install DSpace.
|
||||
# Windows note: Please remember to use forward slashes for all paths (e.g. C:/dspace)
|
||||
|
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<bean id="indexClient" class="org.dspace.discovery.IndexClient" scope="prototype">
|
||||
<property name="name" value="index-discovery"/>
|
||||
<property name="description" value="Update Discovery Solr Search Index"/>
|
||||
</bean>
|
||||
|
||||
<bean id="MockScript" class="org.dspace.scripts.impl.MockDSpaceRunnableScript" scope="prototype">
|
||||
<property name="name" value="mock-script" />
|
||||
<property name="description" value="Mocking a script for testing purposes" />
|
||||
</bean>
|
||||
</beans>
|
@@ -23,6 +23,10 @@
|
||||
|
||||
<alias name="org.dspace.discovery.SearchService" alias="org.dspace.discovery.IndexingService"/>
|
||||
|
||||
<!-- These beans have been added so that we can mock our AuthoritySearchService in the tests-->
|
||||
<bean class="org.dspace.authority.MockAuthoritySolrServiceImpl" id="org.dspace.authority.AuthoritySearchService"/>
|
||||
<alias name="org.dspace.authority.AuthoritySearchService" alias="org.dspace.authority.indexer.AuthorityIndexingService"/>
|
||||
|
||||
<!--<bean class="org.dspace.discovery.SolrServiceIndexOutputPlugin" id="solrServiceIndexOutputPlugin"/>-->
|
||||
|
||||
<!-- Statistics services are both lazy loaded (by name), as you are likely just using ONE of them and not both -->
|
||||
|
@@ -14,11 +14,12 @@
|
||||
<!-- Each form set contains an ordered set of pages; each page defines -->
|
||||
<!-- one submission metadata entry screen. Each page has an ordered list -->
|
||||
<!-- of field definitions, Each field definition corresponds to one -->
|
||||
<!-- metadata entry (a so-called row), which has a DC element name, a -->
|
||||
<!-- metadata entry (a so-called row), which has a DC element name, a -->
|
||||
<!-- displayed label, a text string prompt which is called a hint, and -->
|
||||
<!-- an input-type. Each field also may hold optional elements: DC -->
|
||||
<!-- qualifier name, a repeatable flag, and a text string whose presence -->
|
||||
<!-- serves as a 'this field is required' flag. -->
|
||||
<!-- qualifier name, a repeatable flag, an optional name-variants allowed -->
|
||||
<!-- flag, and a text string whose presence serves as a -->
|
||||
<!-- 'this field is required' flag. -->
|
||||
|
||||
<form-definitions>
|
||||
<form name="bitstream-metadata">
|
||||
@@ -53,6 +54,7 @@
|
||||
<relationship-type>isAuthorOfPublication</relationship-type>
|
||||
<search-configuration>personConfiguration</search-configuration>
|
||||
<repeatable>true</repeatable>
|
||||
<name-variants>true</name-variants>
|
||||
<label>Author</label>
|
||||
<hint>Add an author</hint>
|
||||
<linked-metadata-field>
|
||||
|
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.authority;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* This class has been created so that we can mock our AuthoritySolrSeviceImpl
|
||||
*/
|
||||
@Service
|
||||
public class MockAuthoritySolrServiceImpl extends AuthoritySolrServiceImpl implements InitializingBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
//We don't use SOLR in the tests of this module
|
||||
solr = null;
|
||||
}
|
||||
}
|
@@ -135,7 +135,7 @@ public class EntityServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelationsByLabel() throws Exception {
|
||||
public void testGetRelationsByTypeName() throws Exception {
|
||||
// Declare objects utilized in unit test
|
||||
Relationship relationship = mock(Relationship.class);
|
||||
RelationshipType relationshipType = mock(RelationshipType.class);
|
||||
@@ -145,15 +145,16 @@ public class EntityServiceImplTest {
|
||||
List<Relationship> relationshipList = new ArrayList<>();
|
||||
relationshipList.add(relationship);
|
||||
|
||||
// Mock the state of objects utilized in getRelationsByLabel() to meet the success criteria of an invocation
|
||||
when(relationshipService.findAll(context)).thenReturn(relationshipList);
|
||||
// Mock the state of objects utilized in getRelationsByType() to meet the success criteria of an invocation
|
||||
when(relationshipService.findAll(context, -1, -1)).thenReturn(relationshipList);
|
||||
when(relationship.getRelationshipType()).thenReturn(relationshipType);
|
||||
when(relationshipType.getLeftLabel()).thenReturn("leftLabel");
|
||||
when(relationshipType.getRightLabel()).thenReturn("rightLabel");
|
||||
when(relationshipType.getLeftwardType()).thenReturn("leftwardType");
|
||||
when(relationshipType.getRightwardType()).thenReturn("rightwardType");
|
||||
when(relationshipService.findByTypeName(context, "leftwardType", -1, -1)).thenReturn(relationshipList);
|
||||
|
||||
// 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,
|
||||
entityService.getRelationsByLabel(context, "leftLabel"));
|
||||
entityService.getRelationsByTypeName(context, "leftwardType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,14 +179,16 @@ public class EntityServiceImplTest {
|
||||
when(metadataValue.getValue()).thenReturn("testType");
|
||||
when(entity.getItem()).thenReturn(item);
|
||||
when(itemService.getMetadata(item, "relationship", "type", null, Item.ANY)).thenReturn(list);
|
||||
when(relationshipTypeDAO.findAll(context, RelationshipType.class)).thenReturn(relationshipTypeList);
|
||||
when(relationshipTypeService.findAll(context)).thenReturn(relationshipTypeList);
|
||||
when(relationshipTypeDAO.findAll(context, RelationshipType.class, -1, -1)).thenReturn(relationshipTypeList);
|
||||
when(relationshipTypeService.findAll(context, -1, -1)).thenReturn(relationshipTypeList);
|
||||
when(relationshipType.getLeftType()).thenReturn(leftType);
|
||||
when(relationshipType.getRightType()).thenReturn(rightType);
|
||||
when(entityTypeService.findByEntityType(context, "value")).thenReturn(leftType);
|
||||
when(leftType.getID()).thenReturn(0);
|
||||
when(rightType.getID()).thenReturn(1);
|
||||
when(entityService.getType(context, entity)).thenReturn(leftType); // Mock
|
||||
when(relationshipTypeService.findByEntityType(context, entityService.getType(context, entity), -1, -1))
|
||||
.thenReturn(relationshipTypeList);
|
||||
|
||||
// The relation(s) reported from our mocked Entity should match our relationshipList
|
||||
assertEquals("TestGetAllRelationshipTypes 0", relationshipTypeList,
|
||||
@@ -212,10 +215,12 @@ public class EntityServiceImplTest {
|
||||
when(itemService.getMetadata(any(), any(), any(), any(), any())).thenReturn(metsList);
|
||||
when(entity.getItem()).thenReturn(item);
|
||||
when(entityType.getID()).thenReturn(0);
|
||||
when(relationshipTypeService.findAll(any())).thenReturn(relationshipTypeList);
|
||||
when(relationshipTypeService.findAll(context, -1, -1)).thenReturn(relationshipTypeList);
|
||||
when(relationshipType.getLeftType()).thenReturn(entityType);
|
||||
when(entityService.getType(context, entity)).thenReturn(entityType);
|
||||
when(entityTypeService.findByEntityType(any(), any())).thenReturn(entityType);
|
||||
when(relationshipTypeService.findByEntityType(context, entityService.getType(context, entity), true, -1, -1))
|
||||
.thenReturn(relationshipTypeList);
|
||||
|
||||
// The left relationshipType(s) reported from our mocked Entity should match our relationshipList
|
||||
assertEquals("TestGetLeftRelationshipTypes 0", relationshipTypeList,
|
||||
@@ -242,10 +247,12 @@ public class EntityServiceImplTest {
|
||||
when(itemService.getMetadata(any(), any(), any(), any(), any())).thenReturn(metsList);
|
||||
when(entity.getItem()).thenReturn(item);
|
||||
when(entityType.getID()).thenReturn(0);
|
||||
when(relationshipTypeService.findAll(any())).thenReturn(relationshipTypeList);
|
||||
when(relationshipTypeService.findAll(context, -1, -1)).thenReturn(relationshipTypeList);
|
||||
when(relationshipType.getRightType()).thenReturn(entityType);
|
||||
when(entityService.getType(context, entity)).thenReturn(entityType);
|
||||
when(entityTypeService.findByEntityType(any(), any())).thenReturn(entityType);
|
||||
when(relationshipTypeService.findByEntityType(context, entityService.getType(context, entity), false, -1, -1))
|
||||
.thenReturn(relationshipTypeList);
|
||||
|
||||
// The right relationshipType(s) reported from our mocked Entity should match our relationshipList
|
||||
assertEquals("TestGetRightRelationshipTypes 0", relationshipTypeList,
|
||||
@@ -254,21 +261,23 @@ public class EntityServiceImplTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetRelationshipTypesByLabel() throws Exception {
|
||||
public void testGetRelationshipTypesByTypeName() throws Exception {
|
||||
// Declare objects utilized in unit test
|
||||
List<RelationshipType> list = new LinkedList<>();
|
||||
RelationshipType relationshipType = mock(RelationshipType.class);
|
||||
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
|
||||
when(relationshipTypeService.findAll(context)).thenReturn(list);
|
||||
when(relationshipType.getLeftLabel()).thenReturn("leftLabel");
|
||||
when(relationshipType.getRightLabel()).thenReturn("rightLabel");
|
||||
when(relationshipTypeService.findAll(context, -1, -1)).thenReturn(list);
|
||||
when(relationshipType.getLeftwardType()).thenReturn("leftwardType");
|
||||
when(relationshipType.getRightwardType()).thenReturn("rightwardType");
|
||||
when(relationshipTypeService.findByLeftwardOrRightwardTypeName(context, "leftwardType", -1, -1))
|
||||
.thenReturn(list);
|
||||
|
||||
// The RelationshipType(s) reported from our mocked Entity should match our list
|
||||
assertEquals("TestGetRelationshipTypesByLabel 0", list,
|
||||
entityService.getRelationshipTypesByLabel(context, "leftLabel"));
|
||||
entityService.getRelationshipTypesByTypeName(context, "leftwardType"));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* 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()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextRightPlace() throws Exception {
|
||||
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(0));
|
||||
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();
|
||||
|
||||
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(1));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
Community community = communityService.create(null, context);
|
||||
|
||||
Collection col = collectionService.create(context, community);
|
||||
WorkspaceItem is = workspaceItemService.create(context, col, false);
|
||||
Item secondItem = installItemService.installItem(context, is);
|
||||
itemService.addMetadata(context, secondItem, "relationship", "type", null, null, "Publication");
|
||||
Relationship secondRelationship = relationshipService.create(context, secondItem, authorItem,
|
||||
isAuthorOfPublication, 0, 0);
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(2));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextLeftPlace() throws Exception {
|
||||
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(0));
|
||||
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();
|
||||
|
||||
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(1));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
Community community = communityService.create(null, context);
|
||||
|
||||
Collection col = collectionService.create(context, community);
|
||||
WorkspaceItem is = workspaceItemService.create(context, col, false);
|
||||
Item secondAuthor = installItemService.installItem(context, is);
|
||||
itemService.addMetadata(context, secondAuthor, "relationship", "type", null, null, "Author");
|
||||
itemService.addMetadata(context, secondAuthor, "person", "familyName", null, null, "familyName");
|
||||
itemService.addMetadata(context, secondAuthor, "person", "givenName", null, null, "firstName");
|
||||
Relationship secondRelationship = relationshipService.create(context, item, secondAuthor,
|
||||
isAuthorOfPublication, 0, 0);
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(2));
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,428 @@
|
||||
/**
|
||||
* 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.EntityTypeService;
|
||||
import org.dspace.content.service.InstallItemService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.content.service.MetadataValueService;
|
||||
import org.dspace.content.service.RelationshipService;
|
||||
import org.dspace.content.service.RelationshipTypeService;
|
||||
import org.dspace.content.service.WorkspaceItemService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||
.getLogger(RelationshipServiceImplPlaceTest.class);
|
||||
|
||||
protected RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||
protected RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
|
||||
.getRelationshipTypeService();
|
||||
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();
|
||||
protected MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
||||
|
||||
Community community;
|
||||
Collection col;
|
||||
|
||||
Item item;
|
||||
Item authorItem;
|
||||
RelationshipType isAuthorOfPublication;
|
||||
EntityType publicationEntityType;
|
||||
EntityType authorEntityType;
|
||||
|
||||
String authorQualifier = "author";
|
||||
String contributorElement = "contributor";
|
||||
String dcSchema = "dc";
|
||||
|
||||
/**
|
||||
* This method will be run before every test as per @Before. It will
|
||||
* initialize resources required for the tests.
|
||||
*/
|
||||
@Before
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
community = communityService.create(null, context);
|
||||
|
||||
col = collectionService.create(context, community);
|
||||
WorkspaceItem is = workspaceItemService.create(context, col, false);
|
||||
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
|
||||
|
||||
item = installItemService.installItem(context, is);
|
||||
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
|
||||
|
||||
authorItem = installItemService.installItem(context, authorIs);
|
||||
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Person");
|
||||
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
|
||||
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
|
||||
|
||||
publicationEntityType = entityTypeService.create(context, "Publication");
|
||||
authorEntityType = entityTypeService.create(context, "Person");
|
||||
isAuthorOfPublication = relationshipTypeService
|
||||
.create(context, publicationEntityType, authorEntityType,
|
||||
"isAuthorOfPublication", "isPublicationOfAuthor",
|
||||
null, null, null, null);
|
||||
|
||||
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.
|
||||
*/
|
||||
@After
|
||||
@Override
|
||||
public void destroy() {
|
||||
context.abort();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test will test the use case of having an item to which we add some metadata. After that, we'll add a single
|
||||
* relationship to this Item. We'll test whether the places are correct, in this case it'll be the two metadata
|
||||
* values that we created first, has to have place 0 and 1. The Relationship that we just created needs to have
|
||||
* leftPlace 2 and the metadata value resulting from that Relationship needs to also have place 2.
|
||||
* Once these assertions succeed, we basically repeat said process with new metadata values and a new relationship.
|
||||
* We then test if the old assertions still hold true like they should and that the new ones behave as expected
|
||||
* as well.
|
||||
* @throws Exception If something goes wrong
|
||||
*/
|
||||
@Test
|
||||
public void addMetadataAndRelationshipTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Here we add the first set of metadata to the item
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
|
||||
|
||||
// Here we create the first Relationship to the item
|
||||
Relationship relationship = relationshipService
|
||||
.create(context, item, authorItem, isAuthorOfPublication, -1, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// The code below performs the mentioned assertions to ensure the place is correct
|
||||
List<MetadataValue> list = itemService
|
||||
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
assertThat(list.size(), equalTo(3));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 2, list.get(2));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(2));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// This is where we add the second set of metadata values
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
|
||||
|
||||
// Here we create an Item so that we can create another relationship with this item
|
||||
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
|
||||
Item secondAuthorItem = installItemService.installItem(context, authorIs);
|
||||
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
|
||||
Relationship relationshipTwo = relationshipService
|
||||
.create(context, item, secondAuthorItem, isAuthorOfPublication, -1, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Here we retrieve the list of metadata again to perform the assertions on the places below as mentioned
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 2, list.get(2));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(2));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 3, list.get(3));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, four", null, 4, list.get(4));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
|
||||
"virtual::" + relationshipTwo.getID(), 5, list.get(5));
|
||||
assertThat(relationshipTwo.getLeftPlace(), equalTo(5));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is virtually the same as above, only this time we'll add Relationships with leftPlaces already set
|
||||
* equal to what they HAVE to be. So in the first test addMetadataAndRelationshipTest, we didn't specify a place
|
||||
* and left it up to the Service to determine it, here we provide a correct place already.
|
||||
* We perform the exact same logic except that we give a proper place already to the Relationships and we
|
||||
* perform the same checks
|
||||
* @throws Exception If something goes wrong
|
||||
*/
|
||||
@Test
|
||||
public void AddMetadataAndRelationshipWithSpecificPlaceTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Here we add the first set of metadata to the item
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
|
||||
|
||||
// Here we create the first Relationship to the item with the specific leftPlace: 2
|
||||
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 2, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// The code below performs the mentioned assertions to ensure the place is correct
|
||||
List<MetadataValue> list = itemService
|
||||
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
assertThat(list.size(), equalTo(3));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 2, list.get(2));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(2));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// This is where we add the second set of metadata values
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
|
||||
|
||||
// Here we create an Item so that we can create another relationship with this item. We'll give this
|
||||
// Relationship a specific place as well
|
||||
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
|
||||
Item secondAuthorItem = installItemService.installItem(context, authorIs);
|
||||
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
|
||||
Relationship relationshipTwo = relationshipService
|
||||
.create(context, item, secondAuthorItem, isAuthorOfPublication, 5, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Here we retrieve the list of metadata again to perform the assertions on the places below as mentioned
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 2, list.get(2));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(2));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 3, list.get(3));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, four", null, 4, list.get(4));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
|
||||
"virtual::" + relationshipTwo.getID(), 5, list.get(5));
|
||||
assertThat(relationshipTwo.getLeftPlace(), equalTo(5));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In this test, our goal will be to add a bunch of metadata values to then remove one of them. We'll check the list
|
||||
* of metadata values for the item and check that the places have not been altered for the metadata values IF an
|
||||
* item.update hadn't been called yet. We'll then create a Relationship (by which an item.update will be called)
|
||||
* and then we check that the places are set correctly.
|
||||
* We then repeat this process once more and check that everything works as intended
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void AddAndRemoveMetadataAndRelationshipsTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Here we add the first set of metadata to the item
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
|
||||
|
||||
// Get a specific metadatavlaue to remove
|
||||
MetadataValue metadataValueToRemove = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY)
|
||||
.get(1);
|
||||
// Remove the actual metadata value
|
||||
item.removeMetadata(metadataValueToRemove);
|
||||
metadataValueService.delete(context, metadataValueToRemove);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Retrieve the list of mdv again
|
||||
List<MetadataValue> list = itemService
|
||||
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
// Verify we only have 2 mdv left
|
||||
assertThat(list.size(), equalTo(2));
|
||||
|
||||
// Check that these places are still intact after the deletion as the place doesn't get updated until an
|
||||
// item.update has been called
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(1));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Create a relationship with this item with a spcific place
|
||||
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 1, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Retrieve the list again and verify that the creation of the Relationship added an additional mdv
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
assertThat(list.size(), equalTo(3));
|
||||
|
||||
// Assert that the mdv are well placed
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 1, list.get(1));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(1));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Add two extra mdv
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, five");
|
||||
|
||||
//This is author "test, four" that we're removing
|
||||
metadataValueToRemove = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY).get(3);
|
||||
item.removeMetadata(metadataValueToRemove);
|
||||
metadataValueService.delete(context, metadataValueToRemove);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
|
||||
// Check that these places are still intact after the deletion as the place doesn't get updated until an
|
||||
// item.update has been called
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 1, list.get(1));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(1));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, five", null, 4, list.get(3));
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Create an additional item for another relationship
|
||||
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
|
||||
Item secondAuthorItem = installItemService.installItem(context, authorIs);
|
||||
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
|
||||
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
|
||||
Relationship relationshipTwo = relationshipService
|
||||
.create(context, item, secondAuthorItem, isAuthorOfPublication, 3, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Check that the other mdv are still okay and that the creation of the relationship added
|
||||
// another correct mdv to the item
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 1, list.get(1));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(1));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
|
||||
"virtual::" + relationshipTwo.getID(), 3, list.get(3));
|
||||
assertThat(relationshipTwo.getLeftPlace(), equalTo(3));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, five", null, 4, list.get(4));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void AddAndUpdateMetadataAndRelationshipsTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Add metadata and relationships to the item
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
|
||||
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
|
||||
|
||||
Relationship relationship = relationshipService
|
||||
.create(context, item, authorItem, isAuthorOfPublication, -1, -1);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Get the list of mdv and assert that they're correct
|
||||
List<MetadataValue> list = itemService
|
||||
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
assertThat(list.size(), equalTo(4));
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 3, list.get(3));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(3));
|
||||
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
MetadataValue metadataValueToUpdate = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY)
|
||||
.get(1);
|
||||
|
||||
// Switching the places of this relationship and metadata value to verify in the test later on that this
|
||||
// updating works
|
||||
metadataValueToUpdate.setPlace(3);
|
||||
metadataValueService.update(context, metadataValueToUpdate);
|
||||
relationship.setLeftPlace(1);
|
||||
relationshipService.update(context, relationship);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// Retrieve the list again and verify that the updating did indeed work
|
||||
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
|
||||
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 3, list.get(3));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
|
||||
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
|
||||
"virtual::" + relationship.getID(), 1, list.get(1));
|
||||
assertThat(relationship.getLeftPlace(), equalTo(1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void assertMetadataValue(String authorQualifier, String contributorElement, String dcSchema, String value,
|
||||
String authority, int place, MetadataValue metadataValue) {
|
||||
assertThat(metadataValue.getValue(), equalTo(value));
|
||||
assertThat(metadataValue.getMetadataField().getMetadataSchema().getName(), equalTo(dcSchema));
|
||||
assertThat(metadataValue.getMetadataField().getElement(), equalTo(contributorElement));
|
||||
assertThat(metadataValue.getMetadataField().getQualifier(), equalTo(authorQualifier));
|
||||
assertThat(metadataValue.getAuthority(), equalTo(authority));
|
||||
assertThat(metadataValue.getPlace(), equalTo(place));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -66,7 +66,7 @@ public class RelationshipServiceImplTest {
|
||||
@Test
|
||||
public void testFindAll() throws Exception {
|
||||
// Mock DAO to return our mocked relationshipsList
|
||||
when(relationshipDAO.findAll(context, Relationship.class)).thenReturn(relationshipsList);
|
||||
when(relationshipDAO.findAll(context, Relationship.class, -1, -1)).thenReturn(relationshipsList);
|
||||
// The reported Relationship(s) should match our relationshipsList
|
||||
assertEquals("TestFindAll 0", relationshipsList, relationshipService.findAll(context));
|
||||
}
|
||||
@@ -84,23 +84,22 @@ public class RelationshipServiceImplTest {
|
||||
RelationshipType hasDog = new RelationshipType();
|
||||
RelationshipType hasFather = new RelationshipType();
|
||||
RelationshipType hasMother = new RelationshipType();
|
||||
hasDog.setLeftLabel("hasDog");
|
||||
hasDog.setRightLabel("isDogOf");
|
||||
hasFather.setLeftLabel("hasFather");
|
||||
hasFather.setRightLabel("isFatherOf");
|
||||
hasMother.setLeftLabel("hasMother");
|
||||
hasMother.setRightLabel("isMotherOf");
|
||||
hasDog.setLeftwardType("hasDog");
|
||||
hasDog.setRightwardType("isDogOf");
|
||||
hasFather.setLeftwardType("hasFather");
|
||||
hasFather.setRightwardType("isFatherOf");
|
||||
hasMother.setLeftwardType("hasMother");
|
||||
hasMother.setRightwardType("isMotherOf");
|
||||
|
||||
relationshipTest.add(getRelationship(cindy, spot, hasDog,0,0));
|
||||
relationshipTest.add(getRelationship(cindy, jasper, hasDog,0,1));
|
||||
relationshipTest.add(getRelationship(cindy, hank, hasFather,0,0));
|
||||
relationshipTest.add(getRelationship(fred, cindy, hasMother,0,0));
|
||||
relationshipTest.add(getRelationship(bob, cindy, hasMother,1,0));
|
||||
when(relationshipService.findByItem(context, cindy)).thenReturn(relationshipTest);
|
||||
when(relationshipDAO.findByItem(context, cindy)).thenReturn(relationshipTest);
|
||||
when(relationshipService.findByItem(context, cindy, -1, -1)).thenReturn(relationshipTest);
|
||||
|
||||
// Mock the state of objects utilized in findByItem() to meet the success criteria of the invocation
|
||||
when(relationshipDAO.findByItem(context, cindy)).thenReturn(relationshipTest);
|
||||
when(relationshipDAO.findByItem(context, cindy, -1, -1)).thenReturn(relationshipTest);
|
||||
|
||||
List<Relationship> results = relationshipService.findByItem(context, cindy);
|
||||
assertEquals("TestFindByItem 0", relationshipTest, results);
|
||||
@@ -115,11 +114,11 @@ public class RelationshipServiceImplTest {
|
||||
Item item = mock(Item.class);
|
||||
|
||||
// Mock DAO to return mocked left place as 0
|
||||
when(relationshipDAO.findLeftPlaceByLeftItem(context, item)).thenReturn(0);
|
||||
when(relationshipDAO.findNextLeftPlaceByLeftItem(context, item)).thenReturn(0);
|
||||
|
||||
// The left place reported from out mocked item should match the DAO's report of the left place
|
||||
assertEquals("TestFindLeftPlaceByLeftItem 0", relationshipDAO.findLeftPlaceByLeftItem(context, item),
|
||||
relationshipService.findLeftPlaceByLeftItem(context, item));
|
||||
assertEquals("TestFindLeftPlaceByLeftItem 0", relationshipDAO.findNextLeftPlaceByLeftItem(context, item),
|
||||
relationshipService.findNextLeftPlaceByLeftItem(context, item));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -128,11 +127,11 @@ public class RelationshipServiceImplTest {
|
||||
Item item = mock(Item.class);
|
||||
|
||||
// Mock lower level DAO to return mocked right place as 0
|
||||
when(relationshipDAO.findRightPlaceByRightItem(context, item)).thenReturn(0);
|
||||
when(relationshipDAO.findNextRightPlaceByRightItem(context, item)).thenReturn(0);
|
||||
|
||||
// The right place reported from out mocked item should match the DAO's report of the right place
|
||||
assertEquals("TestFindRightPlaceByRightItem 0", relationshipDAO.findRightPlaceByRightItem(context, item),
|
||||
relationshipService.findRightPlaceByRightItem(context, item));
|
||||
assertEquals("TestFindRightPlaceByRightItem 0", relationshipDAO.findNextRightPlaceByRightItem(context, item),
|
||||
relationshipService.findNextRightPlaceByRightItem(context, item));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,8 +193,8 @@ public class RelationshipServiceImplTest {
|
||||
EntityType rightEntityType = mock(EntityType.class);
|
||||
testRel.setLeftType(leftEntityType);
|
||||
testRel.setRightType(rightEntityType);
|
||||
testRel.setLeftLabel("Entitylabel");
|
||||
testRel.setRightLabel("Entitylabel");
|
||||
testRel.setLeftwardType("Entitylabel");
|
||||
testRel.setRightwardType("Entitylabel");
|
||||
metsList.add(metVal);
|
||||
relationship = getRelationship(leftItem, rightItem, testRel, 0,0);
|
||||
leftTypelist.add(relationship);
|
||||
@@ -247,8 +246,8 @@ public class RelationshipServiceImplTest {
|
||||
EntityType rightEntityType = mock(EntityType.class);
|
||||
testRel.setLeftType(leftEntityType);
|
||||
testRel.setRightType(rightEntityType);
|
||||
testRel.setLeftLabel("Entitylabel");
|
||||
testRel.setRightLabel("Entitylabel");
|
||||
testRel.setLeftwardType("Entitylabel");
|
||||
testRel.setRightwardType("Entitylabel");
|
||||
testRel.setLeftMinCardinality(0);
|
||||
testRel.setRightMinCardinality(0);
|
||||
metsList.add(metVal);
|
||||
@@ -271,6 +270,8 @@ public class RelationshipServiceImplTest {
|
||||
when(metsList.get(0).getValue()).thenReturn("Entitylabel");
|
||||
when(relationshipService.findByItemAndRelationshipType(context, leftItem, testRel, true))
|
||||
.thenReturn(leftTypelist);
|
||||
when(relationshipService.findByItemAndRelationshipType(context, rightItem, testRel, false))
|
||||
.thenReturn(rightTypelist);
|
||||
when(itemService.getMetadata(leftItem, "relationship", "type", null, Item.ANY)).thenReturn(metsList);
|
||||
when(itemService.getMetadata(rightItem, "relationship", "type", null, Item.ANY)).thenReturn(metsList);
|
||||
when(relationshipDAO.create(any(), any())).thenReturn(relationship);
|
||||
@@ -299,8 +300,8 @@ public class RelationshipServiceImplTest {
|
||||
EntityType rightEntityType = mock(EntityType.class);
|
||||
testRel.setLeftType(leftEntityType);
|
||||
testRel.setRightType(rightEntityType);
|
||||
testRel.setLeftLabel("Entitylabel");
|
||||
testRel.setRightLabel("Entitylabel");
|
||||
testRel.setLeftwardType("Entitylabel");
|
||||
testRel.setRightwardType("Entitylabel");
|
||||
testRel.setLeftMinCardinality(0);
|
||||
testRel.setRightMinCardinality(0);
|
||||
metsList.add(metVal);
|
||||
@@ -321,6 +322,12 @@ public class RelationshipServiceImplTest {
|
||||
Mockito.verify(relationshipDAO).save(context, relationship);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCountTotal() throws Exception {
|
||||
when(relationshipDAO.countRows(context)).thenReturn(0);
|
||||
assertEquals("TestCountTotal 1", 0, relationshipService.countTotal(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns a configured Relationship
|
||||
* @param leftItem Relationship's left item
|
||||
|
@@ -51,8 +51,8 @@ public class RelationshipTypeTest {
|
||||
firstRelationshipType.setId(1);
|
||||
firstRelationshipType.setLeftType(mock(EntityType.class));
|
||||
firstRelationshipType.setRightType(mock(EntityType.class));
|
||||
firstRelationshipType.setLeftLabel("isAuthorOfPublication");
|
||||
firstRelationshipType.setRightLabel("isPublicationOfAuthor");
|
||||
firstRelationshipType.setLeftwardType("isAuthorOfPublication");
|
||||
firstRelationshipType.setRightwardType("isPublicationOfAuthor");
|
||||
firstRelationshipType.setLeftMinCardinality(0);
|
||||
firstRelationshipType.setLeftMaxCardinality(null);
|
||||
firstRelationshipType.setRightMinCardinality(0);
|
||||
@@ -63,8 +63,8 @@ public class RelationshipTypeTest {
|
||||
secondRelationshipType.setId(new Random().nextInt());
|
||||
secondRelationshipType.setLeftType(mock(EntityType.class));
|
||||
secondRelationshipType.setRightType(mock(EntityType.class));
|
||||
secondRelationshipType.setLeftLabel("isProjectOfPerson");
|
||||
secondRelationshipType.setRightLabel("isPersonOfProject");
|
||||
secondRelationshipType.setLeftwardType("isProjectOfPerson");
|
||||
secondRelationshipType.setRightwardType("isPersonOfProject");
|
||||
secondRelationshipType.setLeftMinCardinality(0);
|
||||
secondRelationshipType.setLeftMaxCardinality(null);
|
||||
secondRelationshipType.setRightMinCardinality(0);
|
||||
@@ -87,11 +87,11 @@ public class RelationshipTypeTest {
|
||||
@Test
|
||||
public void testRelationshipTypeFindByTypesAndLabels() throws Exception {
|
||||
// Mock DAO to return our firstRelationshipType
|
||||
when(relationshipTypeDAO.findByTypesAndLabels(any(), any(), any(), any(), any()))
|
||||
when(relationshipTypeDAO.findbyTypesAndTypeName(any(), any(), any(), any(), any()))
|
||||
.thenReturn(firstRelationshipType);
|
||||
|
||||
// Declare objects utilized for this test
|
||||
RelationshipType found = relationshipTypeService.findbyTypesAndLabels(context, mock(EntityType.class),
|
||||
RelationshipType found = relationshipTypeService.findbyTypesAndTypeName(context, mock(EntityType.class),
|
||||
mock(EntityType.class),
|
||||
"mock", "mock");
|
||||
|
||||
@@ -107,7 +107,7 @@ public class RelationshipTypeTest {
|
||||
mockedList.add(secondRelationshipType);
|
||||
|
||||
// Mock DAO to return our mockedList
|
||||
when(relationshipTypeDAO.findAll(context, RelationshipType.class)).thenReturn(mockedList);
|
||||
when(relationshipTypeDAO.findAll(context, RelationshipType.class, -1, -1)).thenReturn(mockedList);
|
||||
|
||||
// Invoke findAll()
|
||||
List<RelationshipType> foundRelationshipTypes = relationshipTypeService.findAll(context);
|
||||
@@ -118,16 +118,16 @@ public class RelationshipTypeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelationshipTypeFindByLeftOrRightLabel() throws Exception {
|
||||
public void testRelationshipTypeFindByLeftOrRightwardType() throws Exception {
|
||||
// Declare objects utilized for this test
|
||||
List<RelationshipType> mockedList = new LinkedList<>();
|
||||
mockedList.add(firstRelationshipType);
|
||||
|
||||
// Mock DAO to return our mockedList
|
||||
when(relationshipTypeDAO.findByLeftOrRightLabel(any(), any())).thenReturn(mockedList);
|
||||
when(relationshipTypeDAO.findByLeftwardOrRightwardTypeName(context, "mock", -1, -1)).thenReturn(mockedList);
|
||||
|
||||
// Invoke findByLeftOrRightLabel()
|
||||
List<RelationshipType> found = relationshipTypeService.findByLeftOrRightLabel(context, "mock");
|
||||
// Invoke findByLeftwardOrRightwardTypeName()
|
||||
List<RelationshipType> found = relationshipTypeService.findByLeftwardOrRightwardTypeName(context, "mock");
|
||||
|
||||
// Assert that our expected list contains our expected RelationshipType and nothing more
|
||||
assertThat(found, notNullValue());
|
||||
@@ -142,10 +142,11 @@ public class RelationshipTypeTest {
|
||||
mockedList.add(firstRelationshipType);
|
||||
|
||||
// Mock DAO to return our mockedList
|
||||
when(relationshipTypeDAO.findByEntityType(any(), any())).thenReturn(mockedList);
|
||||
when(relationshipTypeDAO.findByEntityType(any(), any(), any(), any())).thenReturn(mockedList);
|
||||
|
||||
// Invoke findByEntityType()
|
||||
List<RelationshipType> found = relationshipTypeService.findByEntityType(context, mock(EntityType.class));
|
||||
List<RelationshipType> found = relationshipTypeService
|
||||
.findByEntityType(context, mock(EntityType.class), -1, -1);
|
||||
|
||||
// Assert that our expected list contains our expected RelationshipType and nothing more
|
||||
assertThat(found, notNullValue());
|
||||
@@ -160,8 +161,8 @@ public class RelationshipTypeTest {
|
||||
*/
|
||||
private void checkRelationshipTypeValues(RelationshipType found, RelationshipType original) {
|
||||
assertThat(found, notNullValue());
|
||||
assertThat(found.getLeftLabel(), equalTo(original.getLeftLabel()));
|
||||
assertThat(found.getRightLabel(), equalTo(original.getRightLabel()));
|
||||
assertThat(found.getLeftwardType(), equalTo(original.getLeftwardType()));
|
||||
assertThat(found.getRightwardType(), equalTo(original.getRightwardType()));
|
||||
assertThat(found.getLeftType(), equalTo(original.getLeftType()));
|
||||
assertThat(found.getRightType(), equalTo(original.getRightType()));
|
||||
assertThat(found.getLeftMinCardinality(), equalTo(original.getLeftMinCardinality()));
|
||||
|
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.AbstractIntegrationTest;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.EntityType;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.Relationship;
|
||||
import org.dspace.content.RelationshipType;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by: Andrew Wood
|
||||
* Date: 20 Sep 2019
|
||||
*/
|
||||
public class RelationshipDAOImplTest extends AbstractIntegrationTest {
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(RelationshipDAOImplTest.class);
|
||||
|
||||
private Relationship relationship;
|
||||
|
||||
private Item itemOne;
|
||||
|
||||
private Item itemTwo;
|
||||
|
||||
private Collection collection;
|
||||
|
||||
private Community owningCommunity;
|
||||
|
||||
private RelationshipType relationshipType;
|
||||
|
||||
private List<Relationship> relationshipsList = new ArrayList<>();
|
||||
|
||||
private EntityType entityTypeOne;
|
||||
|
||||
private EntityType entityTypeTwo;
|
||||
|
||||
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();
|
||||
protected RelationshipTypeService relationshipTypeService =
|
||||
ContentServiceFactory.getInstance().getRelationshipTypeService();
|
||||
protected RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||
protected EntityTypeService entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
|
||||
|
||||
/**
|
||||
* Initalize DSpace objects used for testing for each test
|
||||
*/
|
||||
@Before
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
try {
|
||||
// Create objects for testing
|
||||
context.turnOffAuthorisationSystem();
|
||||
owningCommunity = communityService.create(null, context);
|
||||
collection = collectionService.create(context, owningCommunity);
|
||||
WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false);
|
||||
WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false);
|
||||
itemOne = installItemService.installItem(context, workspaceItem);
|
||||
itemTwo = installItemService.installItem(context, workspaceItemTwo);
|
||||
itemService.addMetadata(context, itemOne, "relationship", "type", null, Item.ANY, "Publication");
|
||||
itemService.addMetadata(context, itemTwo, "relationship", "type", null, Item.ANY, "Person");
|
||||
itemService.update(context, itemOne);
|
||||
itemService.update(context, itemTwo);
|
||||
entityTypeOne = entityTypeService.create(context, "Person");
|
||||
entityTypeTwo = entityTypeService.create(context, "Publication");
|
||||
relationshipType = relationshipTypeService.create(context, entityTypeTwo, entityTypeOne,
|
||||
"isAuthorOfPublication", "isPublicationOfAuthor",0,10,0,10);
|
||||
relationship = relationshipService.create(context, itemOne, itemTwo, relationshipType, 0, 0);
|
||||
relationshipService.update(context, relationship);
|
||||
relationshipsList.add(relationship);
|
||||
context.restoreAuthSystemState();
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all initalized DSpace objects after each test
|
||||
*/
|
||||
@After
|
||||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
relationshipService.delete(context, relationship);
|
||||
relationshipTypeService.delete(context, relationshipType);
|
||||
entityTypeService.delete(context, entityTypeTwo);
|
||||
entityTypeService.delete(context, entityTypeOne);
|
||||
itemService.delete(context, itemOne);
|
||||
itemService.delete(context, itemTwo);
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findItem should return our defined relationshipsList given our test Item itemOne.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindByItem() throws Exception {
|
||||
assertEquals("TestFindByItem 0", relationshipsList, relationshipService.findByItem(context, itemOne, -1, -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findNextLeftPlaceByLeftItem should return 0 given our test left Item itemOne.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindNextLeftPlaceByLeftItem() throws Exception {
|
||||
assertEquals("TestNextLeftPlaceByLeftItem 0", 1, relationshipService.findNextLeftPlaceByLeftItem(context,
|
||||
itemOne));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findNextRightPlaceByRightItem should return 0 given our test right Item itemTwo.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindNextRightPlaceByRightItem() throws Exception {
|
||||
assertEquals("TestNextRightPlaceByRightItem 0", 1, relationshipService.findNextRightPlaceByRightItem(context,
|
||||
itemTwo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findByRelationshipType should return our defined relationshipsList given our test RelationshipType
|
||||
* relationshipType
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindByRelationshipType() throws Exception {
|
||||
assertEquals("TestByRelationshipType 0", relationshipsList, relationshipService.findByRelationshipType(context,
|
||||
relationshipType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test countTotal should return our defined relationshipsList's size given our test Context
|
||||
* context
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testCountRows() throws Exception {
|
||||
assertEquals("TestByRelationshipType 0", relationshipsList.size(), relationshipService.countTotal(context));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.AbstractIntegrationTest;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.EntityType;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.Relationship;
|
||||
import org.dspace.content.RelationshipType;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
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 RelationshipTypeDAOImplTest extends AbstractIntegrationTest {
|
||||
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(RelationshipTypeDAOImplTest.class);
|
||||
|
||||
private Relationship relationship;
|
||||
|
||||
private Item itemOne;
|
||||
|
||||
private Item itemTwo;
|
||||
|
||||
private Collection collection;
|
||||
|
||||
private Community owningCommunity;
|
||||
|
||||
private RelationshipType relationshipType;
|
||||
|
||||
private List<RelationshipType> relationshipTypeList = new ArrayList<>();
|
||||
|
||||
private EntityType entityTypeOne;
|
||||
|
||||
private EntityType entityTypeTwo;
|
||||
|
||||
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();
|
||||
protected RelationshipTypeService relationshipTypeService =
|
||||
ContentServiceFactory.getInstance().getRelationshipTypeService();
|
||||
protected RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
|
||||
protected EntityTypeService entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
|
||||
|
||||
/**
|
||||
* Initalize DSpace objects used for testing for each test
|
||||
*/
|
||||
@Before
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
owningCommunity = communityService.create(null, context);
|
||||
collection = collectionService.create(context, owningCommunity);
|
||||
WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false);
|
||||
WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false);
|
||||
itemOne = installItemService.installItem(context, workspaceItem);
|
||||
itemTwo = installItemService.installItem(context, workspaceItemTwo);
|
||||
itemService.addMetadata(context, itemOne, "relationship", "type", null, Item.ANY, "Publication");
|
||||
itemService.addMetadata(context, itemTwo, "relationship", "type", null, Item.ANY, "Person");
|
||||
itemService.update(context, itemOne);
|
||||
itemService.update(context, itemTwo);
|
||||
entityTypeOne = entityTypeService.create(context, "Person");
|
||||
entityTypeTwo = entityTypeService.create(context, "Publication");
|
||||
relationshipType = relationshipTypeService.create(context, entityTypeTwo, entityTypeOne,
|
||||
"isAuthorOfPublication", "isPublicationOfAuthor",0,10,0,10);
|
||||
relationship = relationshipService.create(context, itemOne, itemTwo, relationshipType, 0, 0);
|
||||
relationshipService.update(context, relationship);
|
||||
relationshipTypeList.add(relationshipType);
|
||||
context.restoreAuthSystemState();
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all initalized DSpace objects after each test
|
||||
*/
|
||||
@After
|
||||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
// Cleanup newly created objects
|
||||
context.turnOffAuthorisationSystem();
|
||||
relationshipService.delete(context, relationship);
|
||||
relationshipTypeService.delete(context, relationshipType);
|
||||
entityTypeService.delete(context, entityTypeTwo);
|
||||
entityTypeService.delete(context, entityTypeOne);
|
||||
itemService.delete(context, itemOne);
|
||||
itemService.delete(context, itemTwo);
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findbyTypesAndLabels should return our defined RelationshipType given our test Entities entityTypeTwo and
|
||||
* entityTypeOne with the affiliated labels isAuthorOfPublication and isPublicationOfAuthor
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindByTypesAndLabels() throws Exception {
|
||||
assertEquals("TestFindbyTypesAndLabels 0", relationshipType, relationshipTypeService
|
||||
.findbyTypesAndTypeName(context, entityTypeTwo, entityTypeOne, "isAuthorOfPublication",
|
||||
"isPublicationOfAuthor"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findByLeftOrRightLabel should return our defined relationshipTypeList given one of our affiliated labels
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindByLeftOrRightLabel() throws Exception {
|
||||
assertEquals("TestFindByLeftOrRightLabel 0", relationshipTypeList, relationshipTypeService.
|
||||
findByLeftwardOrRightwardTypeName(context, "isAuthorOfPublication", -1, -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test findByEntityType should return our defined relationshipsList given one our defined EntityTypes
|
||||
* entityTypeOne
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFindByEntityType() throws Exception {
|
||||
assertEquals("TestFindByEntityType 0", relationshipTypeList, relationshipTypeService.findByEntityType(context,
|
||||
entityTypeOne));
|
||||
}
|
||||
}
|
@@ -124,15 +124,15 @@ public class RelatedTest {
|
||||
Entity entity = mock(Entity.class);
|
||||
EntityType entityType = mock(EntityType.class);
|
||||
RelationshipType relationshipType = mock(RelationshipType.class);
|
||||
related.setRelationshipTypeString("LeftLabel");
|
||||
related.setRelationshipTypeString("LeftwardType");
|
||||
relationshipTypeList.add(relationshipType);
|
||||
relationshipList.add(relationship);
|
||||
related.setPlace(0);
|
||||
|
||||
// Mock the state of objects utilized in getRelationsByLabel() to meet the success criteria of an invocation
|
||||
when(item.getID()).thenReturn(UUID.randomUUID());
|
||||
when(relationshipType.getLeftLabel()).thenReturn("LeftLabel");
|
||||
when(relationshipType.getRightLabel()).thenReturn("RightLabel");
|
||||
when(relationshipType.getLeftwardType()).thenReturn("LeftwardType");
|
||||
when(relationshipType.getRightwardType()).thenReturn("RightwardType");
|
||||
when(relationshipType.getLeftType()).thenReturn(entityType);
|
||||
when(relationshipType.getRightType()).thenReturn(entityType);
|
||||
when(entityService.getAllRelationshipTypes(context, entity)).thenReturn(relationshipTypeList);
|
||||
|
@@ -62,15 +62,15 @@ public class VirtualMetadataPopulatorTest {
|
||||
HashMap<String, VirtualMetadataConfiguration> mapExt = new HashMap<>();
|
||||
VirtualMetadataConfiguration virtualMetadataConfiguration = mock(VirtualMetadataConfiguration.class);
|
||||
mapExt.put("hashKey", virtualMetadataConfiguration);
|
||||
map.put("LeftLabel", mapExt);
|
||||
map.put("NotRightLabel", mapExt);
|
||||
map.put("LeftwardType", mapExt);
|
||||
map.put("NotRightwardType", mapExt);
|
||||
virtualMetadataPopulator.setMap(map);
|
||||
|
||||
// Mock the state of objects utilized in isUseForPlaceTrueForRelationshipType()
|
||||
// to meet the success criteria of an invocation
|
||||
when(virtualMetadataConfiguration.getUseForPlace()).thenReturn(true);
|
||||
when(relationshipType.getLeftLabel()).thenReturn("LeftLabel");
|
||||
when(relationshipType.getRightLabel()).thenReturn("RightLabel");
|
||||
when(relationshipType.getLeftwardType()).thenReturn("LeftwardType");
|
||||
when(relationshipType.getRightwardType()).thenReturn("RightwardType");
|
||||
|
||||
// Assert that the useForPlace for our mocked relationshipType is false
|
||||
assertEquals("TestGetFields 0", false,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user