mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 07:23:08 +00:00
Merge branch 'master' into DS-4042_ITs_WrongPatchRequest
This commit is contained in:
7
.github/pull_request_template.md
vendored
7
.github/pull_request_template.md
vendored
@@ -20,11 +20,8 @@ List of changes in this PR:
|
|||||||
_This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!_
|
_This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!_
|
||||||
|
|
||||||
- [ ] My PR is small in size (e.g. less than 1,000 lines of code, not including comments & integration tests). Exceptions may be made if previously agreed upon.
|
- [ ] My PR is small in size (e.g. less than 1,000 lines of code, not including comments & integration tests). Exceptions may be made if previously agreed upon.
|
||||||
- [ ] My PR passes Checkstyle validation based on the [Code Style Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Style+Guide)
|
- [ ] My PR passes Checkstyle validation based on the [Code Style Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Style+Guide).
|
||||||
- [ ] My PR includes Javadoc for _all new (or modified) public methods and classes_. It also includes Javadoc for large or complex private methods.
|
- [ ] My PR includes Javadoc for _all new (or modified) public methods and classes_. It also includes Javadoc for large or complex private methods.
|
||||||
- [ ] My PR passes all tests and includes new/updated Unit or Integration Tests for any bug fixes, improvements or new features. A few reminders about what constitutes good tests:
|
- [ ] My PR passes all tests and includes new/updated Unit or Integration Tests based on the [Code Testing Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Testing+Guide).
|
||||||
* Include tests for different user types, including: (1) Anonymous user, (2) Logged in user (non-admin), and (3) Administrator.
|
|
||||||
* Include tests for known error scenarios and error codes (e.g. `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, etc)
|
|
||||||
* For bug fixes, include a test that reproduces the bug and proves it is fixed. For clarity, it may be useful to provide the test in a separate commit from the bug fix.
|
|
||||||
- [ ] If my PR includes new, third-party dependencies (in any `pom.xml`), I've made sure their licenses align with the [DSpace BSD License](https://github.com/DSpace/DSpace/blob/master/LICENSE) based on the [Licensing of Contributions](https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines#CodeContributionGuidelines-LicensingofContributions) documentation.
|
- [ ] If my PR includes new, third-party dependencies (in any `pom.xml`), I've made sure their licenses align with the [DSpace BSD License](https://github.com/DSpace/DSpace/blob/master/LICENSE) based on the [Licensing of Contributions](https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines#CodeContributionGuidelines-LicensingofContributions) documentation.
|
||||||
- [ ] If my PR modifies the REST API, I've linked to the REST Contract page (or open PR) related to this change.
|
- [ ] If my PR modifies the REST API, I've linked to the REST Contract page (or open PR) related to this change.
|
||||||
|
@@ -98,20 +98,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Verify OS license headers for all source code files -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.mycila</groupId>
|
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/src/test/resources/**</exclude>
|
|
||||||
<exclude>**/src/test/data/**</exclude>
|
|
||||||
<exclude>**/.gitignore</exclude>
|
|
||||||
<exclude>**/src/main/resources/rebel.xml</exclude>
|
|
||||||
<exclude>src/test/data/dspaceFolder/config/spiders/**</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
@@ -8,14 +8,10 @@
|
|||||||
package org.dspace.app.bulkedit;
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.InputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -27,6 +23,7 @@ import java.util.UUID;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.authority.AuthorityValue;
|
import org.dspace.authority.AuthorityValue;
|
||||||
import org.dspace.authority.factory.AuthorityServiceFactory;
|
import org.dspace.authority.factory.AuthorityServiceFactory;
|
||||||
@@ -141,18 +138,18 @@ public class DSpaceCSV implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Create a new instance, reading the lines in from file
|
* Create a new instance, reading the lines in from file
|
||||||
*
|
*
|
||||||
* @param f The file to read from
|
* @param inputStream the inputstream to read from
|
||||||
* @param c The DSpace Context
|
* @param c The DSpace Context
|
||||||
* @throws Exception thrown if there is an error reading or processing the file
|
* @throws Exception thrown if there is an error reading or processing the file
|
||||||
*/
|
*/
|
||||||
public DSpaceCSV(File f, Context c) throws Exception {
|
public DSpaceCSV(InputStream inputStream, Context c) throws Exception {
|
||||||
// Initialise the class
|
// Initialise the class
|
||||||
init();
|
init();
|
||||||
|
|
||||||
// Open the CSV file
|
// Open the CSV file
|
||||||
BufferedReader input = null;
|
BufferedReader input = null;
|
||||||
try {
|
try {
|
||||||
input = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
|
input = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||||
|
|
||||||
// Read the heading line
|
// Read the heading line
|
||||||
String head = input.readLine();
|
String head = input.readLine();
|
||||||
@@ -623,21 +620,15 @@ public class DSpaceCSV implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the CSV file to the given filename
|
* Creates and returns an InputStream from the CSV Lines in this DSpaceCSV
|
||||||
*
|
* @return The InputStream created from the CSVLines in this DSpaceCSV
|
||||||
* @param filename The filename to save the CSV file to
|
|
||||||
* @throws IOException Thrown if an error occurs when writing the file
|
|
||||||
*/
|
*/
|
||||||
public final void save(String filename) throws IOException {
|
public InputStream getInputStream() {
|
||||||
// Save the file
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
BufferedWriter out = new BufferedWriter(
|
|
||||||
new OutputStreamWriter(
|
|
||||||
new FileOutputStream(filename), "UTF-8"));
|
|
||||||
for (String csvLine : getCSVLinesAsStringArray()) {
|
for (String csvLine : getCSVLinesAsStringArray()) {
|
||||||
out.write(csvLine + "\n");
|
stringBuilder.append(csvLine + "\n");
|
||||||
}
|
}
|
||||||
out.flush();
|
return IOUtils.toInputStream(stringBuilder.toString(), StandardCharsets.UTF_8);
|
||||||
out.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -8,271 +8,84 @@
|
|||||||
package org.dspace.app.bulkedit;
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterators;
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.commons.cli.PosixParser;
|
import org.dspace.content.service.MetadataDSpaceCsvExportService;
|
||||||
import org.dspace.content.Collection;
|
|
||||||
import org.dspace.content.Community;
|
|
||||||
import org.dspace.content.DSpaceObject;
|
|
||||||
import org.dspace.content.Item;
|
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
|
||||||
import org.dspace.content.service.ItemService;
|
|
||||||
import org.dspace.core.Constants;
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.handle.factory.HandleServiceFactory;
|
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||||
|
import org.dspace.eperson.service.EPersonService;
|
||||||
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata exporter to allow the batch export of metadata into a file
|
* Metadata exporter to allow the batch export of metadata into a file
|
||||||
*
|
*
|
||||||
* @author Stuart Lewis
|
* @author Stuart Lewis
|
||||||
*/
|
*/
|
||||||
public class MetadataExport {
|
public class MetadataExport extends DSpaceRunnable<MetadataExportScriptConfiguration> {
|
||||||
/**
|
|
||||||
* The items to export
|
|
||||||
*/
|
|
||||||
protected Iterator<Item> toExport;
|
|
||||||
|
|
||||||
protected ItemService itemService;
|
private boolean help = false;
|
||||||
|
private String filename = null;
|
||||||
|
private String handle = null;
|
||||||
|
private boolean exportAllMetadata = false;
|
||||||
|
private boolean exportAllItems = false;
|
||||||
|
|
||||||
protected Context context;
|
private static final String EXPORT_CSV = "exportCSV";
|
||||||
|
|
||||||
/**
|
private MetadataDSpaceCsvExportService metadataDSpaceCsvExportService = new DSpace().getServiceManager()
|
||||||
* Whether to export all metadata, or just normally edited metadata
|
.getServicesByType(MetadataDSpaceCsvExportService.class).get(0);
|
||||||
*/
|
|
||||||
protected boolean exportAll;
|
|
||||||
|
|
||||||
protected MetadataExport() {
|
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Set up a new metadata export
|
public void internalRun() throws Exception {
|
||||||
*
|
|
||||||
* @param c The Context
|
|
||||||
* @param toExport The ItemIterator of items to export
|
|
||||||
* @param exportAll whether to export all metadata or not (include handle, provenance etc)
|
|
||||||
*/
|
|
||||||
public MetadataExport(Context c, Iterator<Item> toExport, boolean exportAll) {
|
|
||||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
|
||||||
|
|
||||||
// Store the export settings
|
|
||||||
this.toExport = toExport;
|
|
||||||
this.exportAll = exportAll;
|
|
||||||
this.context = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to export a community (and sub-communities and collections)
|
|
||||||
*
|
|
||||||
* @param c The Context
|
|
||||||
* @param toExport The Community to export
|
|
||||||
* @param exportAll whether to export all metadata or not (include handle, provenance etc)
|
|
||||||
*/
|
|
||||||
public MetadataExport(Context c, Community toExport, boolean exportAll) {
|
|
||||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
handler.logInfo("\nfull export: metadata-export -f filename");
|
||||||
|
handler.logInfo("partial export: metadata-export -i handle -f filename");
|
||||||
|
printHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Context context = new Context();
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
try {
|
try {
|
||||||
// Try to export the community
|
context.setCurrentUser(ePersonService.find(context, this.getEpersonIdentifier()));
|
||||||
this.toExport = buildFromCommunity(c, toExport, 0);
|
} catch (SQLException e) {
|
||||||
this.exportAll = exportAll;
|
handler.handleException(e);
|
||||||
this.context = c;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
// Something went wrong...
|
|
||||||
System.err.println("Error running exporter:");
|
|
||||||
sqle.printStackTrace(System.err);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
|
DSpaceCSV dSpaceCSV = metadataDSpaceCsvExportService
|
||||||
|
.handleExport(context, exportAllItems, exportAllMetadata, handle,
|
||||||
|
handler);
|
||||||
|
handler.writeFilestream(context, filename, dSpaceCSV.getInputStream(), EXPORT_CSV);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
context.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Build an array list of item ids that are in a community (include sub-communities and collections)
|
public MetadataExportScriptConfiguration getScriptConfiguration() {
|
||||||
*
|
return new DSpace().getServiceManager().getServiceByName("metadata-export",
|
||||||
* @param context DSpace context
|
MetadataExportScriptConfiguration.class);
|
||||||
* @param community The community to build from
|
|
||||||
* @param indent How many spaces to use when writing out the names of items added
|
|
||||||
* @return The list of item ids
|
|
||||||
* @throws SQLException if database error
|
|
||||||
*/
|
|
||||||
protected Iterator<Item> buildFromCommunity(Context context, Community community, int indent)
|
|
||||||
throws SQLException {
|
|
||||||
// Add all the collections
|
|
||||||
List<Collection> collections = community.getCollections();
|
|
||||||
Iterator<Item> result = null;
|
|
||||||
for (Collection collection : collections) {
|
|
||||||
for (int i = 0; i < indent; i++) {
|
|
||||||
System.out.print(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<Item> items = itemService.findByCollection(context, collection);
|
|
||||||
result = addItemsToResult(result, items);
|
|
||||||
|
|
||||||
}
|
|
||||||
// Add all the sub-communities
|
|
||||||
List<Community> communities = community.getSubcommunities();
|
|
||||||
for (Community subCommunity : communities) {
|
|
||||||
for (int i = 0; i < indent; i++) {
|
|
||||||
System.out.print(" ");
|
|
||||||
}
|
|
||||||
Iterator<Item> items = buildFromCommunity(context, subCommunity, indent + 1);
|
|
||||||
result = addItemsToResult(result, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterator<Item> addItemsToResult(Iterator<Item> result, Iterator<Item> items) {
|
@Override
|
||||||
if (result == null) {
|
public void setup() throws ParseException {
|
||||||
result = items;
|
|
||||||
} else {
|
|
||||||
result = Iterators.concat(result, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
if (commandLine.hasOption('h')) {
|
||||||
}
|
help = true;
|
||||||
|
return;
|
||||||
/**
|
|
||||||
* Run the export
|
|
||||||
*
|
|
||||||
* @return the exported CSV lines
|
|
||||||
*/
|
|
||||||
public DSpaceCSV export() {
|
|
||||||
try {
|
|
||||||
Context.Mode originalMode = context.getCurrentMode();
|
|
||||||
context.setMode(Context.Mode.READ_ONLY);
|
|
||||||
|
|
||||||
// Process each item
|
|
||||||
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
|
||||||
while (toExport.hasNext()) {
|
|
||||||
Item item = toExport.next();
|
|
||||||
csv.addItem(item);
|
|
||||||
context.uncacheEntity(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.setMode(originalMode);
|
|
||||||
// Return the results
|
|
||||||
return csv;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Something went wrong...
|
|
||||||
System.err.println("Error exporting to CSV:");
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the help message
|
|
||||||
*
|
|
||||||
* @param options The command line options the user gave
|
|
||||||
* @param exitCode the system exit code to use
|
|
||||||
*/
|
|
||||||
private static void printHelp(Options options, int exitCode) {
|
|
||||||
// print the help message
|
|
||||||
HelpFormatter myhelp = new HelpFormatter();
|
|
||||||
myhelp.printHelp("MetadataExport\n", options);
|
|
||||||
System.out.println("\nfull export: metadataexport -f filename");
|
|
||||||
System.out.println("partial export: metadataexport -i handle -f filename");
|
|
||||||
System.exit(exitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* main method to run the metadata exporter
|
|
||||||
*
|
|
||||||
* @param argv the command line arguments given
|
|
||||||
* @throws Exception if error occurs
|
|
||||||
*/
|
|
||||||
public static void main(String[] argv) throws Exception {
|
|
||||||
// Create an options object and populate it
|
|
||||||
CommandLineParser parser = new PosixParser();
|
|
||||||
|
|
||||||
Options options = new Options();
|
|
||||||
|
|
||||||
options.addOption("i", "id", true, "ID or handle of thing to export (item, collection, or community)");
|
|
||||||
options.addOption("f", "file", true, "destination where you want file written");
|
|
||||||
options.addOption("a", "all", false,
|
|
||||||
"include all metadata fields that are not normally changed (e.g. provenance)");
|
|
||||||
options.addOption("h", "help", false, "help");
|
|
||||||
|
|
||||||
CommandLine line = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
line = parser.parse(options, argv);
|
|
||||||
} catch (ParseException pe) {
|
|
||||||
System.err.println("Error with commands.");
|
|
||||||
printHelp(options, 1);
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.hasOption('h')) {
|
|
||||||
printHelp(options, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check a filename is given
|
// Check a filename is given
|
||||||
if (!line.hasOption('f')) {
|
if (!commandLine.hasOption('f')) {
|
||||||
System.err.println("Required parameter -f missing!");
|
throw new ParseException("Required parameter -f missing!");
|
||||||
printHelp(options, 1);
|
|
||||||
}
|
}
|
||||||
String filename = line.getOptionValue('f');
|
filename = commandLine.getOptionValue('f');
|
||||||
|
|
||||||
// Create a context
|
exportAllMetadata = commandLine.hasOption('a');
|
||||||
Context c = new Context(Context.Mode.READ_ONLY);
|
|
||||||
c.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
// The things we'll export
|
if (!commandLine.hasOption('i')) {
|
||||||
Iterator<Item> toExport = null;
|
exportAllItems = true;
|
||||||
MetadataExport exporter = null;
|
|
||||||
|
|
||||||
// Export everything?
|
|
||||||
boolean exportAll = line.hasOption('a');
|
|
||||||
|
|
||||||
ContentServiceFactory contentServiceFactory = ContentServiceFactory.getInstance();
|
|
||||||
// Check we have an item OK
|
|
||||||
ItemService itemService = contentServiceFactory.getItemService();
|
|
||||||
if (!line.hasOption('i')) {
|
|
||||||
System.out.println("Exporting whole repository WARNING: May take some time!");
|
|
||||||
exporter = new MetadataExport(c, itemService.findAll(c), exportAll);
|
|
||||||
} else {
|
|
||||||
String handle = line.getOptionValue('i');
|
|
||||||
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService().resolveToObject(c, handle);
|
|
||||||
if (dso == null) {
|
|
||||||
System.err.println("Item '" + handle + "' does not resolve to an item in your repository!");
|
|
||||||
printHelp(options, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dso.getType() == Constants.ITEM) {
|
|
||||||
System.out.println("Exporting item '" + dso.getName() + "' (" + handle + ")");
|
|
||||||
List<Item> item = new ArrayList<>();
|
|
||||||
item.add((Item) dso);
|
|
||||||
exporter = new MetadataExport(c, item.iterator(), exportAll);
|
|
||||||
} else if (dso.getType() == Constants.COLLECTION) {
|
|
||||||
System.out.println("Exporting collection '" + dso.getName() + "' (" + handle + ")");
|
|
||||||
Collection collection = (Collection) dso;
|
|
||||||
toExport = itemService.findByCollection(c, collection);
|
|
||||||
exporter = new MetadataExport(c, toExport, exportAll);
|
|
||||||
} else if (dso.getType() == Constants.COMMUNITY) {
|
|
||||||
System.out.println("Exporting community '" + dso.getName() + "' (" + handle + ")");
|
|
||||||
exporter = new MetadataExport(c, (Community) dso, exportAll);
|
|
||||||
} else {
|
|
||||||
System.err.println("Error identifying '" + handle + "'");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
handle = commandLine.getOptionValue('i');
|
||||||
// Perform the export
|
|
||||||
DSpaceCSV csv = exporter.export();
|
|
||||||
|
|
||||||
// Save the files to the file
|
|
||||||
csv.save(filename);
|
|
||||||
|
|
||||||
// Finish off and tidy up
|
|
||||||
c.restoreAuthSystemState();
|
|
||||||
c.complete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ScriptConfiguration} for the {@link MetadataExport} script
|
||||||
|
*/
|
||||||
|
public class MetadataExportScriptConfiguration<T extends MetadataExport> extends ScriptConfiguration<T> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
private Class<T> dspaceRunnableClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getDspaceRunnableClass() {
|
||||||
|
return dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the dspaceRunnableClass
|
||||||
|
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this MetadataExportScriptConfiguration
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||||
|
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowedToExecute(Context context) {
|
||||||
|
try {
|
||||||
|
return authorizeService.isAdmin(context);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getOptions() {
|
||||||
|
if (options == null) {
|
||||||
|
Options options = new Options();
|
||||||
|
|
||||||
|
options.addOption("i", "id", true, "ID or handle of thing to export (item, collection, or community)");
|
||||||
|
options.getOption("i").setType(String.class);
|
||||||
|
options.addOption("f", "file", true, "destination where you want file written");
|
||||||
|
options.getOption("f").setType(OutputStream.class);
|
||||||
|
options.getOption("f").setRequired(true);
|
||||||
|
options.addOption("a", "all", false,
|
||||||
|
"include all metadata fields that are not normally changed (e.g. provenance)");
|
||||||
|
options.getOption("a").setType(boolean.class);
|
||||||
|
options.addOption("h", "help", false, "help");
|
||||||
|
options.getOption("h").setType(boolean.class);
|
||||||
|
|
||||||
|
|
||||||
|
super.options = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI variant for the {@link MetadataImport} class
|
||||||
|
* This has been made so that we can specify the behaviour of the determineChanges method to be specific for the CLI
|
||||||
|
*/
|
||||||
|
public class MetadataImportCLI extends MetadataImport {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean determineChange(DSpaceRunnableHandler handler) throws IOException {
|
||||||
|
handler.logInfo("Do you want to make these changes? [y/n] ");
|
||||||
|
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
|
||||||
|
String yn = bufferedReader.readLine();
|
||||||
|
if ("y".equalsIgnoreCase(yn)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ScriptConfiguration} for the {@link org.dspace.app.bulkedit.MetadataImportCLI} CLI script
|
||||||
|
*/
|
||||||
|
public class MetadataImportCliScriptConfiguration extends MetadataImportScriptConfiguration<MetadataImportCLI> {
|
||||||
|
}
|
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ScriptConfiguration} for the {@link MetadataImport} script
|
||||||
|
*/
|
||||||
|
public class MetadataImportScriptConfiguration<T extends MetadataImport> extends ScriptConfiguration<T> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
private Class<T> dspaceRunnableClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getDspaceRunnableClass() {
|
||||||
|
return dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the dspaceRunnableClass
|
||||||
|
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this MetadataImportScriptConfiguration
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||||
|
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowedToExecute(Context context) {
|
||||||
|
try {
|
||||||
|
return authorizeService.isAdmin(context);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getOptions() {
|
||||||
|
if (options == null) {
|
||||||
|
Options options = new Options();
|
||||||
|
|
||||||
|
options.addOption("f", "file", true, "source file");
|
||||||
|
options.getOption("f").setType(InputStream.class);
|
||||||
|
options.getOption("f").setRequired(true);
|
||||||
|
options.addOption("e", "email", true, "email address or user id of user (required if adding new items)");
|
||||||
|
options.getOption("e").setType(String.class);
|
||||||
|
options.getOption("e").setRequired(true);
|
||||||
|
options.addOption("s", "silent", false,
|
||||||
|
"silent operation - doesn't request confirmation of changes USE WITH CAUTION");
|
||||||
|
options.getOption("s").setType(boolean.class);
|
||||||
|
options.addOption("w", "workflow", false, "workflow - when adding new items, use collection workflow");
|
||||||
|
options.getOption("w").setType(boolean.class);
|
||||||
|
options.addOption("n", "notify", false,
|
||||||
|
"notify - when adding new items using a workflow, send notification emails");
|
||||||
|
options.getOption("n").setType(boolean.class);
|
||||||
|
options.addOption("v", "validate-only", false,
|
||||||
|
"validate - just validate the csv, don't run the import");
|
||||||
|
options.getOption("v").setType(boolean.class);
|
||||||
|
options.addOption("t", "template", false,
|
||||||
|
"template - when adding new items, use the collection template (if it exists)");
|
||||||
|
options.getOption("t").setType(boolean.class);
|
||||||
|
options.addOption("h", "help", false, "help");
|
||||||
|
options.getOption("h").setType(boolean.class);
|
||||||
|
|
||||||
|
super.options = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
@@ -16,9 +16,11 @@ import java.util.TreeMap;
|
|||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
import org.dspace.scripts.factory.ScriptServiceFactory;
|
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||||
|
import org.dspace.scripts.service.ScriptService;
|
||||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||||
import org.dspace.services.RequestService;
|
import org.dspace.services.RequestService;
|
||||||
@@ -44,7 +46,8 @@ public class ScriptLauncher {
|
|||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
private ScriptLauncher() { }
|
private ScriptLauncher() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the DSpace script launcher
|
* Execute the DSpace script launcher
|
||||||
@@ -54,7 +57,7 @@ public class ScriptLauncher {
|
|||||||
* @throws FileNotFoundException if file doesn't exist
|
* @throws FileNotFoundException if file doesn't exist
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
throws FileNotFoundException, IOException {
|
throws FileNotFoundException, IOException, IllegalAccessException, InstantiationException {
|
||||||
// Initialise the service manager kernel
|
// Initialise the service manager kernel
|
||||||
try {
|
try {
|
||||||
kernelImpl = DSpaceKernelInit.getKernel(null);
|
kernelImpl = DSpaceKernelInit.getKernel(null);
|
||||||
@@ -107,13 +110,18 @@ public class ScriptLauncher {
|
|||||||
* @param commandConfigs The Document
|
* @param commandConfigs The Document
|
||||||
* @param dSpaceRunnableHandler The DSpaceRunnableHandler for this execution
|
* @param dSpaceRunnableHandler The DSpaceRunnableHandler for this execution
|
||||||
* @param kernelImpl The relevant DSpaceKernelImpl
|
* @param kernelImpl The relevant DSpaceKernelImpl
|
||||||
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||||
*/
|
*/
|
||||||
public static int handleScript(String[] args, Document commandConfigs,
|
public static int handleScript(String[] args, Document commandConfigs,
|
||||||
DSpaceRunnableHandler dSpaceRunnableHandler,
|
DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||||
DSpaceKernelImpl kernelImpl) {
|
DSpaceKernelImpl kernelImpl) throws InstantiationException, IllegalAccessException {
|
||||||
int status;
|
int status;
|
||||||
DSpaceRunnable script = ScriptServiceFactory.getInstance().getScriptService().getScriptForName(args[0]);
|
ScriptService scriptService = ScriptServiceFactory.getInstance().getScriptService();
|
||||||
|
ScriptConfiguration scriptConfiguration = scriptService.getScriptConfiguration(args[0]);
|
||||||
|
DSpaceRunnable script = null;
|
||||||
|
if (scriptConfiguration != null) {
|
||||||
|
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
|
||||||
|
}
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
status = executeScript(args, dSpaceRunnableHandler, script);
|
status = executeScript(args, dSpaceRunnableHandler, script);
|
||||||
} else {
|
} else {
|
||||||
@@ -127,12 +135,12 @@ public class ScriptLauncher {
|
|||||||
* @param args The arguments of the script with the script name as first place in the array
|
* @param args The arguments of the script with the script name as first place in the array
|
||||||
* @param dSpaceRunnableHandler The relevant DSpaceRunnableHandler
|
* @param dSpaceRunnableHandler The relevant DSpaceRunnableHandler
|
||||||
* @param script The script to be executed
|
* @param script The script to be executed
|
||||||
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
* @return A 1 or 0 depending on whether the script failed or passed respectively
|
||||||
*/
|
*/
|
||||||
private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
|
private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||||
DSpaceRunnable script) {
|
DSpaceRunnable script) {
|
||||||
try {
|
try {
|
||||||
script.initialize(args, dSpaceRunnableHandler);
|
script.initialize(args, dSpaceRunnableHandler, null);
|
||||||
script.run();
|
script.run();
|
||||||
return 0;
|
return 0;
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
|
@@ -590,8 +590,11 @@ public class AuthorizeUtil {
|
|||||||
authorizeManageAdminGroup(context, collection);
|
authorizeManageAdminGroup(context, collection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if we reach this point, it means that the group is related
|
||||||
|
// to a collection but as it is not the submitters, nor the administrators,
|
||||||
|
// nor a workflow groups it must be a default item/bitstream groups
|
||||||
|
authorizeManageDefaultReadGroup(context, collection);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (parentObject.getType() == Constants.COMMUNITY) {
|
if (parentObject.getType() == Constants.COMMUNITY) {
|
||||||
Community community = (Community) parentObject;
|
Community community = (Community) parentObject;
|
||||||
@@ -601,4 +604,38 @@ public class AuthorizeUtil {
|
|||||||
|
|
||||||
throw new AuthorizeException("not authorized to manage this group");
|
throw new AuthorizeException("not authorized to manage this group");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if the community Admin can manage accounts
|
||||||
|
*
|
||||||
|
* @return true if is able
|
||||||
|
*/
|
||||||
|
public static boolean canCommunityAdminManageAccounts() {
|
||||||
|
boolean isAble = false;
|
||||||
|
if (AuthorizeConfiguration.canCommunityAdminManagePolicies()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageAdminGroup()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageCollectionPolicies()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageCollectionSubmitters()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup()) {
|
||||||
|
isAble = true;
|
||||||
|
}
|
||||||
|
return isAble;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if the Collection Admin can manage accounts
|
||||||
|
*
|
||||||
|
* @return true if is able
|
||||||
|
*/
|
||||||
|
public static boolean canCollectionAdminManageAccounts() {
|
||||||
|
boolean isAble = false;
|
||||||
|
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()
|
||||||
|
|| AuthorizeConfiguration.canCollectionAdminManageSubmitters()
|
||||||
|
|| AuthorizeConfiguration.canCollectionAdminManageWorkflows()
|
||||||
|
|| AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) {
|
||||||
|
isAble = true;
|
||||||
|
}
|
||||||
|
return isAble;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -430,7 +430,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
|
|
||||||
public boolean isCommunityAdmin(Context c) throws SQLException {
|
public boolean isCommunityAdmin(Context c) throws SQLException {
|
||||||
EPerson e = c.getCurrentUser();
|
EPerson e = c.getCurrentUser();
|
||||||
|
return isCommunityAdmin(c, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException {
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
||||||
groupService.allMemberGroups(c, e),
|
groupService.allMemberGroups(c, e),
|
||||||
@@ -446,7 +450,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
|
|
||||||
public boolean isCollectionAdmin(Context c) throws SQLException {
|
public boolean isCollectionAdmin(Context c) throws SQLException {
|
||||||
EPerson e = c.getCurrentUser();
|
EPerson e = c.getCurrentUser();
|
||||||
|
return isCollectionAdmin(c, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException {
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
|
||||||
groupService.allMemberGroups(c, e),
|
groupService.allMemberGroups(c, e),
|
||||||
|
@@ -213,6 +213,26 @@ public interface AuthorizeService {
|
|||||||
|
|
||||||
public boolean isCollectionAdmin(Context c) throws SQLException;
|
public boolean isCollectionAdmin(Context c) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if a specific user is Community admin
|
||||||
|
*
|
||||||
|
* @param c current context
|
||||||
|
* @param e the user to check
|
||||||
|
* @return true if user is an admin of some community
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if a specific user is Collection admin
|
||||||
|
*
|
||||||
|
* @param c current context
|
||||||
|
* @param e the user to check
|
||||||
|
* @return true if user is an admin of some collection
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException;
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// policy manipulation methods
|
// policy manipulation methods
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
@@ -17,11 +17,13 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||||
import org.dspace.app.util.AuthorizeUtil;
|
import org.dspace.app.util.AuthorizeUtil;
|
||||||
import org.dspace.authorize.AuthorizeConfiguration;
|
import org.dspace.authorize.AuthorizeConfiguration;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
@@ -40,6 +42,13 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.core.I18nUtil;
|
import org.dspace.core.I18nUtil;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
import org.dspace.core.service.LicenseService;
|
import org.dspace.core.service.LicenseService;
|
||||||
|
import org.dspace.discovery.DiscoverQuery;
|
||||||
|
import org.dspace.discovery.DiscoverResult;
|
||||||
|
import org.dspace.discovery.IndexableObject;
|
||||||
|
import org.dspace.discovery.SearchService;
|
||||||
|
import org.dspace.discovery.SearchServiceException;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
import org.dspace.eperson.service.GroupService;
|
import org.dspace.eperson.service.GroupService;
|
||||||
import org.dspace.eperson.service.SubscribeService;
|
import org.dspace.eperson.service.SubscribeService;
|
||||||
@@ -100,6 +109,9 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected CollectionRoleService collectionRoleService;
|
protected CollectionRoleService collectionRoleService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected SearchService searchService;
|
||||||
|
|
||||||
protected CollectionServiceImpl() {
|
protected CollectionServiceImpl() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -907,4 +919,77 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Collection> findCollectionsWithSubmit(String q, Context context, Community community,
|
||||||
|
int offset, int limit) throws SQLException, SearchServiceException {
|
||||||
|
|
||||||
|
List<Collection> collections = new ArrayList<Collection>();
|
||||||
|
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||||
|
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||||
|
discoverQuery.setStart(offset);
|
||||||
|
discoverQuery.setMaxResults(limit);
|
||||||
|
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community, q);
|
||||||
|
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
||||||
|
Collection c = ((IndexableCollection) solrCollections).getIndexedObject();
|
||||||
|
collections.add(c);
|
||||||
|
}
|
||||||
|
return collections;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countCollectionsWithSubmit(String q, Context context, Community community)
|
||||||
|
throws SQLException, SearchServiceException {
|
||||||
|
|
||||||
|
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||||
|
discoverQuery.setMaxResults(0);
|
||||||
|
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||||
|
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community,q);
|
||||||
|
return (int)resp.getTotalSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all Indexed Collections where the current user has submit rights. If the user is an Admin,
|
||||||
|
* this is all Indexed Collections. Otherwise, it includes those collections where
|
||||||
|
* an indexed "submit" policy lists either the eperson or one of the eperson's groups
|
||||||
|
*
|
||||||
|
* @param context DSpace context
|
||||||
|
* @param discoverQuery
|
||||||
|
* @param community parent community, could be null
|
||||||
|
* @param q limit the returned collection to those with metadata values matching the query
|
||||||
|
* terms. The terms are used to make also a prefix query on SOLR
|
||||||
|
* so it can be used to implement an autosuggest feature over the collection name
|
||||||
|
* @return discovery search result objects
|
||||||
|
* @throws SQLException if something goes wrong
|
||||||
|
* @throws SearchServiceException if search error
|
||||||
|
*/
|
||||||
|
private DiscoverResult retrieveCollectionsWithSubmit(Context context, DiscoverQuery discoverQuery,
|
||||||
|
Community community, String q) throws SQLException, SearchServiceException {
|
||||||
|
|
||||||
|
StringBuilder query = new StringBuilder();
|
||||||
|
EPerson currentUser = context.getCurrentUser();
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
String userId = "";
|
||||||
|
if (currentUser != null) {
|
||||||
|
userId = currentUser.getID().toString();
|
||||||
|
}
|
||||||
|
query.append("submit:(e").append(userId);
|
||||||
|
Set<Group> groups = groupService.allMemberGroupsSet(context, currentUser);
|
||||||
|
for (Group group : groups) {
|
||||||
|
query.append(" OR g").append(group.getID());
|
||||||
|
}
|
||||||
|
query.append(")");
|
||||||
|
discoverQuery.addFilterQueries(query.toString());
|
||||||
|
}
|
||||||
|
if (community != null) {
|
||||||
|
discoverQuery.addFilterQueries("location.comm:" + community.getID().toString());
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(q)) {
|
||||||
|
StringBuilder buildQuery = new StringBuilder();
|
||||||
|
String escapedQuery = ClientUtils.escapeQueryChars(q);
|
||||||
|
buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*");
|
||||||
|
discoverQuery.setQuery(buildQuery.toString());
|
||||||
|
}
|
||||||
|
DiscoverResult resp = searchService.search(context, discoverQuery);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* 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.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
import org.dspace.app.bulkedit.DSpaceCSV;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.MetadataDSpaceCsvExportService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link MetadataDSpaceCsvExportService}
|
||||||
|
*/
|
||||||
|
public class MetadataDSpaceCsvExportServiceImpl implements MetadataDSpaceCsvExportService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ItemService itemService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DSpaceCSV handleExport(Context context, boolean exportAllItems, boolean exportAllMetadata, String handle,
|
||||||
|
DSpaceRunnableHandler handler) throws Exception {
|
||||||
|
Iterator<Item> toExport = null;
|
||||||
|
|
||||||
|
if (exportAllItems) {
|
||||||
|
handler.logInfo("Exporting whole repository WARNING: May take some time!");
|
||||||
|
toExport = itemService.findAll(context);
|
||||||
|
} else {
|
||||||
|
DSpaceObject dso = HandleServiceFactory.getInstance().getHandleService().resolveToObject(context, handle);
|
||||||
|
if (dso == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Item '" + handle + "' does not resolve to an item in your repository!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dso.getType() == Constants.ITEM) {
|
||||||
|
handler.logInfo("Exporting item '" + dso.getName() + "' (" + handle + ")");
|
||||||
|
List<Item> item = new ArrayList<>();
|
||||||
|
item.add((Item) dso);
|
||||||
|
toExport = item.iterator();
|
||||||
|
} else if (dso.getType() == Constants.COLLECTION) {
|
||||||
|
handler.logInfo("Exporting collection '" + dso.getName() + "' (" + handle + ")");
|
||||||
|
Collection collection = (Collection) dso;
|
||||||
|
toExport = itemService.findByCollection(context, collection);
|
||||||
|
} else if (dso.getType() == Constants.COMMUNITY) {
|
||||||
|
handler.logInfo("Exporting community '" + dso.getName() + "' (" + handle + ")");
|
||||||
|
toExport = buildFromCommunity(context, (Community) dso);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Error identifying '" + handle + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DSpaceCSV csv = this.export(context, toExport, exportAllMetadata);
|
||||||
|
return csv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DSpaceCSV export(Context context, Iterator<Item> toExport, boolean exportAll) throws Exception {
|
||||||
|
Context.Mode originalMode = context.getCurrentMode();
|
||||||
|
context.setMode(Context.Mode.READ_ONLY);
|
||||||
|
|
||||||
|
// Process each item
|
||||||
|
DSpaceCSV csv = new DSpaceCSV(exportAll);
|
||||||
|
while (toExport.hasNext()) {
|
||||||
|
Item item = toExport.next();
|
||||||
|
csv.addItem(item);
|
||||||
|
context.uncacheEntity(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.setMode(originalMode);
|
||||||
|
// Return the results
|
||||||
|
return csv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DSpaceCSV export(Context context, Community community, boolean exportAll) throws Exception {
|
||||||
|
return export(context, buildFromCommunity(context, community), exportAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an array list of item ids that are in a community (include sub-communities and collections)
|
||||||
|
*
|
||||||
|
* @param context DSpace context
|
||||||
|
* @param community The community to build from
|
||||||
|
* @return The list of item ids
|
||||||
|
* @throws SQLException if database error
|
||||||
|
*/
|
||||||
|
private Iterator<Item> buildFromCommunity(Context context, Community community)
|
||||||
|
throws SQLException {
|
||||||
|
// Add all the collections
|
||||||
|
List<Collection> collections = community.getCollections();
|
||||||
|
Iterator<Item> result = null;
|
||||||
|
for (Collection collection : collections) {
|
||||||
|
Iterator<Item> items = itemService.findByCollection(context, collection);
|
||||||
|
result = addItemsToResult(result, items);
|
||||||
|
|
||||||
|
}
|
||||||
|
// Add all the sub-communities
|
||||||
|
List<Community> communities = community.getSubcommunities();
|
||||||
|
for (Community subCommunity : communities) {
|
||||||
|
Iterator<Item> items = buildFromCommunity(context, subCommunity);
|
||||||
|
result = addItemsToResult(result, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterator<Item> addItemsToResult(Iterator<Item> result, Iterator<Item> items) {
|
||||||
|
if (result == null) {
|
||||||
|
result = items;
|
||||||
|
} else {
|
||||||
|
result = Iterators.concat(result, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@@ -20,8 +20,10 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.discovery.SearchServiceException;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service interface class for the Collection object.
|
* Service interface class for the Collection object.
|
||||||
* The implementation of this class is responsible for all business logic calls for the Collection object and is
|
* The implementation of this class is responsible for all business logic calls for the Collection object and is
|
||||||
@@ -354,4 +356,42 @@ public interface CollectionService
|
|||||||
*/
|
*/
|
||||||
Group createDefaultReadGroup(Context context, Collection collection, String typeOfGroupString, int defaultRead)
|
Group createDefaultReadGroup(Context context, Collection collection, String typeOfGroupString, int defaultRead)
|
||||||
throws SQLException, AuthorizeException;
|
throws SQLException, AuthorizeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Collections for which the current user has 'submit' privileges.
|
||||||
|
* NOTE: for better performance, this method retrieves its results from an
|
||||||
|
* index (cache) and does not query the database directly.
|
||||||
|
* This means that results may be stale or outdated until DS-4524 is resolved"
|
||||||
|
*
|
||||||
|
* @param q limit the returned collection to those with metadata values matching the query terms.
|
||||||
|
* The terms are used to make also a prefix query on SOLR so it can be used to implement
|
||||||
|
* an autosuggest feature over the collection name
|
||||||
|
* @param context DSpace Context
|
||||||
|
* @param community parent community
|
||||||
|
* @param offset the position of the first result to return
|
||||||
|
* @param limit paging limit
|
||||||
|
* @return discovery search result objects
|
||||||
|
* @throws SQLException if something goes wrong
|
||||||
|
* @throws SearchServiceException if search error
|
||||||
|
*/
|
||||||
|
public List<Collection> findCollectionsWithSubmit(String q, Context context, Community community,
|
||||||
|
int offset, int limit) throws SQLException, SearchServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of Collection for which the current user has 'submit' privileges.
|
||||||
|
* NOTE: for better performance, this method retrieves its results from an index (cache)
|
||||||
|
* and does not query the database directly.
|
||||||
|
* This means that results may be stale or outdated until DS-4524 is resolved."
|
||||||
|
*
|
||||||
|
* @param q limit the returned collection to those with metadata values matching the query terms.
|
||||||
|
* The terms are used to make also a prefix query on SOLR so it can be used to implement
|
||||||
|
* an autosuggest feature over the collection name
|
||||||
|
* @param context DSpace Context
|
||||||
|
* @param community parent community
|
||||||
|
* @return total collections found
|
||||||
|
* @throws SQLException if something goes wrong
|
||||||
|
* @throws SearchServiceException if search error
|
||||||
|
*/
|
||||||
|
public int countCollectionsWithSubmit(String q, Context context, Community community)
|
||||||
|
throws SQLException, SearchServiceException;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.content.service;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.dspace.app.bulkedit.DSpaceCSV;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the interface to be implemented by a Service that deals with the exporting of Metadata
|
||||||
|
*/
|
||||||
|
public interface MetadataDSpaceCsvExportService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will export DSpaceObject objects depending on the parameters it gets. It can export all the items
|
||||||
|
* in the repository, all the items in a community, all the items in a collection or a specific item. The latter
|
||||||
|
* three are specified by the handle parameter. The entire repository can be exported by defining the
|
||||||
|
* exportAllItems parameter as true
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param exportAllItems A boolean indicating whether or not the entire repository should be exported
|
||||||
|
* @param exportAllMetadata Defines if all metadata should be exported or only the allowed ones
|
||||||
|
* @param handle The handle for the DSpaceObject to be exported, can be a Community, Collection or Item
|
||||||
|
* @return A DSpaceCSV object containing the exported information
|
||||||
|
* @throws Exception If something goes wrong
|
||||||
|
*/
|
||||||
|
public DSpaceCSV handleExport(Context context, boolean exportAllItems, boolean exportAllMetadata,
|
||||||
|
String handle, DSpaceRunnableHandler dSpaceRunnableHandler) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will export all the Items in the given toExport iterator to a DSpaceCSV
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param toExport The iterator containing the items to export
|
||||||
|
* @param exportAll Defines if all metadata should be exported or only the allowed ones
|
||||||
|
* @return A DSpaceCSV object containing the exported information
|
||||||
|
* @throws Exception If something goes wrong
|
||||||
|
*/
|
||||||
|
public DSpaceCSV export(Context context, Iterator<Item> toExport, boolean exportAll) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will export all the Items within the given Community to a DSpaceCSV
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param community The Community that contains the Items to be exported
|
||||||
|
* @param exportAll Defines if all metadata should be exported or only the allowed ones
|
||||||
|
* @return A DSpaceCSV object containing the exported information
|
||||||
|
* @throws Exception If something goes wrong
|
||||||
|
*/
|
||||||
|
public DSpaceCSV export(Context context, Community community, boolean exportAll) throws Exception;
|
||||||
|
|
||||||
|
}
|
@@ -14,7 +14,6 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
@@ -30,17 +29,18 @@ import org.dspace.discovery.indexobject.factory.IndexFactory;
|
|||||||
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
|
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
|
||||||
import org.dspace.handle.factory.HandleServiceFactory;
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to reindex dspace communities/collections/items into discovery
|
* Class used to reindex dspace communities/collections/items into discovery
|
||||||
*/
|
*/
|
||||||
public class IndexClient extends DSpaceRunnable {
|
public class IndexClient extends DSpaceRunnable<IndexDiscoveryScriptConfiguration> {
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
private IndexingService indexer = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
@Autowired
|
.getServiceByName(IndexingService.class.getName(),
|
||||||
private IndexingService indexer;
|
IndexingService.class);
|
||||||
|
|
||||||
private IndexClientOptions indexClientOptions;
|
private IndexClientOptions indexClientOptions;
|
||||||
|
|
||||||
@@ -144,6 +144,12 @@ public class IndexClient extends DSpaceRunnable {
|
|||||||
handler.logInfo("Done with indexing");
|
handler.logInfo("Done with indexing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IndexDiscoveryScriptConfiguration getScriptConfiguration() {
|
||||||
|
return new DSpace().getServiceManager().getServiceByName("index-discovery",
|
||||||
|
IndexDiscoveryScriptConfiguration.class);
|
||||||
|
}
|
||||||
|
|
||||||
public void setup() throws ParseException {
|
public void setup() throws ParseException {
|
||||||
try {
|
try {
|
||||||
context = new Context(Context.Mode.READ_ONLY);
|
context = new Context(Context.Mode.READ_ONLY);
|
||||||
@@ -151,18 +157,8 @@ public class IndexClient extends DSpaceRunnable {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ParseException("Unable to create a new DSpace Context: " + e.getMessage());
|
throw new ParseException("Unable to create a new DSpace Context: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
indexClientOptions = IndexClientOptions.getIndexClientOption(commandLine);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indexes the given object and all children, if applicable.
|
* Indexes the given object and all children, if applicable.
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ScriptConfiguration} for the {@link IndexClient} script
|
||||||
|
*/
|
||||||
|
public class IndexDiscoveryScriptConfiguration<T extends IndexClient> extends ScriptConfiguration<T> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
private Class<T> dspaceRunnableClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getDspaceRunnableClass() {
|
||||||
|
return dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowedToExecute(Context context) {
|
||||||
|
try {
|
||||||
|
return authorizeService.isAdmin(context);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getOptions() {
|
||||||
|
if (options == null) {
|
||||||
|
super.options = IndexClientOptions.constructOptions();
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the dspaceRunnableClass
|
||||||
|
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this IndexDiscoveryScriptConfiguration
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||||
|
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* 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 java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.LogManager;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this plugin is to index all ADD type resource policies related to collections.
|
||||||
|
*
|
||||||
|
* @author Mykhaylo Boychuk (at 4science.it)
|
||||||
|
*/
|
||||||
|
public class SolrServiceIndexCollectionSubmittersPlugin implements SolrServiceIndexPlugin {
|
||||||
|
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
|
.getLogger(SolrServiceIndexCollectionSubmittersPlugin.class);
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void additionalIndex(Context context, IndexableObject idxObj, SolrInputDocument document) {
|
||||||
|
if (idxObj instanceof IndexableCollection) {
|
||||||
|
Collection col = ((IndexableCollection) idxObj).getIndexedObject();
|
||||||
|
if (col != null) {
|
||||||
|
try {
|
||||||
|
String fieldValue = null;
|
||||||
|
Community parent = (Community) ContentServiceFactory.getInstance().getDSpaceObjectService(col)
|
||||||
|
.getParentObject(context, col);
|
||||||
|
while (parent != null) {
|
||||||
|
if (parent.getAdministrators() != null) {
|
||||||
|
fieldValue = "g" + parent.getAdministrators().getID();
|
||||||
|
document.addField("submit", fieldValue);
|
||||||
|
}
|
||||||
|
parent = (Community) ContentServiceFactory.getInstance().getDSpaceObjectService(parent)
|
||||||
|
.getParentObject(context, parent);
|
||||||
|
}
|
||||||
|
List<ResourcePolicy> policies = authorizeService.getPoliciesActionFilter(context, col,
|
||||||
|
Constants.ADD);
|
||||||
|
for (ResourcePolicy resourcePolicy : policies) {
|
||||||
|
if (resourcePolicy.getGroup() != null) {
|
||||||
|
fieldValue = "g" + resourcePolicy.getGroup().getID();
|
||||||
|
} else {
|
||||||
|
fieldValue = "e" + resourcePolicy.getEPerson().getID();
|
||||||
|
|
||||||
|
}
|
||||||
|
document.addField("submit", fieldValue);
|
||||||
|
context.uncacheEntity(resourcePolicy);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(LogManager.getHeader(context, "Error while indexing resource policies",
|
||||||
|
"Collection: (id " + col.getID() + " type " + col.getName() + ")" ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -23,7 +23,9 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.dspace.authorize.AuthorizeConfiguration;
|
import org.dspace.authorize.AuthorizeConfiguration;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.authorize.service.ResourcePolicyService;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.DSpaceObjectServiceImpl;
|
import org.dspace.content.DSpaceObjectServiceImpl;
|
||||||
@@ -76,6 +78,8 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
|||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected AuthorizeService authorizeService;
|
protected AuthorizeService authorizeService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected ResourcePolicyService resourcePolicyService;
|
||||||
|
|
||||||
protected GroupServiceImpl() {
|
protected GroupServiceImpl() {
|
||||||
super();
|
super();
|
||||||
@@ -654,6 +658,23 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
|||||||
return collectionService.getParentObject(context, collection);
|
return collectionService.getParentObject(context, collection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManagePolicies()
|
||||||
|
|| AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()) {
|
||||||
|
List<Group> groups = new ArrayList<Group>();
|
||||||
|
groups.add(group);
|
||||||
|
List<ResourcePolicy> policies = resourcePolicyService.find(context, null, groups,
|
||||||
|
Constants.DEFAULT_ITEM_READ, Constants.COLLECTION);
|
||||||
|
if (policies.size() > 0) {
|
||||||
|
return policies.get(0).getdSpaceObject();
|
||||||
|
}
|
||||||
|
policies = resourcePolicyService.find(context, null, groups,
|
||||||
|
Constants.DEFAULT_BITSTREAM_READ, Constants.COLLECTION);
|
||||||
|
if (policies.size() > 0) {
|
||||||
|
return policies.get(0).getdSpaceObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) {
|
if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) {
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
package org.dspace.license;
|
package org.dspace.license;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author wbossons
|
* @author wbossons
|
||||||
*/
|
*/
|
||||||
@@ -15,17 +17,17 @@ public class CCLicense {
|
|||||||
|
|
||||||
private String licenseName;
|
private String licenseName;
|
||||||
private String licenseId;
|
private String licenseId;
|
||||||
private int order = 0;
|
private List<CCLicenseField> ccLicenseFieldList;
|
||||||
|
|
||||||
public CCLicense() {
|
public CCLicense() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CCLicense(String licenseId, String licenseName, int order) {
|
public CCLicense(String licenseId, String licenseName, List<CCLicenseField> ccLicenseFieldList) {
|
||||||
super();
|
super();
|
||||||
this.licenseId = licenseId;
|
this.licenseId = licenseId;
|
||||||
this.licenseName = licenseName;
|
this.licenseName = licenseName;
|
||||||
this.order = order;
|
this.ccLicenseFieldList = ccLicenseFieldList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLicenseName() {
|
public String getLicenseName() {
|
||||||
@@ -44,13 +46,19 @@ public class CCLicense {
|
|||||||
this.licenseId = licenseId;
|
this.licenseId = licenseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOrder() {
|
/**
|
||||||
return this.order;
|
* Gets the list of CC License Fields
|
||||||
|
* @return the list of CC License Fields
|
||||||
|
*/
|
||||||
|
public List<CCLicenseField> getCcLicenseFieldList() {
|
||||||
|
return ccLicenseFieldList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrder(int order) {
|
/**
|
||||||
this.order = order;
|
* Sets the list of CC License Fields
|
||||||
|
* @param ccLicenseFieldList
|
||||||
|
*/
|
||||||
|
public void setCcLicenseFieldList(final List<CCLicenseField> ccLicenseFieldList) {
|
||||||
|
this.ccLicenseFieldList = ccLicenseFieldList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.license;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jdom.Document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service interface class for the Creative commons license connector service.
|
||||||
|
* The implementation of this class is responsible for all the calls to the CC license API and parsing the response
|
||||||
|
* The service is autowired by spring
|
||||||
|
*/
|
||||||
|
public interface CCLicenseConnectorService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the CC Licenses for the provided language from the CC License API
|
||||||
|
*
|
||||||
|
* @param language - the language to retrieve the licenses for
|
||||||
|
* @return a map of licenses with the id and the license for the provided language
|
||||||
|
*/
|
||||||
|
public Map<String, CCLicense> retrieveLicenses(String language);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI based on the provided license id, language and answers to the field questions from
|
||||||
|
* the CC License API
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the CC License URI
|
||||||
|
*/
|
||||||
|
public String retrieveRightsByQuestion(String licenseId,
|
||||||
|
String language,
|
||||||
|
Map<String, String> answerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the license RDF document based on the license URI
|
||||||
|
*
|
||||||
|
* @param licenseURI - The license URI for which to retrieve the license RDF document
|
||||||
|
* @return the license RDF document
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the license Name from the license document
|
||||||
|
*
|
||||||
|
* @param doc - The license document from which to retrieve the license name
|
||||||
|
* @return the license name
|
||||||
|
*/
|
||||||
|
public String retrieveLicenseName(final Document doc);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,371 @@
|
|||||||
|
/**
|
||||||
|
* 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.license;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.jaxen.JaxenException;
|
||||||
|
import org.jaxen.jdom.JDOMXPath;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for the Creative commons license connector service.
|
||||||
|
* This class is responsible for all the calls to the CC license API and parsing the response
|
||||||
|
*/
|
||||||
|
public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService, InitializingBean {
|
||||||
|
|
||||||
|
private Logger log = org.apache.logging.log4j.LogManager.getLogger(CCLicenseConnectorServiceImpl.class);
|
||||||
|
|
||||||
|
private CloseableHttpClient client;
|
||||||
|
protected SAXBuilder parser = new SAXBuilder();
|
||||||
|
|
||||||
|
private String postArgument = "answers";
|
||||||
|
private String postAnswerFormat =
|
||||||
|
"<answers> " +
|
||||||
|
"<locale>{1}</locale>" +
|
||||||
|
"<license-{0}>" +
|
||||||
|
"{2}" +
|
||||||
|
"</license-{0}>" +
|
||||||
|
"</answers>";
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||||
|
|
||||||
|
client = builder
|
||||||
|
.disableAutomaticRetries()
|
||||||
|
.setMaxConnTotal(5)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the CC Licenses for the provided language from the CC License API
|
||||||
|
*
|
||||||
|
* @param language - the language to retrieve the licenses for
|
||||||
|
* @return a map of licenses with the id and the license for the provided language
|
||||||
|
*/
|
||||||
|
public Map<String, CCLicense> retrieveLicenses(String language) {
|
||||||
|
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
||||||
|
|
||||||
|
String uri = ccLicenseUrl + "/?locale=" + language;
|
||||||
|
HttpGet httpGet = new HttpGet(uri);
|
||||||
|
|
||||||
|
List<String> licenses;
|
||||||
|
try (CloseableHttpResponse response = client.execute(httpGet)) {
|
||||||
|
licenses = retrieveLicenses(response);
|
||||||
|
} catch (JDOMException | JaxenException | IOException e) {
|
||||||
|
log.error("Error while retrieving the license details using url: " + uri, e);
|
||||||
|
licenses = Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, CCLicense> ccLicenses = new HashMap<>();
|
||||||
|
|
||||||
|
for (String license : licenses) {
|
||||||
|
|
||||||
|
String licenseUri = ccLicenseUrl + "/license/" + license;
|
||||||
|
HttpGet licenseHttpGet = new HttpGet(licenseUri);
|
||||||
|
try (CloseableHttpResponse response = client.execute(licenseHttpGet)) {
|
||||||
|
CCLicense ccLicense = retrieveLicenseObject(license, response);
|
||||||
|
ccLicenses.put(ccLicense.getLicenseId(), ccLicense);
|
||||||
|
} catch (JaxenException | JDOMException | IOException e) {
|
||||||
|
log.error("Error while retrieving the license details using url: " + licenseUri, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ccLicenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of licenses from the response from the CC License API and remove the licenses configured
|
||||||
|
* to be excluded
|
||||||
|
*
|
||||||
|
* @param response The response from the API
|
||||||
|
* @return a list of license identifiers for which details need to be retrieved
|
||||||
|
* @throws IOException
|
||||||
|
* @throws JaxenException
|
||||||
|
* @throws JDOMException
|
||||||
|
*/
|
||||||
|
private List<String> retrieveLicenses(CloseableHttpResponse response)
|
||||||
|
throws IOException, JaxenException, JDOMException {
|
||||||
|
|
||||||
|
List<String> domains = new LinkedList<>();
|
||||||
|
String[] excludedLicenses = configurationService.getArrayProperty("cc.license.classfilter");
|
||||||
|
|
||||||
|
|
||||||
|
String responseString = EntityUtils.toString(response.getEntity());
|
||||||
|
JDOMXPath licenseClassXpath = new JDOMXPath("//licenses/license");
|
||||||
|
|
||||||
|
|
||||||
|
try (StringReader stringReader = new StringReader(responseString)) {
|
||||||
|
InputSource is = new InputSource(stringReader);
|
||||||
|
org.jdom.Document classDoc = this.parser.build(is);
|
||||||
|
|
||||||
|
List<Element> elements = licenseClassXpath.selectNodes(classDoc);
|
||||||
|
for (Element element : elements) {
|
||||||
|
String licenseId = getSingleNodeValue(element, "@id");
|
||||||
|
if (StringUtils.isNotBlank(licenseId) && !ArrayUtils.contains(excludedLicenses, licenseId)) {
|
||||||
|
domains.add(licenseId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return domains;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the response for a single CC License and return the corresponding CC License Object
|
||||||
|
*
|
||||||
|
* @param licenseId the license id of the CC License to retrieve
|
||||||
|
* @param response for a specific CC License response
|
||||||
|
* @return the corresponding CC License Object
|
||||||
|
* @throws IOException
|
||||||
|
* @throws JaxenException
|
||||||
|
* @throws JDOMException
|
||||||
|
*/
|
||||||
|
private CCLicense retrieveLicenseObject(final String licenseId, CloseableHttpResponse response)
|
||||||
|
throws IOException, JaxenException, JDOMException {
|
||||||
|
|
||||||
|
String responseString = EntityUtils.toString(response.getEntity());
|
||||||
|
|
||||||
|
|
||||||
|
JDOMXPath licenseClassXpath = new JDOMXPath("//licenseclass");
|
||||||
|
JDOMXPath licenseFieldXpath = new JDOMXPath("field");
|
||||||
|
|
||||||
|
|
||||||
|
try (StringReader stringReader = new StringReader(responseString)) {
|
||||||
|
InputSource is = new InputSource(stringReader);
|
||||||
|
|
||||||
|
org.jdom.Document classDoc = this.parser.build(is);
|
||||||
|
|
||||||
|
Object element = licenseClassXpath.selectSingleNode(classDoc);
|
||||||
|
String licenseLabel = getSingleNodeValue(element, "label");
|
||||||
|
|
||||||
|
List<CCLicenseField> ccLicenseFields = new LinkedList<>();
|
||||||
|
|
||||||
|
List<Element> licenseFields = licenseFieldXpath.selectNodes(element);
|
||||||
|
for (Element licenseField : licenseFields) {
|
||||||
|
CCLicenseField ccLicenseField = parseLicenseField(licenseField);
|
||||||
|
ccLicenseFields.add(ccLicenseField);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CCLicense(licenseId, licenseLabel, ccLicenseFields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CCLicenseField parseLicenseField(final Element licenseField) throws JaxenException {
|
||||||
|
String id = getSingleNodeValue(licenseField, "@id");
|
||||||
|
String label = getSingleNodeValue(licenseField, "label");
|
||||||
|
String description = getSingleNodeValue(licenseField, "description");
|
||||||
|
|
||||||
|
JDOMXPath enumXpath = new JDOMXPath("enum");
|
||||||
|
List<Element> enums = enumXpath.selectNodes(licenseField);
|
||||||
|
|
||||||
|
List<CCLicenseFieldEnum> ccLicenseFieldEnumList = new LinkedList<>();
|
||||||
|
|
||||||
|
for (Element enumElement : enums) {
|
||||||
|
CCLicenseFieldEnum ccLicenseFieldEnum = parseEnum(enumElement);
|
||||||
|
ccLicenseFieldEnumList.add(ccLicenseFieldEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CCLicenseField(id, label, description, ccLicenseFieldEnumList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private CCLicenseFieldEnum parseEnum(final Element enumElement) throws JaxenException {
|
||||||
|
String id = getSingleNodeValue(enumElement, "@id");
|
||||||
|
String label = getSingleNodeValue(enumElement, "label");
|
||||||
|
String description = getSingleNodeValue(enumElement, "description");
|
||||||
|
|
||||||
|
return new CCLicenseFieldEnum(id, label, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getNodeValue(final Object el) {
|
||||||
|
if (el instanceof Element) {
|
||||||
|
return ((Element) el).getValue();
|
||||||
|
} else if (el instanceof Attribute) {
|
||||||
|
return ((Attribute) el).getValue();
|
||||||
|
} else if (el instanceof String) {
|
||||||
|
return (String) el;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSingleNodeValue(final Object t, String query) throws JaxenException {
|
||||||
|
JDOMXPath xpath = new JDOMXPath(query);
|
||||||
|
Object singleNode = xpath.selectSingleNode(t);
|
||||||
|
|
||||||
|
return getNodeValue(singleNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI based on the provided license id, language and answers to the field questions from
|
||||||
|
* the CC License API
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the CC License URI
|
||||||
|
*/
|
||||||
|
public String retrieveRightsByQuestion(String licenseId,
|
||||||
|
String language,
|
||||||
|
Map<String, String> answerMap) {
|
||||||
|
|
||||||
|
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
||||||
|
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost(ccLicenseUrl + "/license/" + licenseId + "/issue");
|
||||||
|
|
||||||
|
|
||||||
|
String answers = createAnswerString(answerMap);
|
||||||
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
|
String text = MessageFormat.format(postAnswerFormat, licenseId, language, answers);
|
||||||
|
builder.addTextBody(postArgument, text);
|
||||||
|
|
||||||
|
HttpEntity multipart = builder.build();
|
||||||
|
|
||||||
|
httpPost.setEntity(multipart);
|
||||||
|
|
||||||
|
try (CloseableHttpResponse response = client.execute(httpPost)) {
|
||||||
|
return retrieveLicenseUri(response);
|
||||||
|
} catch (JDOMException | JaxenException | IOException e) {
|
||||||
|
log.error("Error while retrieving the license uri for license : " + licenseId + " with answers "
|
||||||
|
+ answerMap.toString(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the response for the CC License URI request and return the corresponding CC License URI
|
||||||
|
*
|
||||||
|
* @param response for a specific CC License URI response
|
||||||
|
* @return the corresponding CC License URI as a string
|
||||||
|
* @throws IOException
|
||||||
|
* @throws JaxenException
|
||||||
|
* @throws JDOMException
|
||||||
|
*/
|
||||||
|
private String retrieveLicenseUri(final CloseableHttpResponse response)
|
||||||
|
throws IOException, JaxenException, JDOMException {
|
||||||
|
|
||||||
|
String responseString = EntityUtils.toString(response.getEntity());
|
||||||
|
JDOMXPath licenseClassXpath = new JDOMXPath("//result/license-uri");
|
||||||
|
|
||||||
|
|
||||||
|
try (StringReader stringReader = new StringReader(responseString)) {
|
||||||
|
InputSource is = new InputSource(stringReader);
|
||||||
|
org.jdom.Document classDoc = this.parser.build(is);
|
||||||
|
|
||||||
|
Object node = licenseClassXpath.selectSingleNode(classDoc);
|
||||||
|
String nodeValue = getNodeValue(node);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(nodeValue)) {
|
||||||
|
return nodeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createAnswerString(final Map<String, String> parameterMap) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String key : parameterMap.keySet()) {
|
||||||
|
sb.append("<");
|
||||||
|
sb.append(key);
|
||||||
|
sb.append(">");
|
||||||
|
sb.append(parameterMap.get(key));
|
||||||
|
sb.append("</");
|
||||||
|
sb.append(key);
|
||||||
|
sb.append(">");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the license RDF document based on the license URI
|
||||||
|
*
|
||||||
|
* @param licenseURI - The license URI for which to retrieve the license RDF document
|
||||||
|
* @return the license RDF document
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
|
||||||
|
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
|
||||||
|
|
||||||
|
String issueUrl = ccLicenseUrl + "/details?license-uri=" + licenseURI;
|
||||||
|
|
||||||
|
URL request_url;
|
||||||
|
try {
|
||||||
|
request_url = new URL(issueUrl);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
URLConnection connection = request_url.openConnection();
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
try {
|
||||||
|
// parsing document from input stream
|
||||||
|
InputStream stream = connection.getInputStream();
|
||||||
|
Document doc = parser.build(stream);
|
||||||
|
return doc;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while retrieving the license document for URI: " + licenseURI, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the license Name from the license document
|
||||||
|
*
|
||||||
|
* @param doc - The license document from which to retrieve the license name
|
||||||
|
* @return the license name
|
||||||
|
*/
|
||||||
|
public String retrieveLicenseName(final Document doc) {
|
||||||
|
try {
|
||||||
|
return getSingleNodeValue(doc, "//result/license-name");
|
||||||
|
} catch (JaxenException e) {
|
||||||
|
log.error("Error while retrieving the license name from the license document", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,8 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.license;
|
package org.dspace.license;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper class for representation of a license field declaration.
|
* Wrapper class for representation of a license field declaration.
|
||||||
@@ -22,7 +21,7 @@ public class CCLicenseField {
|
|||||||
private String description = "";
|
private String description = "";
|
||||||
private String type = "";
|
private String type = "";
|
||||||
|
|
||||||
private HashMap fieldEnum = null;
|
private List<CCLicenseFieldEnum> fieldEnum = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new LicenseField class. Note that after construction,
|
* Construct a new LicenseField class. Note that after construction,
|
||||||
@@ -31,13 +30,11 @@ public class CCLicenseField {
|
|||||||
* @param id The unique identifier for this field; this value will be used in constructing the answers XML.
|
* @param id The unique identifier for this field; this value will be used in constructing the answers XML.
|
||||||
* @param label The label to use when generating the user interface.
|
* @param label The label to use when generating the user interface.
|
||||||
*/
|
*/
|
||||||
public CCLicenseField(String id, String label) {
|
public CCLicenseField(String id, String label, String description, List<CCLicenseFieldEnum> fieldEnum) {
|
||||||
super();
|
|
||||||
|
|
||||||
this.fieldEnum = new HashMap();
|
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
|
this.description = description;
|
||||||
|
this.fieldEnum = fieldEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,16 +87,12 @@ public class CCLicenseField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns an instance implementing the Map interface;
|
* Returns the list of enums of this field
|
||||||
* the instance contains a mapping from identifiers to
|
* @return the list of enums of this field
|
||||||
* labels for the enumeration values.
|
|
||||||
* @see Map
|
|
||||||
*/
|
*/
|
||||||
public Map<String, String> getEnum() {
|
public List<CCLicenseFieldEnum> getFieldEnum() {
|
||||||
return this.fieldEnum;
|
return fieldEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.license;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class for representation of a license field enum declaration.
|
||||||
|
* A field enum is a single "answer" to the field question
|
||||||
|
*/
|
||||||
|
public class CCLicenseFieldEnum {
|
||||||
|
|
||||||
|
private String id = "";
|
||||||
|
private String label = "";
|
||||||
|
private String description = "";
|
||||||
|
|
||||||
|
public CCLicenseFieldEnum(String id, String label, String description) {
|
||||||
|
if (StringUtils.isNotBlank(id)) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(label)) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(description)) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id of this enum
|
||||||
|
* @return the id of this enum
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the id of this enum
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
public void setId(final String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the label of this enum
|
||||||
|
* @return the label of this enum
|
||||||
|
*/
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the label of this enum
|
||||||
|
* @param label
|
||||||
|
*/
|
||||||
|
public void setLabel(final String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of this enum
|
||||||
|
* @return the description of this enum
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the description of this enum
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,435 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.license;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.dspace.license.factory.LicenseServiceFactory;
|
|
||||||
import org.dspace.license.service.CreativeCommonsService;
|
|
||||||
import org.dspace.services.ConfigurationService;
|
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
|
||||||
import org.jaxen.JaxenException;
|
|
||||||
import org.jaxen.jdom.JDOMXPath;
|
|
||||||
import org.jdom.Attribute;
|
|
||||||
import org.jdom.Document;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.JDOMException;
|
|
||||||
import org.jdom.input.SAXBuilder;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper around Creative Commons REST web services.
|
|
||||||
*
|
|
||||||
* @author Wendy Bossons
|
|
||||||
*/
|
|
||||||
public class CCLookup {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* log4j logger
|
|
||||||
*/
|
|
||||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(CCLookup.class);
|
|
||||||
|
|
||||||
private String cc_root;
|
|
||||||
private String jurisdiction;
|
|
||||||
private List<String> lcFilter = new ArrayList<String>();
|
|
||||||
|
|
||||||
private Document license_doc = null;
|
|
||||||
private String rdfString = null;
|
|
||||||
private String errorMessage = null;
|
|
||||||
private boolean success = false;
|
|
||||||
|
|
||||||
private SAXBuilder parser = new SAXBuilder();
|
|
||||||
private List<CCLicense> licenses = new ArrayList<CCLicense>();
|
|
||||||
private List<CCLicenseField> licenseFields = new ArrayList<CCLicenseField>();
|
|
||||||
|
|
||||||
protected CreativeCommonsService creativeCommonsService = LicenseServiceFactory.getInstance()
|
|
||||||
.getCreativeCommonsService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance with the default web services root.
|
|
||||||
*/
|
|
||||||
public CCLookup() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
|
||||||
|
|
||||||
cc_root = configurationService.getProperty("cc.api.rooturl");
|
|
||||||
|
|
||||||
String jurisProp = configurationService.getProperty("cc.license.jurisdiction");
|
|
||||||
jurisdiction = (jurisProp != null) ? jurisProp : "";
|
|
||||||
|
|
||||||
String[] filters = configurationService.getArrayProperty("cc.license.classfilter");
|
|
||||||
if (filters != null) {
|
|
||||||
for (String name : filters) {
|
|
||||||
lcFilter.add(name.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the id for a particular CCLicense label. Returns an
|
|
||||||
* empty string if no match is found.
|
|
||||||
*
|
|
||||||
* @param class_label The CCLicense label to find.
|
|
||||||
* @return Returns a String containing the License class ID if the label
|
|
||||||
* is found; if not found, returns an empty string.
|
|
||||||
* @see CCLicense
|
|
||||||
*/
|
|
||||||
public String getLicenseId(String class_label) {
|
|
||||||
for (int i = 0; i < this.licenses.size(); i++) {
|
|
||||||
if (((CCLicense) this.licenses.get(i)).getLicenseName().equals(class_label)) {
|
|
||||||
return ((CCLicense) this.licenses.get(i)).getLicenseId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the web service for the available licenses.
|
|
||||||
*
|
|
||||||
* @param language The language to request labels and description strings in.
|
|
||||||
* @return Returns a Map of CCLicense objects.
|
|
||||||
* @see Map
|
|
||||||
* @see CCLicense
|
|
||||||
*/
|
|
||||||
public Collection<CCLicense> getLicenses(String language) {
|
|
||||||
|
|
||||||
// create XPath expressions
|
|
||||||
try {
|
|
||||||
JDOMXPath xp_Licenses = new JDOMXPath("//licenses/license");
|
|
||||||
JDOMXPath xp_LicenseID = new JDOMXPath("@id");
|
|
||||||
URL classUrl = new URL(this.cc_root + "/?locale=" + language);
|
|
||||||
Document classDoc = this.parser.build(classUrl);
|
|
||||||
// extract the identifiers and labels using XPath
|
|
||||||
List<Element> results = xp_Licenses.selectNodes(classDoc);
|
|
||||||
// populate licenses container
|
|
||||||
this.licenses.clear();
|
|
||||||
for (int i = 0; i < results.size(); i++) {
|
|
||||||
Element license = results.get(i);
|
|
||||||
// add if not filtered
|
|
||||||
String liD = ((Attribute) xp_LicenseID.selectSingleNode(license)).getValue();
|
|
||||||
if (!lcFilter.contains(liD)) {
|
|
||||||
this.licenses.add(new CCLicense(liD, license.getText(), i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JaxenException jaxen_e) {
|
|
||||||
return null;
|
|
||||||
} catch (JDOMException jdom_e) {
|
|
||||||
return null;
|
|
||||||
} catch (IOException io_e) {
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// do nothing... but we should
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return licenses;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the web service for a set of licenseFields for a particular license class.
|
|
||||||
*
|
|
||||||
* @param license A String specifying the CCLicense identifier to
|
|
||||||
* retrieve fields for.
|
|
||||||
* @param language the locale string
|
|
||||||
* @return A Collection of LicenseField objects.
|
|
||||||
* @see CCLicense
|
|
||||||
*/
|
|
||||||
public Collection<CCLicenseField> getLicenseFields(String license, String language) {
|
|
||||||
|
|
||||||
JDOMXPath xp_LicenseField;
|
|
||||||
JDOMXPath xp_LicenseID;
|
|
||||||
JDOMXPath xp_FieldType;
|
|
||||||
JDOMXPath xp_Description;
|
|
||||||
JDOMXPath xp_Label;
|
|
||||||
JDOMXPath xp_Enum;
|
|
||||||
|
|
||||||
Document fieldDoc;
|
|
||||||
|
|
||||||
URL classUrl;
|
|
||||||
List results = null;
|
|
||||||
List enumOptions = null;
|
|
||||||
|
|
||||||
// create XPath expressions
|
|
||||||
try {
|
|
||||||
xp_LicenseField = new JDOMXPath("//field");
|
|
||||||
xp_LicenseID = new JDOMXPath("@id");
|
|
||||||
xp_Description = new JDOMXPath("description");
|
|
||||||
xp_Label = new JDOMXPath("label");
|
|
||||||
xp_FieldType = new JDOMXPath("type");
|
|
||||||
xp_Enum = new JDOMXPath("enum");
|
|
||||||
|
|
||||||
} catch (JaxenException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve and parse the license class document
|
|
||||||
try {
|
|
||||||
classUrl = new URL(this.cc_root + "/license/" + license + "?locale=" + language);
|
|
||||||
} catch (Exception err) {
|
|
||||||
// do nothing... but we should
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the licenses document
|
|
||||||
try {
|
|
||||||
fieldDoc = this.parser.build(classUrl);
|
|
||||||
} catch (JDOMException e) {
|
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the field definition container
|
|
||||||
this.licenseFields.clear();
|
|
||||||
|
|
||||||
// extract the identifiers and labels using XPath
|
|
||||||
try {
|
|
||||||
results = xp_LicenseField.selectNodes(fieldDoc);
|
|
||||||
} catch (JaxenException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < results.size(); i++) {
|
|
||||||
Element field = (Element) results.get(i);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// create the field object
|
|
||||||
CCLicenseField cclicensefield = new CCLicenseField(
|
|
||||||
((Attribute) xp_LicenseID.selectSingleNode(field)).getValue(),
|
|
||||||
((Element) xp_Label.selectSingleNode(field)).getText());
|
|
||||||
|
|
||||||
// extract additional properties
|
|
||||||
cclicensefield.setDescription(((Element) xp_Description.selectSingleNode(field)).getText());
|
|
||||||
cclicensefield.setType(((Element) xp_FieldType.selectSingleNode(field)).getText());
|
|
||||||
|
|
||||||
enumOptions = xp_Enum.selectNodes(field);
|
|
||||||
|
|
||||||
for (int j = 0; j < enumOptions.size(); j++) {
|
|
||||||
String id = ((Attribute) xp_LicenseID.selectSingleNode(enumOptions.get(j))).getValue();
|
|
||||||
String label = ((Element) xp_Label.selectSingleNode(enumOptions.get(j))).getText();
|
|
||||||
|
|
||||||
cclicensefield.getEnum().put(id, label);
|
|
||||||
|
|
||||||
} // for each enum option
|
|
||||||
|
|
||||||
this.licenseFields.add(cclicensefield);
|
|
||||||
} catch (JaxenException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return licenseFields;
|
|
||||||
} // licenseFields
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passes a set of "answers" to the web service and retrieves a license.
|
|
||||||
*
|
|
||||||
* @param licenseId The identifier of the license class being requested.
|
|
||||||
* @param answers A Map containing the answers to the license fields;
|
|
||||||
* each key is the identifier of a LicenseField, with the value
|
|
||||||
* containing the user-supplied answer.
|
|
||||||
* @param lang The language to request localized elements in.
|
|
||||||
* @throws IOException if IO error
|
|
||||||
* @see CCLicense
|
|
||||||
* @see Map
|
|
||||||
*/
|
|
||||||
public void issue(String licenseId, Map answers, String lang)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
// Determine the issue URL
|
|
||||||
String issueUrl = this.cc_root + "/license/" + licenseId + "/issue";
|
|
||||||
// Assemble the "answers" document
|
|
||||||
String answer_doc = "<answers>\n<locale>" + lang + "</locale>\n" + "<license-" + licenseId + ">\n";
|
|
||||||
Iterator keys = answers.keySet().iterator();
|
|
||||||
|
|
||||||
try {
|
|
||||||
String current = (String) keys.next();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
answer_doc += "<" + current + ">" + (String) answers.get(current) + "</" + current + ">\n";
|
|
||||||
current = (String) keys.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
// exception indicates we've iterated through the
|
|
||||||
// entire collection; just swallow and continue
|
|
||||||
}
|
|
||||||
// answer_doc += "<jurisdiction></jurisidiction>\n"; FAILS with jurisdiction argument
|
|
||||||
answer_doc += "</license-" + licenseId + ">\n</answers>\n";
|
|
||||||
String post_data;
|
|
||||||
|
|
||||||
try {
|
|
||||||
post_data = URLEncoder.encode("answers", "UTF-8") + "=" + URLEncoder.encode(answer_doc, "UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
URL post_url;
|
|
||||||
try {
|
|
||||||
post_url = new URL(issueUrl);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
URLConnection connection = post_url.openConnection();
|
|
||||||
// this will not be needed after I'm done TODO: remove
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
|
|
||||||
writer.write(post_data);
|
|
||||||
writer.flush();
|
|
||||||
// end TODO
|
|
||||||
try {
|
|
||||||
// parsing document from input stream
|
|
||||||
java.io.InputStream stream = connection.getInputStream();
|
|
||||||
this.license_doc = this.parser.build(stream);
|
|
||||||
} catch (JDOMException jde) {
|
|
||||||
log.warn(jde.getMessage());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn(e.getCause());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} // issue
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passes a set of "answers" to the web service and retrieves a license.
|
|
||||||
*
|
|
||||||
* @param licenseURI The uri of the license.
|
|
||||||
*
|
|
||||||
* Note: does not support localization in 1.5 -- not yet
|
|
||||||
* @throws IOException if IO error
|
|
||||||
* @see CCLicense
|
|
||||||
* @see Map
|
|
||||||
*/
|
|
||||||
public void issue(String licenseURI)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
// Determine the issue URL
|
|
||||||
// Example: http://api.creativecommons.org/rest/1.5/details?
|
|
||||||
// license-uri=http://creativecommons.org/licenses/by-nc-sa/3.0/
|
|
||||||
String issueUrl = cc_root + "/details?license-uri=" + licenseURI;
|
|
||||||
|
|
||||||
URL request_url;
|
|
||||||
try {
|
|
||||||
request_url = new URL(issueUrl);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
URLConnection connection = request_url.openConnection();
|
|
||||||
// this will not be needed after I'm done TODO: remove
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
try {
|
|
||||||
// parsing document from input stream
|
|
||||||
java.io.InputStream stream = connection.getInputStream();
|
|
||||||
license_doc = this.parser.build(stream);
|
|
||||||
} catch (JDOMException jde) {
|
|
||||||
log.warn(jde.getMessage());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn(e.getCause());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} // issue
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the URI for the license issued.
|
|
||||||
*
|
|
||||||
* @return A String containing the URI for the license issued.
|
|
||||||
*/
|
|
||||||
public String getLicenseUrl() {
|
|
||||||
String text = null;
|
|
||||||
try {
|
|
||||||
JDOMXPath xp_LicenseName = new JDOMXPath("//result/license-uri");
|
|
||||||
text = ((Element) xp_LicenseName.selectSingleNode(this.license_doc)).getText();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn(e.getMessage());
|
|
||||||
setSuccess(false);
|
|
||||||
text = "An error occurred getting the license - uri.";
|
|
||||||
} finally {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
} // getLicenseUrl
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the human readable name for the license issued.
|
|
||||||
*
|
|
||||||
* @return A String containing the license name.
|
|
||||||
*/
|
|
||||||
public String getLicenseName() {
|
|
||||||
String text = null;
|
|
||||||
try {
|
|
||||||
JDOMXPath xp_LicenseName = new JDOMXPath("//result/license-name");
|
|
||||||
text = ((Element) xp_LicenseName.selectSingleNode(this.license_doc)).getText();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn(e.getMessage());
|
|
||||||
setSuccess(false);
|
|
||||||
text = "An error occurred on the license name.";
|
|
||||||
} finally {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
} // getLicenseName
|
|
||||||
|
|
||||||
|
|
||||||
public org.jdom.Document getLicenseDocument() {
|
|
||||||
return this.license_doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRdf()
|
|
||||||
throws IOException {
|
|
||||||
String result = "";
|
|
||||||
try {
|
|
||||||
result = creativeCommonsService.fetchLicenseRDF(license_doc);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("An error occurred getting the rdf . . ." + e.getMessage());
|
|
||||||
setSuccess(false);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccess() {
|
|
||||||
setSuccess(false);
|
|
||||||
JDOMXPath xp_Success;
|
|
||||||
String text = null;
|
|
||||||
try {
|
|
||||||
xp_Success = new JDOMXPath("//message");
|
|
||||||
text = ((Element) xp_Success.selectSingleNode(this.license_doc)).getText();
|
|
||||||
setErrorMessage(text);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("There was an issue . . . " + text);
|
|
||||||
setSuccess(true);
|
|
||||||
}
|
|
||||||
return this.success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSuccess(boolean success) {
|
|
||||||
this.success = success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrorMessage() {
|
|
||||||
return this.errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setErrorMessage(String errorMessage) {
|
|
||||||
this.errorMessage = errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -13,7 +13,10 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import javax.xml.transform.TransformerConfigurationException;
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
@@ -82,9 +85,18 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
protected BundleService bundleService;
|
protected BundleService bundleService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
|
@Autowired
|
||||||
|
protected CCLicenseConnectorService ccLicenseConnectorService;
|
||||||
|
|
||||||
protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
|
private String defaultLanguage;
|
||||||
|
private String jurisdiction;
|
||||||
|
private static final String JURISDICTION_KEY = "jurisdiction";
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Map<String, CCLicense>> ccLicenses;
|
||||||
|
|
||||||
protected CreativeCommonsServiceImpl() {
|
protected CreativeCommonsServiceImpl() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -101,10 +113,14 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
System.setProperty("http.proxyPort", proxyPort);
|
System.setProperty("http.proxyPort", proxyPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccLicenses = new HashMap<>();
|
||||||
|
defaultLanguage = configurationService.getProperty("cc.license.locale", "en");
|
||||||
|
jurisdiction = configurationService.getProperty("cc.license.jurisdiction", "");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
templates = TransformerFactory.newInstance().newTemplates(
|
templates = TransformerFactory.newInstance().newTemplates(
|
||||||
new StreamSource(CreativeCommonsServiceImpl.class
|
new StreamSource(CreativeCommonsServiceImpl.class
|
||||||
.getResourceAsStream("CreativeCommons.xsl")));
|
.getResourceAsStream("CreativeCommons.xsl")));
|
||||||
} catch (TransformerConfigurationException e) {
|
} catch (TransformerConfigurationException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@@ -112,15 +128,10 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the CC bundle if it doesn't exist
|
// create the CC bundle if it doesn't exist
|
||||||
// If it does, remove it and create a new one.
|
// If it does, remove it and create a new one.
|
||||||
protected Bundle getCcBundle(Context context, Item item)
|
protected Bundle getCcBundle(Context context, Item item)
|
||||||
throws SQLException, AuthorizeException, IOException {
|
throws SQLException, AuthorizeException, IOException {
|
||||||
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
|
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
|
||||||
|
|
||||||
if ((bundles.size() > 0) && (bundles.get(0) != null)) {
|
if ((bundles.size() > 0) && (bundles.get(0) != null)) {
|
||||||
@@ -131,8 +142,8 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLicenseRDF(Context context, Item item, String licenseRdf)
|
public void setLicenseRDF(Context context, Item item, String licenseRdf)
|
||||||
throws SQLException, IOException,
|
throws SQLException, IOException,
|
||||||
AuthorizeException {
|
AuthorizeException {
|
||||||
Bundle bundle = getCcBundle(context, item);
|
Bundle bundle = getCcBundle(context, item);
|
||||||
// set the format
|
// set the format
|
||||||
BitstreamFormat bs_rdf_format = bitstreamFormatService.findByShortDescription(context, "RDF XML");
|
BitstreamFormat bs_rdf_format = bitstreamFormatService.findByShortDescription(context, "RDF XML");
|
||||||
@@ -144,7 +155,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
@Override
|
@Override
|
||||||
public void setLicense(Context context, Item item,
|
public void setLicense(Context context, Item item,
|
||||||
InputStream licenseStm, String mimeType)
|
InputStream licenseStm, String mimeType)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
Bundle bundle = getCcBundle(context, item);
|
Bundle bundle = getCcBundle(context, item);
|
||||||
|
|
||||||
// set the format
|
// set the format
|
||||||
@@ -160,17 +171,26 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
Bitstream bs = bitstreamService.create(context, bundle, licenseStm);
|
Bitstream bs = bitstreamService.create(context, bundle, licenseStm);
|
||||||
bs.setSource(context, CC_BS_SOURCE);
|
bs.setSource(context, CC_BS_SOURCE);
|
||||||
bs.setName(context, (mimeType != null &&
|
bs.setName(context, (mimeType != null &&
|
||||||
(mimeType.equalsIgnoreCase("text/xml") ||
|
(mimeType.equalsIgnoreCase("text/xml") ||
|
||||||
mimeType.equalsIgnoreCase("text/rdf"))) ?
|
mimeType.equalsIgnoreCase("text/rdf"))) ?
|
||||||
BSN_LICENSE_RDF : BSN_LICENSE_TEXT);
|
BSN_LICENSE_RDF : BSN_LICENSE_TEXT);
|
||||||
bs.setFormat(context, bs_format);
|
bs.setFormat(context, bs_format);
|
||||||
bitstreamService.update(context, bs);
|
bitstreamService.update(context, bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the license file from the item
|
||||||
|
*
|
||||||
|
* @param context - The relevant DSpace Context
|
||||||
|
* @param item - The item from which the license file needs to be removed
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeLicense(Context context, Item item)
|
public void removeLicenseFile(Context context, Item item)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
// remove CC license bundle if one exists
|
// remove CC license bundle if one exists
|
||||||
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
|
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
|
||||||
|
|
||||||
@@ -179,66 +199,74 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasLicense(Context context, Item item)
|
|
||||||
throws SQLException, IOException {
|
|
||||||
// try to find CC license bundle
|
|
||||||
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
|
|
||||||
|
|
||||||
if (bundles.size() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify it has correct contents
|
|
||||||
try {
|
|
||||||
if ((getLicenseURL(context, item) == null)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (AuthorizeException ae) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLicenseRDF(Context context, Item item) throws SQLException,
|
|
||||||
IOException, AuthorizeException {
|
|
||||||
return getStringFromBitstream(context, item, BSN_LICENSE_RDF);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitstream getLicenseRdfBitstream(Item item) throws SQLException,
|
public Bitstream getLicenseRdfBitstream(Item item) throws SQLException,
|
||||||
IOException, AuthorizeException {
|
IOException, AuthorizeException {
|
||||||
return getBitstream(item, BSN_LICENSE_RDF);
|
return getBitstream(item, BSN_LICENSE_RDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public Bitstream getLicenseTextBitstream(Item item) throws SQLException,
|
public Bitstream getLicenseTextBitstream(Item item) throws SQLException,
|
||||||
IOException, AuthorizeException {
|
IOException, AuthorizeException {
|
||||||
return getBitstream(item, BSN_LICENSE_TEXT);
|
return getBitstream(item, BSN_LICENSE_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLicenseURL(Context context, Item item) throws SQLException, IOException, AuthorizeException {
|
public String getLicenseURL(Context context, Item item) throws SQLException, IOException, AuthorizeException {
|
||||||
String licenseUri = getCCField("uri").ccItemValue(item);
|
String licenseUri = getCCField("uri");
|
||||||
if (StringUtils.isNotBlank(licenseUri)) {
|
if (StringUtils.isNotBlank(licenseUri)) {
|
||||||
return licenseUri;
|
return getLicenseURI(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSPUI backward compatibility see https://jira.duraspace.org/browse/DS-2604
|
// JSPUI backward compatibility see https://jira.duraspace.org/browse/DS-2604
|
||||||
return getStringFromBitstream(context, item, BSN_LICENSE_URL);
|
return getStringFromBitstream(context, item, BSN_LICENSE_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored license uri of the item
|
||||||
|
*
|
||||||
|
* @param item - The item for which to retrieve the stored license uri
|
||||||
|
* @return the stored license uri of the item
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getLicenseURI(Item item) {
|
||||||
|
String licenseUriField = getCCField("uri");
|
||||||
|
if (StringUtils.isNotBlank(licenseUriField)) {
|
||||||
|
String metadata = itemService.getMetadata(item, licenseUriField);
|
||||||
|
if (StringUtils.isNotBlank(metadata)) {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored license name of the item
|
||||||
|
*
|
||||||
|
* @param item - The item for which to retrieve the stored license name
|
||||||
|
* @return the stored license name of the item
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getLicenseName( Item item) {
|
||||||
|
String licenseNameField = getCCField("name");
|
||||||
|
if (StringUtils.isNotBlank(licenseNameField)) {
|
||||||
|
String metadata = itemService.getMetadata(item, licenseNameField);
|
||||||
|
if (StringUtils.isNotBlank(metadata)) {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String fetchLicenseRDF(Document license) {
|
public String fetchLicenseRDF(Document license) {
|
||||||
StringWriter result = new StringWriter();
|
StringWriter result = new StringWriter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
templates.newTransformer().transform(
|
templates.newTransformer().transform(
|
||||||
new JDOMSource(license),
|
new JDOMSource(license),
|
||||||
new StreamResult(result)
|
new StreamResult(result)
|
||||||
);
|
);
|
||||||
} catch (TransformerException e) {
|
} catch (TransformerException e) {
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
throw new IllegalStateException(e.getMessage(), e);
|
||||||
@@ -267,7 +295,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
*/
|
*/
|
||||||
protected void setBitstreamFromBytes(Context context, Item item, Bundle bundle,
|
protected void setBitstreamFromBytes(Context context, Item item, Bundle bundle,
|
||||||
String bitstream_name, BitstreamFormat format, byte[] bytes)
|
String bitstream_name, BitstreamFormat format, byte[] bytes)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
Bitstream bs = bitstreamService.create(context, bundle, bais);
|
Bitstream bs = bitstreamService.create(context, bundle, bais);
|
||||||
|
|
||||||
@@ -297,7 +325,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
*/
|
*/
|
||||||
protected String getStringFromBitstream(Context context, Item item,
|
protected String getStringFromBitstream(Context context, Item item,
|
||||||
String bitstream_name) throws SQLException, IOException,
|
String bitstream_name) throws SQLException, IOException,
|
||||||
AuthorizeException {
|
AuthorizeException {
|
||||||
byte[] bytes = getBytesFromBitstream(context, item, bitstream_name);
|
byte[] bytes = getBytesFromBitstream(context, item, bitstream_name);
|
||||||
|
|
||||||
if (bytes == null) {
|
if (bytes == null) {
|
||||||
@@ -320,7 +348,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
* to perform a particular action.
|
* to perform a particular action.
|
||||||
*/
|
*/
|
||||||
protected Bitstream getBitstream(Item item, String bitstream_name)
|
protected Bitstream getBitstream(Item item, String bitstream_name)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
Bundle cc_bundle = null;
|
Bundle cc_bundle = null;
|
||||||
|
|
||||||
// look for the CC bundle
|
// look for the CC bundle
|
||||||
@@ -342,7 +370,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] getBytesFromBitstream(Context context, Item item, String bitstream_name)
|
protected byte[] getBytesFromBitstream(Context context, Item item, String bitstream_name)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
Bitstream bs = getBitstream(item, bitstream_name);
|
Bitstream bs = getBitstream(item, bitstream_name);
|
||||||
|
|
||||||
// no such bitstream
|
// no such bitstream
|
||||||
@@ -361,26 +389,322 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
|
|||||||
* Returns a metadata field handle for given field Id
|
* Returns a metadata field handle for given field Id
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public LicenseMetadataValue getCCField(String fieldId) {
|
public String getCCField(String fieldId) {
|
||||||
return new LicenseMetadataValue(configurationService.getProperty("cc.license." + fieldId));
|
return configurationService.getProperty("cc.license." + fieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove license information, delete also the bitstream
|
||||||
|
*
|
||||||
|
* @param context - DSpace Context
|
||||||
|
* @param item - the item
|
||||||
|
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
|
||||||
|
* to perform a particular action.
|
||||||
|
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
||||||
|
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeLicense(Context context, LicenseMetadataValue uriField,
|
public void removeLicense(Context context, Item item)
|
||||||
LicenseMetadataValue nameField, Item item)
|
throws AuthorizeException, IOException, SQLException {
|
||||||
throws AuthorizeException, IOException, SQLException {
|
|
||||||
|
String uriField = getCCField("uri");
|
||||||
|
String nameField = getCCField("name");
|
||||||
|
|
||||||
|
String licenseUri = itemService.getMetadata(item, uriField);
|
||||||
|
|
||||||
// only remove any previous licenses
|
// only remove any previous licenses
|
||||||
String licenseUri = uriField.ccItemValue(item);
|
|
||||||
if (licenseUri != null) {
|
if (licenseUri != null) {
|
||||||
uriField.removeItemValue(context, item, licenseUri);
|
removeLicenseField(context, item, uriField);
|
||||||
if (configurationService.getBooleanProperty("cc.submit.setname")) {
|
if (configurationService.getBooleanProperty("cc.submit.setname")) {
|
||||||
String licenseName = nameField.keyedItemValue(item, licenseUri);
|
removeLicenseField(context, item, nameField);
|
||||||
nameField.removeItemValue(context, item, licenseName);
|
|
||||||
}
|
}
|
||||||
if (configurationService.getBooleanProperty("cc.submit.addbitstream")) {
|
if (configurationService.getBooleanProperty("cc.submit.addbitstream")) {
|
||||||
removeLicense(context, item);
|
removeLicenseFile(context, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeLicenseField(Context context, Item item, String field) throws SQLException {
|
||||||
|
String[] params = splitField(field);
|
||||||
|
itemService.clearMetadata(context, item, params[0], params[1], params[2], params[3]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLicenseField(Context context, Item item, String field, String value) throws SQLException {
|
||||||
|
String[] params = splitField(field);
|
||||||
|
itemService.addMetadata(context, item, params[0], params[1], params[2], params[3], value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all CC Licenses using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @return A list of available CC Licenses
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<CCLicense> findAllCCLicenses() {
|
||||||
|
return findAllCCLicenses(defaultLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all CC Licenses for the provided language
|
||||||
|
*
|
||||||
|
* @param language - the language for which to find the CC Licenses
|
||||||
|
* @return A list of available CC Licenses for the provided language
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<CCLicense> findAllCCLicenses(String language) {
|
||||||
|
|
||||||
|
if (!ccLicenses.containsKey(language)) {
|
||||||
|
initLicenses(language);
|
||||||
|
}
|
||||||
|
return new LinkedList<>(ccLicenses.get(language).values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the CC License corresponding to the provided ID using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @param id - the ID of the license to be found
|
||||||
|
* @return the corresponding license if found or null when not found
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CCLicense findOne(String id) {
|
||||||
|
return findOne(id, defaultLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the CC License corresponding to the provided ID and provided language
|
||||||
|
*
|
||||||
|
* @param id - the ID of the license to be found
|
||||||
|
* @param language - the language for which to find the CC License
|
||||||
|
* @return the corresponding license if found or null when not found
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CCLicense findOne(String id, String language) {
|
||||||
|
if (!ccLicenses.containsKey(language)) {
|
||||||
|
initLicenses(language);
|
||||||
|
}
|
||||||
|
Map<String, CCLicense> licenseMap = ccLicenses.get(language);
|
||||||
|
if (licenseMap.containsKey(id)) {
|
||||||
|
return licenseMap.get(id);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the licenses for a specific language and cache them in this service
|
||||||
|
*
|
||||||
|
* @param language - the language for which to find the CC Licenses
|
||||||
|
*/
|
||||||
|
private void initLicenses(final String language) {
|
||||||
|
Map<String, CCLicense> licenseMap = ccLicenseConnectorService.retrieveLicenses(language);
|
||||||
|
ccLicenses.put(language, licenseMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI for the provided license ID, based on the provided answers, using the default
|
||||||
|
* language found in the configuration
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the corresponding license URI
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String retrieveLicenseUri(String licenseId, Map<String, String> answerMap) {
|
||||||
|
return retrieveLicenseUri(licenseId, defaultLanguage, answerMap);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI for the provided license ID and language based on the provided answers
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to find the CC License URI
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the corresponding license URI
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String retrieveLicenseUri(String licenseId, String language, Map<String, String> answerMap) {
|
||||||
|
return ccLicenseConnectorService.retrieveRightsByQuestion(licenseId, language, answerMap);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the answer map contains a valid response to all field questions and no answers that don't have a
|
||||||
|
* corresponding question in the license, using the default language found in the config to check the license
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param fullAnswerMap - the answers to the different field questions
|
||||||
|
* @return whether the information is valid
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean verifyLicenseInformation(String licenseId, Map<String, String> fullAnswerMap) {
|
||||||
|
return verifyLicenseInformation(licenseId, defaultLanguage, fullAnswerMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the answer map contains a valid response to all field questions and no answers that don't have a
|
||||||
|
* corresponding question in the license, using the provided language to check the license
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param fullAnswerMap - the answers to the different field questions
|
||||||
|
* @return whether the information is valid
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean verifyLicenseInformation(String licenseId, String language, Map<String, String> fullAnswerMap) {
|
||||||
|
CCLicense ccLicense = findOne(licenseId, language);
|
||||||
|
|
||||||
|
List<CCLicenseField> ccLicenseFieldList = ccLicense.getCcLicenseFieldList();
|
||||||
|
|
||||||
|
for (String field : fullAnswerMap.keySet()) {
|
||||||
|
CCLicenseField ccLicenseField = findCCLicenseField(field, ccLicenseFieldList);
|
||||||
|
if (ccLicenseField == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!containsAnswerEnum(fullAnswerMap.get(field), ccLicenseField)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the full answer map containing empty values when an answer for a field was not provided in the
|
||||||
|
* answerMap, using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the answerMap supplemented with all other license fields with a blank answer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> retrieveFullAnswerMap(String licenseId, Map<String, String> answerMap) {
|
||||||
|
return retrieveFullAnswerMap(licenseId, defaultLanguage, answerMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the full answer map for a provided language, containing empty values when an answer for a field was not
|
||||||
|
* provided in the answerMap.
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the answerMap supplemented with all other license fields with a blank answer for the provided language
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> retrieveFullAnswerMap(String licenseId, String language, Map<String, String> answerMap) {
|
||||||
|
CCLicense ccLicense = findOne(licenseId, language);
|
||||||
|
if (ccLicense == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, String> fullParamMap = new HashMap<>(answerMap);
|
||||||
|
List<CCLicenseField> ccLicenseFieldList = ccLicense.getCcLicenseFieldList();
|
||||||
|
for (CCLicenseField ccLicenseField : ccLicenseFieldList) {
|
||||||
|
if (!fullParamMap.containsKey(ccLicenseField.getId())) {
|
||||||
|
fullParamMap.put(ccLicenseField.getId(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateJurisdiction(fullParamMap);
|
||||||
|
|
||||||
|
return fullParamMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateJurisdiction(final Map<String, String> fullParamMap) {
|
||||||
|
if (fullParamMap.containsKey(JURISDICTION_KEY)) {
|
||||||
|
fullParamMap.put(JURISDICTION_KEY, jurisdiction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsAnswerEnum(final String enumAnswer, final CCLicenseField ccLicenseField) {
|
||||||
|
List<CCLicenseFieldEnum> fieldEnums = ccLicenseField.getFieldEnum();
|
||||||
|
for (CCLicenseFieldEnum fieldEnum : fieldEnums) {
|
||||||
|
if (StringUtils.equals(fieldEnum.getId(), enumAnswer)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CCLicenseField findCCLicenseField(final String field, final List<CCLicenseField> ccLicenseFieldList) {
|
||||||
|
for (CCLicenseField ccLicenseField : ccLicenseFieldList) {
|
||||||
|
if (StringUtils.equals(ccLicenseField.getId(), field)) {
|
||||||
|
return ccLicenseField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the license of the item with a new one based on the provided license URI
|
||||||
|
*
|
||||||
|
* @param context - The relevant DSpace context
|
||||||
|
* @param licenseUri - The license URI to be used in the update
|
||||||
|
* @param item - The item for which to update the license
|
||||||
|
* @return true when the update was successful, false when not
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean updateLicense(final Context context, final String licenseUri, final Item item)
|
||||||
|
throws AuthorizeException, SQLException {
|
||||||
|
try {
|
||||||
|
Document doc = ccLicenseConnectorService.retrieveLicenseRDFDoc(licenseUri);
|
||||||
|
if (doc == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String licenseName = ccLicenseConnectorService.retrieveLicenseName(doc);
|
||||||
|
if (StringUtils.isBlank(licenseName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLicense(context, item);
|
||||||
|
addLicense(context, item, licenseUri, licenseName, doc);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error while updating the license of item: " + item.getID(), e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new license to the item
|
||||||
|
*
|
||||||
|
* @param context - The relevant Dspace context
|
||||||
|
* @param item - The item to which the license will be added
|
||||||
|
* @param licenseUri - The license URI to add
|
||||||
|
* @param licenseName - The license name to add
|
||||||
|
* @param doc - The license to document to add
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addLicense(Context context, Item item, String licenseUri, String licenseName, Document doc)
|
||||||
|
throws SQLException, IOException, AuthorizeException {
|
||||||
|
String uriField = getCCField("uri");
|
||||||
|
String nameField = getCCField("name");
|
||||||
|
|
||||||
|
addLicenseField(context, item, uriField, licenseUri);
|
||||||
|
if (configurationService.getBooleanProperty("cc.submit.addbitstream")) {
|
||||||
|
setLicenseRDF(context, item, fetchLicenseRDF(doc));
|
||||||
|
}
|
||||||
|
if (configurationService.getBooleanProperty("cc.submit.setname")) {
|
||||||
|
addLicenseField(context, item, nameField, licenseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] splitField(String fieldName) {
|
||||||
|
String[] params = new String[4];
|
||||||
|
String[] fParams = fieldName.split("\\.");
|
||||||
|
for (int i = 0; i < fParams.length; i++) {
|
||||||
|
params[i] = fParams[i];
|
||||||
|
}
|
||||||
|
params[3] = Item.ANY;
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,129 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.license;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
|
||||||
import org.dspace.content.Item;
|
|
||||||
import org.dspace.content.MetadataValue;
|
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
|
||||||
import org.dspace.content.service.ItemService;
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class for using CC-related Metadata fields
|
|
||||||
*
|
|
||||||
* @author kevinvandevelde at atmire.com
|
|
||||||
*/
|
|
||||||
public class LicenseMetadataValue {
|
|
||||||
|
|
||||||
protected final ItemService itemService;
|
|
||||||
// Shibboleth for Creative Commons license data - i.e. characters that reliably indicate CC in a URI
|
|
||||||
protected static final String ccShib = "creativecommons";
|
|
||||||
|
|
||||||
private String[] params = new String[4];
|
|
||||||
|
|
||||||
public LicenseMetadataValue(String fieldName) {
|
|
||||||
if (fieldName != null && fieldName.length() > 0) {
|
|
||||||
String[] fParams = fieldName.split("\\.");
|
|
||||||
for (int i = 0; i < fParams.length; i++) {
|
|
||||||
params[i] = fParams[i];
|
|
||||||
}
|
|
||||||
params[3] = Item.ANY;
|
|
||||||
}
|
|
||||||
itemService = ContentServiceFactory.getInstance().getItemService();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns first value that matches Creative Commons 'shibboleth',
|
|
||||||
* or null if no matching values.
|
|
||||||
* NB: this method will succeed only for metadata fields holding CC URIs
|
|
||||||
*
|
|
||||||
* @param item - the item to read
|
|
||||||
* @return value - the first CC-matched value, or null if no such value
|
|
||||||
*/
|
|
||||||
public String ccItemValue(Item item) {
|
|
||||||
List<MetadataValue> dcvalues = itemService.getMetadata(item, params[0], params[1], params[2], params[3]);
|
|
||||||
for (MetadataValue dcvalue : dcvalues) {
|
|
||||||
if ((dcvalue.getValue()).indexOf(ccShib) != -1) {
|
|
||||||
// return first value that matches the shib
|
|
||||||
return dcvalue.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value that matches the value mapped to the passed key if any.
|
|
||||||
* NB: this only delivers a license name (if present in field) given a license URI
|
|
||||||
*
|
|
||||||
* @param item - the item to read
|
|
||||||
* @param key - the key for desired value
|
|
||||||
* @return value - the value associated with key or null if no such value
|
|
||||||
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
|
|
||||||
* to perform a particular action.
|
|
||||||
*/
|
|
||||||
public String keyedItemValue(Item item, String key)
|
|
||||||
throws AuthorizeException, IOException, SQLException {
|
|
||||||
CCLookup ccLookup = new CCLookup();
|
|
||||||
ccLookup.issue(key);
|
|
||||||
String matchValue = ccLookup.getLicenseName();
|
|
||||||
List<MetadataValue> dcvalues = itemService.getMetadata(item, params[0], params[1], params[2], params[3]);
|
|
||||||
for (MetadataValue dcvalue : dcvalues) {
|
|
||||||
if (dcvalue.getValue().equals(matchValue)) {
|
|
||||||
return dcvalue.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the passed value from the set of values for the field in passed item.
|
|
||||||
*
|
|
||||||
* @param context The relevant DSpace Context.
|
|
||||||
* @param item - the item to update
|
|
||||||
* @param value - the value to remove
|
|
||||||
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
|
|
||||||
* to perform a particular action.
|
|
||||||
*/
|
|
||||||
public void removeItemValue(Context context, Item item, String value)
|
|
||||||
throws AuthorizeException, IOException, SQLException {
|
|
||||||
if (value != null) {
|
|
||||||
List<MetadataValue> dcvalues = itemService.getMetadata(item, params[0], params[1], params[2], params[3]);
|
|
||||||
ArrayList<String> arrayList = new ArrayList<String>();
|
|
||||||
for (MetadataValue dcvalue : dcvalues) {
|
|
||||||
if (!dcvalue.getValue().equals(value)) {
|
|
||||||
arrayList.add(dcvalue.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemService.clearMetadata(context, item, params[0], params[1], params[2], params[3]);
|
|
||||||
itemService.addMetadata(context, item, params[0], params[1], params[2], params[3], arrayList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds passed value to the set of values for the field in passed item.
|
|
||||||
*
|
|
||||||
* @param context The relevant DSpace Context.
|
|
||||||
* @param item - the item to update
|
|
||||||
* @param value - the value to add in this field
|
|
||||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
|
||||||
*/
|
|
||||||
public void addItemValue(Context context, Item item, String value) throws SQLException {
|
|
||||||
itemService.addMetadata(context, item, params[0], params[1], params[2], params[3], value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -10,12 +10,14 @@ package org.dspace.license.service;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.license.LicenseMetadataValue;
|
import org.dspace.license.CCLicense;
|
||||||
import org.jdom.Document;
|
import org.jdom.Document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,13 +31,6 @@ public interface CreativeCommonsService {
|
|||||||
|
|
||||||
public static final String CC_BUNDLE_NAME = "CC-LICENSE";
|
public static final String CC_BUNDLE_NAME = "CC-LICENSE";
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple accessor for enabling of CC
|
|
||||||
*
|
|
||||||
* @return is CC enabled?
|
|
||||||
*/
|
|
||||||
public boolean isEnabled();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setLicenseRDF
|
* setLicenseRDF
|
||||||
*
|
*
|
||||||
@@ -50,7 +45,7 @@ public interface CreativeCommonsService {
|
|||||||
* to perform a particular action.
|
* to perform a particular action.
|
||||||
*/
|
*/
|
||||||
public void setLicenseRDF(Context context, Item item, String licenseRdf)
|
public void setLicenseRDF(Context context, Item item, String licenseRdf)
|
||||||
throws SQLException, IOException, AuthorizeException;
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,19 +67,40 @@ public interface CreativeCommonsService {
|
|||||||
*/
|
*/
|
||||||
public void setLicense(Context context, Item item,
|
public void setLicense(Context context, Item item,
|
||||||
InputStream licenseStm, String mimeType)
|
InputStream licenseStm, String mimeType)
|
||||||
throws SQLException, IOException, AuthorizeException;
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
public void removeLicense(Context context, Item item)
|
/**
|
||||||
throws SQLException, IOException, AuthorizeException;
|
* Removes the license file from the item
|
||||||
|
*
|
||||||
|
* @param context - The relevant DSpace Context
|
||||||
|
* @param item - The item from which the license file needs to be removed
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
|
public void removeLicenseFile(Context context, Item item)
|
||||||
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
public boolean hasLicense(Context context, Item item)
|
|
||||||
throws SQLException, IOException;
|
|
||||||
|
|
||||||
public String getLicenseURL(Context context, Item item)
|
public String getLicenseURL(Context context, Item item)
|
||||||
throws SQLException, IOException, AuthorizeException;
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
public String getLicenseRDF(Context context, Item item)
|
|
||||||
throws SQLException, IOException, AuthorizeException;
|
/**
|
||||||
|
* Returns the stored license uri of the item
|
||||||
|
*
|
||||||
|
* @param item - The item for which to retrieve the stored license uri
|
||||||
|
* @return the stored license uri of the item
|
||||||
|
*/
|
||||||
|
public String getLicenseURI(Item item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored license name of the item
|
||||||
|
*
|
||||||
|
* @param item - The item for which to retrieve the stored license name
|
||||||
|
* @return the stored license name of the item
|
||||||
|
*/
|
||||||
|
public String getLicenseName(Item item);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Creative Commons license RDF, returning Bitstream object.
|
* Get Creative Commons license RDF, returning Bitstream object.
|
||||||
@@ -97,7 +113,7 @@ public interface CreativeCommonsService {
|
|||||||
* to perform a particular action.
|
* to perform a particular action.
|
||||||
*/
|
*/
|
||||||
public Bitstream getLicenseRdfBitstream(Item item)
|
public Bitstream getLicenseRdfBitstream(Item item)
|
||||||
throws SQLException, IOException, AuthorizeException;
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Creative Commons license Text, returning Bitstream object.
|
* Get Creative Commons license Text, returning Bitstream object.
|
||||||
@@ -112,7 +128,7 @@ public interface CreativeCommonsService {
|
|||||||
* is no longer stored (see https://jira.duraspace.org/browse/DS-2604)
|
* is no longer stored (see https://jira.duraspace.org/browse/DS-2604)
|
||||||
*/
|
*/
|
||||||
public Bitstream getLicenseTextBitstream(Item item)
|
public Bitstream getLicenseTextBitstream(Item item)
|
||||||
throws SQLException, IOException, AuthorizeException;
|
throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a few license-specific properties. We expect these to be cached at
|
* Get a few license-specific properties. We expect these to be cached at
|
||||||
@@ -121,7 +137,7 @@ public interface CreativeCommonsService {
|
|||||||
* @param fieldId name of the property.
|
* @param fieldId name of the property.
|
||||||
* @return its value.
|
* @return its value.
|
||||||
*/
|
*/
|
||||||
public LicenseMetadataValue getCCField(String fieldId);
|
public String getCCField(String fieldId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply same transformation on the document to retrieve only the most
|
* Apply same transformation on the document to retrieve only the most
|
||||||
@@ -138,15 +154,134 @@ public interface CreativeCommonsService {
|
|||||||
* Remove license information, delete also the bitstream
|
* Remove license information, delete also the bitstream
|
||||||
*
|
*
|
||||||
* @param context - DSpace Context
|
* @param context - DSpace Context
|
||||||
* @param uriField - the metadata field for license uri
|
|
||||||
* @param nameField - the metadata field for license name
|
|
||||||
* @param item - the item
|
* @param item - the item
|
||||||
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
|
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
|
||||||
* to perform a particular action.
|
* to perform a particular action.
|
||||||
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
|
||||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||||
*/
|
*/
|
||||||
public void removeLicense(Context context, LicenseMetadataValue uriField,
|
public void removeLicense(Context context, Item item)
|
||||||
LicenseMetadataValue nameField, Item item)
|
throws AuthorizeException, IOException, SQLException;
|
||||||
throws AuthorizeException, IOException, SQLException;
|
|
||||||
|
/**
|
||||||
|
* Find all CC Licenses using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @return A list of available CC Licenses
|
||||||
|
*/
|
||||||
|
public List<CCLicense> findAllCCLicenses();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all CC Licenses for the provided language
|
||||||
|
*
|
||||||
|
* @param language - the language for which to find the CC Licenses
|
||||||
|
* @return A list of available CC Licenses for the provided language
|
||||||
|
*/
|
||||||
|
public List<CCLicense> findAllCCLicenses(String language);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the CC License corresponding to the provided ID using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @param id - the ID of the license to be found
|
||||||
|
* @return the corresponding license if found or null when not found
|
||||||
|
*/
|
||||||
|
public CCLicense findOne(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the CC License corresponding to the provided ID and provided language
|
||||||
|
*
|
||||||
|
* @param id - the ID of the license to be found
|
||||||
|
* @param language - the language for which to find the CC License
|
||||||
|
* @return the corresponding license if found or null when not found
|
||||||
|
*/
|
||||||
|
public CCLicense findOne(String id, String language);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI for the provided license ID, based on the provided answers, using the default
|
||||||
|
* language found in the configuration
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the corresponding license URI
|
||||||
|
*/
|
||||||
|
public String retrieveLicenseUri(String licenseId, Map<String, String> answerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the CC License URI for the provided license ID and language based on the provided answers
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to find the CC License URI
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the corresponding license URI
|
||||||
|
*/
|
||||||
|
public String retrieveLicenseUri(String licenseId, String language, Map<String, String> answerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the full answer map containing empty values when an answer for a field was not provided in the
|
||||||
|
* answerMap, using the default language found in the configuration
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the answerMap supplemented with all other license fields with a blank answer
|
||||||
|
*/
|
||||||
|
public Map<String, String> retrieveFullAnswerMap(String licenseId, Map<String, String> answerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the full answer map for a provided language, containing empty values when an answer for a field was not
|
||||||
|
* provided in the answerMap.
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the answerMap supplemented with all other license fields with a blank answer for the provided language
|
||||||
|
*/
|
||||||
|
public Map<String, String> retrieveFullAnswerMap(String licenseId, String language, Map<String, String> answerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the answer map contains a valid response to all field questions and no answers that don't have a
|
||||||
|
* corresponding question in the license, using the default language found in the config to check the license
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param fullAnswerMap - the answers to the different field questions
|
||||||
|
* @return whether the information is valid
|
||||||
|
*/
|
||||||
|
public boolean verifyLicenseInformation(String licenseId, Map<String, String> fullAnswerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify whether the answer map contains a valid response to all field questions and no answers that don't have a
|
||||||
|
* corresponding question in the license, using the provided language to check the license
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param fullAnswerMap - the answers to the different field questions
|
||||||
|
* @return whether the information is valid
|
||||||
|
*/
|
||||||
|
public boolean verifyLicenseInformation(String licenseId, String language, Map<String, String> fullAnswerMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the license of the item with a new one based on the provided license URI
|
||||||
|
*
|
||||||
|
* @param context - The relevant DSpace context
|
||||||
|
* @param licenseUri - The license URI to be used in the update
|
||||||
|
* @param item - The item for which to update the license
|
||||||
|
* @return true when the update was successful, false when not
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public boolean updateLicense(final Context context, String licenseUri, final Item item)
|
||||||
|
throws AuthorizeException, SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new license to the item
|
||||||
|
*
|
||||||
|
* @param context - The relevant Dspace context
|
||||||
|
* @param item - The item to which the license will be added
|
||||||
|
* @param licenseUri - The license URI to add
|
||||||
|
* @param licenseName - The license name to add
|
||||||
|
* @param doc - The license to document to add
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
|
public void addLicense(Context context, Item item, String licenseUri, String licenseName, Document doc)
|
||||||
|
throws SQLException, IOException, AuthorizeException;
|
||||||
}
|
}
|
||||||
|
@@ -7,70 +7,72 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts;
|
package org.dspace.scripts;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.io.InputStream;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
import org.apache.commons.cli.DefaultParser;
|
||||||
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
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.
|
* This is the class that should be extended for each Script. This class will contain the logic needed to run and it'll
|
||||||
* it provides the basic variables to be hold by the script as well as the means to initialize, parse and run the script
|
* fetch the information that it needs from the {@link ScriptConfiguration} provided through the diamond operators.
|
||||||
* Every DSpaceRunnable that is implemented in this way should be defined in the scripts.xml config file as a bean
|
* This will be the dspaceRunnableClass for the {@link ScriptConfiguration} beans. Specifically created for each
|
||||||
|
* script
|
||||||
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public abstract class DSpaceRunnable implements Runnable {
|
public abstract class DSpaceRunnable<T extends ScriptConfiguration> 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
|
* The CommandLine object for the script that'll hold the information
|
||||||
*/
|
*/
|
||||||
protected CommandLine commandLine;
|
protected CommandLine commandLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The possible options for this script
|
* This EPerson identifier variable is the uuid of the eperson that's running the script
|
||||||
*/
|
*/
|
||||||
protected Options options;
|
private UUID epersonIdentifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The handler that deals with this script. This handler can currently either be a RestDSpaceRunnableHandler or
|
* 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
|
* a CommandlineDSpaceRunnableHandler depending from where the script is called
|
||||||
*/
|
*/
|
||||||
protected DSpaceRunnableHandler handler;
|
protected DSpaceRunnableHandler handler;
|
||||||
|
|
||||||
@Autowired
|
/**
|
||||||
private AuthorizeService authorizeService;
|
* This method will return the Configuration that the implementing DSpaceRunnable uses
|
||||||
|
* @return The {@link ScriptConfiguration} that this implementing DspaceRunnable uses
|
||||||
|
*/
|
||||||
|
public abstract T getScriptConfiguration();
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
private void setHandler(DSpaceRunnableHandler dSpaceRunnableHandler) {
|
||||||
|
this.handler = dSpaceRunnableHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Required
|
/**
|
||||||
public void setName(String name) {
|
* This method sets the appropriate DSpaceRunnableHandler depending on where it was ran from and it parses
|
||||||
this.name = name;
|
* 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
|
||||||
public String getDescription() {
|
* @param currentUser
|
||||||
return description;
|
* @throws ParseException If something goes wrong
|
||||||
}
|
*/
|
||||||
|
public void initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
|
||||||
@Required
|
EPerson currentUser) throws ParseException {
|
||||||
public void setDescription(String description) {
|
if (currentUser != null) {
|
||||||
this.description = description;
|
this.setEpersonIdentifier(currentUser.getID());
|
||||||
}
|
}
|
||||||
|
this.setHandler(dSpaceRunnableHandler);
|
||||||
public Options getOptions() {
|
this.parse(args);
|
||||||
return options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,18 +82,16 @@ public abstract class DSpaceRunnable implements Runnable {
|
|||||||
* @throws ParseException If something goes wrong
|
* @throws ParseException If something goes wrong
|
||||||
*/
|
*/
|
||||||
private void parse(String[] args) throws ParseException {
|
private void parse(String[] args) throws ParseException {
|
||||||
commandLine = new DefaultParser().parse(getOptions(), args);
|
commandLine = new DefaultParser().parse(getScriptConfiguration().getOptions(), args);
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will call upon the {@link DSpaceRunnableHandler#printHelp(Options, String)} method with the script's
|
* This method has to be included in every script and handles the setup of the script by parsing the CommandLine
|
||||||
* options and name
|
* and setting the variables
|
||||||
|
* @throws ParseException If something goes wrong
|
||||||
*/
|
*/
|
||||||
public void printHelp() {
|
public abstract void setup() throws ParseException;
|
||||||
handler.printHelp(options, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the run() method from the Runnable interface that we implement. This method will handle the running
|
* This is the run() method from the Runnable interface that we implement. This method will handle the running
|
||||||
@@ -108,22 +108,6 @@ public abstract class DSpaceRunnable implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* 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
|
* contain all the logic needed
|
||||||
@@ -132,25 +116,46 @@ public abstract class DSpaceRunnable implements Runnable {
|
|||||||
public abstract void internalRun() throws Exception;
|
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
|
* This method will call upon the {@link DSpaceRunnableHandler#printHelp(Options, String)} method with the script's
|
||||||
* and setting the variables
|
* options and name
|
||||||
* @throws ParseException If something goes wrong
|
|
||||||
*/
|
*/
|
||||||
public abstract void setup() throws ParseException;
|
public void printHelp() {
|
||||||
|
handler.printHelp(getScriptConfiguration().getOptions(), getScriptConfiguration().getName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return if the script is allowed to execute in the given context. This is by default set
|
* This method will traverse all the options and it'll grab options defined as an InputStream type to then save
|
||||||
* to the currentUser in the context being an admin, however this can be overwritten by each script individually
|
* the filename specified by that option in a list of Strings that'll be returned in the end
|
||||||
* if different rules apply
|
* @return The list of Strings representing filenames from the options given to the script
|
||||||
* @param context The relevant DSpace context
|
|
||||||
* @return A boolean indicating whether the script is allowed to execute or not
|
|
||||||
*/
|
*/
|
||||||
public boolean isAllowedToExecute(Context context) {
|
public List<String> getFileNamesFromInputStreamOptions() {
|
||||||
try {
|
List<String> fileNames = new LinkedList<>();
|
||||||
return authorizeService.isAdmin(context);
|
|
||||||
} catch (SQLException e) {
|
for (Option option : getScriptConfiguration().getOptions().getOptions()) {
|
||||||
handler.logError("Error occured when trying to verify permissions for script: " + name);
|
if (option.getType() == InputStream.class &&
|
||||||
|
StringUtils.isNotBlank(commandLine.getOptionValue(option.getOpt()))) {
|
||||||
|
fileNames.add(commandLine.getOptionValue(option.getOpt()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return fileNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the epersonIdentifier
|
||||||
|
* This EPerson identifier variable is the uuid of the eperson that's running the script
|
||||||
|
* @return the epersonIdentifier value of this DSpaceRunnable
|
||||||
|
*/
|
||||||
|
public UUID getEpersonIdentifier() {
|
||||||
|
return epersonIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the epersonIdentifier
|
||||||
|
* This EPerson identifier variable is the uuid of the eperson that's running the script
|
||||||
|
* @param epersonIdentifier The epersonIdentifier to be set on this DSpaceRunnable
|
||||||
|
*/
|
||||||
|
public void setEpersonIdentifier(UUID epersonIdentifier) {
|
||||||
|
this.epersonIdentifier = epersonIdentifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
package org.dspace.scripts;
|
package org.dspace.scripts;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
@@ -80,6 +81,8 @@ public class Process implements ReloadableEntity<Integer> {
|
|||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date creationTime;
|
private Date creationTime;
|
||||||
|
|
||||||
|
public static final String BITSTREAM_TYPE_METADATAFIELD = "dspace.process.filetype";
|
||||||
|
|
||||||
protected Process() {
|
protected Process() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +177,9 @@ public class Process implements ReloadableEntity<Integer> {
|
|||||||
* @return The Bitstreams that are used or created by the process
|
* @return The Bitstreams that are used or created by the process
|
||||||
*/
|
*/
|
||||||
public List<Bitstream> getBitstreams() {
|
public List<Bitstream> getBitstreams() {
|
||||||
|
if (bitstreams == null) {
|
||||||
|
bitstreams = new LinkedList<>();
|
||||||
|
}
|
||||||
return bitstreams;
|
return bitstreams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,18 +7,33 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts;
|
package org.dspace.scripts;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.ListUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataField;
|
||||||
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.ProcessStatus;
|
import org.dspace.content.ProcessStatus;
|
||||||
import org.dspace.content.dao.ProcessDAO;
|
import org.dspace.content.dao.ProcessDAO;
|
||||||
|
import org.dspace.content.service.BitstreamFormatService;
|
||||||
|
import org.dspace.content.service.BitstreamService;
|
||||||
|
import org.dspace.content.service.MetadataFieldService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
@@ -35,6 +50,18 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ProcessDAO processDAO;
|
private ProcessDAO processDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BitstreamService bitstreamService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BitstreamFormatService bitstreamFormatService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MetadataFieldService metadataFieldService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Process create(Context context, EPerson ePerson, String scriptName,
|
public Process create(Context context, EPerson ePerson, String scriptName,
|
||||||
List<DSpaceCommandLineParameter> parameters) throws SQLException {
|
List<DSpaceCommandLineParameter> parameters) throws SQLException {
|
||||||
@@ -113,11 +140,35 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(Context context, Process process) throws SQLException {
|
public void appendFile(Context context, Process process, InputStream is, String type, String fileName)
|
||||||
|
throws IOException, SQLException, AuthorizeException {
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, is);
|
||||||
|
if (getBitstream(context, process, type) != null) {
|
||||||
|
throw new IllegalArgumentException("Cannot create another file of type: " + type + " for this process" +
|
||||||
|
" with id: " + process.getID());
|
||||||
|
}
|
||||||
|
bitstream.setName(context, fileName);
|
||||||
|
bitstreamService.setFormat(context, bitstream, bitstreamFormatService.guessFormat(context, bitstream));
|
||||||
|
MetadataField dspaceProcessFileTypeField = metadataFieldService
|
||||||
|
.findByString(context, Process.BITSTREAM_TYPE_METADATAFIELD, '.');
|
||||||
|
bitstreamService.addMetadata(context, bitstream, dspaceProcessFileTypeField, null, type);
|
||||||
|
authorizeService.addPolicy(context, bitstream, Constants.READ, context.getCurrentUser());
|
||||||
|
authorizeService.addPolicy(context, bitstream, Constants.WRITE, context.getCurrentUser());
|
||||||
|
authorizeService.addPolicy(context, bitstream, Constants.DELETE, context.getCurrentUser());
|
||||||
|
bitstreamService.update(context, bitstream);
|
||||||
|
process.addBitstream(bitstream);
|
||||||
|
update(context, process);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context, Process process) throws SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
|
for (Bitstream bitstream : ListUtils.emptyIfNull(process.getBitstreams())) {
|
||||||
|
bitstreamService.delete(context, bitstream);
|
||||||
|
}
|
||||||
processDAO.delete(context, process);
|
processDAO.delete(context, process);
|
||||||
log.info(LogManager.getHeader(context, "process_delete", "Process with ID " + process.getID()
|
log.info(LogManager.getHeader(context, "process_delete", "Process with ID " + process.getID()
|
||||||
+ " and name " + process.getName() + " has been deleted"));
|
+ " and name " + process.getName() + " has been deleted"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -141,8 +192,57 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
return parameterList;
|
return parameterList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitstream getBitstreamByName(Context context, Process process, String bitstreamName) {
|
||||||
|
for (Bitstream bitstream : getBitstreams(context, process)) {
|
||||||
|
if (StringUtils.equals(bitstream.getName(), bitstreamName)) {
|
||||||
|
return bitstream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitstream getBitstream(Context context, Process process, String type) {
|
||||||
|
List<Bitstream> allBitstreams = process.getBitstreams();
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
if (allBitstreams != null) {
|
||||||
|
for (Bitstream bitstream : allBitstreams) {
|
||||||
|
if (StringUtils.equals(bitstreamService.getMetadata(bitstream,
|
||||||
|
Process.BITSTREAM_TYPE_METADATAFIELD), type)) {
|
||||||
|
return bitstream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Bitstream> getBitstreams(Context context, Process process) {
|
||||||
|
return process.getBitstreams();
|
||||||
|
}
|
||||||
|
|
||||||
public int countTotal(Context context) throws SQLException {
|
public int countTotal(Context context) throws SQLException {
|
||||||
return processDAO.countRows(context);
|
return processDAO.countRows(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getFileTypesForProcessBitstreams(Context context, Process process) {
|
||||||
|
List<Bitstream> list = getBitstreams(context, process);
|
||||||
|
Set<String> fileTypesSet = new HashSet<>();
|
||||||
|
for (Bitstream bitstream : list) {
|
||||||
|
List<MetadataValue> metadata = bitstreamService.getMetadata(bitstream,
|
||||||
|
Process.BITSTREAM_TYPE_METADATAFIELD, Item.ANY);
|
||||||
|
if (metadata != null && !metadata.isEmpty()) {
|
||||||
|
fileTypesSet.add(metadata.get(0).getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ArrayList<>(fileTypesSet);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,33 +7,46 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts;
|
package org.dspace.scripts;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.kernel.ServiceManager;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
import org.dspace.scripts.service.ScriptService;
|
import org.dspace.scripts.service.ScriptService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation for the {@link ScriptService}
|
* The implementation for the {@link ScriptService}
|
||||||
*/
|
*/
|
||||||
public class ScriptServiceImpl implements ScriptService {
|
public class ScriptServiceImpl implements ScriptService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ScriptServiceImpl.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private List<DSpaceRunnable> dSpaceRunnables;
|
private ServiceManager serviceManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DSpaceRunnable getScriptForName(String name) {
|
public ScriptConfiguration getScriptConfiguration(String name) {
|
||||||
return dSpaceRunnables.stream()
|
return serviceManager.getServiceByName(name, ScriptConfiguration.class);
|
||||||
.filter(dSpaceRunnable -> StringUtils.equalsIgnoreCase(dSpaceRunnable.getName(), name))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DSpaceRunnable> getDSpaceRunnables(Context context) {
|
public List<ScriptConfiguration> getScriptConfigurations(Context context) {
|
||||||
return dSpaceRunnables.stream().filter(
|
return serviceManager.getServicesByType(ScriptConfiguration.class).stream().filter(
|
||||||
dSpaceRunnable -> dSpaceRunnable.isAllowedToExecute(context)).collect(Collectors.toList());
|
scriptConfiguration -> scriptConfiguration.isAllowedToExecute(context)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DSpaceRunnable createDSpaceRunnableForScriptConfiguration(ScriptConfiguration scriptToExecute)
|
||||||
|
throws IllegalAccessException, InstantiationException {
|
||||||
|
try {
|
||||||
|
return (DSpaceRunnable) scriptToExecute.getDspaceRunnableClass().getDeclaredConstructor().newInstance();
|
||||||
|
} catch (InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* 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.configuration;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an Abstract class that a ScriptConfiguration can inherit to further implement this
|
||||||
|
* and represent a script's configuration
|
||||||
|
*/
|
||||||
|
public abstract class ScriptConfiguration<T extends DSpaceRunnable> implements BeanNameAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The possible options for this script
|
||||||
|
*/
|
||||||
|
protected Options options;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the description
|
||||||
|
* @return the description value of this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the description
|
||||||
|
* @param description The description to be set on this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the name
|
||||||
|
* @return the name value of this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the name
|
||||||
|
* @param name The name to be set on this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the dspaceRunnableClass
|
||||||
|
* @return the dspaceRunnableClass value of this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public abstract Class<T> getDspaceRunnableClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the dspaceRunnableClass
|
||||||
|
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this IndexDiscoveryScriptConfiguration
|
||||||
|
*/
|
||||||
|
public abstract void setDspaceRunnableClass(Class<T> dspaceRunnableClass);
|
||||||
|
/**
|
||||||
|
* 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 abstract boolean isAllowedToExecute(Context context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The getter for the options of the Script
|
||||||
|
* @return the options value of this ScriptConfiguration
|
||||||
|
*/
|
||||||
|
public abstract Options getOptions();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanName(String beanName) {
|
||||||
|
this.name = beanName;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,9 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts.handler;
|
package org.dspace.scripts.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an interface meant to be implemented by any DSpaceRunnableHandler to specify specific execution methods
|
* This is an interface meant to be implemented by any DSpaceRunnableHandler to specify specific execution methods
|
||||||
@@ -78,4 +83,28 @@ public interface DSpaceRunnableHandler {
|
|||||||
* @param name The name of the script
|
* @param name The name of the script
|
||||||
*/
|
*/
|
||||||
public void printHelp(Options options, String name);
|
public void printHelp(Options options, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will grab the InputStream for the file defined by the given file name. The exact implementation will
|
||||||
|
* differ based on whether it's a REST call or CommandLine call. The REST Call will look for Bitstreams in the
|
||||||
|
* Database whereas the CommandLine call will look on the filesystem
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param fileName The filename for the file that holds the InputStream
|
||||||
|
* @return The InputStream for the file defined by the given file name
|
||||||
|
* @throws IOException If something goes wrong
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
public Optional<InputStream> getFileStream(Context context, String fileName) throws IOException, AuthorizeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will write the InputStream to either a file on the filesystem or a bitstream in the database
|
||||||
|
* depending on whether it's coming from a CommandLine call or REST call respectively
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param fileName The filename
|
||||||
|
* @param inputStream The inputstream to be written
|
||||||
|
* @param type The type of the file
|
||||||
|
* @throws IOException If something goes wrong
|
||||||
|
*/
|
||||||
|
public void writeFilestream(Context context, String fileName, InputStream inputStream, String type)
|
||||||
|
throws IOException, SQLException, AuthorizeException;
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts.handler.impl;
|
package org.dspace.scripts.handler.impl;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.core.Context;
|
||||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,4 +91,20 @@ public class CommandLineDSpaceRunnableHandler implements DSpaceRunnableHandler {
|
|||||||
formatter.printHelp(name, options);
|
formatter.printHelp(name, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<InputStream> getFileStream(Context context, String fileName) throws IOException {
|
||||||
|
File file = new File(fileName);
|
||||||
|
if (!(file.exists() && file.isFile())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(FileUtils.openInputStream(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeFilestream(Context context, String fileName, InputStream inputStream, String type)
|
||||||
|
throws IOException {
|
||||||
|
File file = new File(fileName);
|
||||||
|
FileUtils.copyInputStreamToFile(inputStream, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts.service;
|
package org.dspace.scripts.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.scripts.DSpaceCommandLineParameter;
|
import org.dspace.scripts.DSpaceCommandLineParameter;
|
||||||
@@ -104,13 +108,28 @@ public interface ProcessService {
|
|||||||
*/
|
*/
|
||||||
public void complete(Context context, Process process) throws SQLException;
|
public void complete(Context context, Process process) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method will create a bitstream from the given inputstream with the given type as metadata and given name
|
||||||
|
* as name and attach it to the given process
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param process The process for which the bitstream will be made
|
||||||
|
* @param is The inputstream for the bitstream
|
||||||
|
* @param type The type of the bitstream
|
||||||
|
* @param fileName The name of the bitstream
|
||||||
|
* @throws IOException If something goes wrong
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
public void appendFile(Context context, Process process, InputStream is, String type, String fileName)
|
||||||
|
throws IOException, SQLException, AuthorizeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will delete the given Process object from the database
|
* This method will delete the given Process object from the database
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param process The Process object to be deleted
|
* @param process The Process object to be deleted
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
public void delete(Context context, Process process) throws SQLException;
|
public void delete(Context context, Process process) throws SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be used to update the given Process object in the database
|
* This method will be used to update the given Process object in the database
|
||||||
@@ -128,6 +147,32 @@ public interface ProcessService {
|
|||||||
*/
|
*/
|
||||||
public List<DSpaceCommandLineParameter> getParameters(Process process);
|
public List<DSpaceCommandLineParameter> getParameters(Process process);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return the Bitstream that matches the given name for the given Process
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param process The process that should hold the requested Bitstream
|
||||||
|
* @param bitstreamName The name of the requested Bitstream
|
||||||
|
* @return The Bitstream from the given Process that matches the given bitstream name
|
||||||
|
*/
|
||||||
|
public Bitstream getBitstreamByName(Context context, Process process, String bitstreamName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return the Bitstream for a given process with a given type
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param process The process that holds the Bitstreams to be searched in
|
||||||
|
* @param type The type that the Bitstream must have
|
||||||
|
* @return The Bitstream of the given type for the given Process
|
||||||
|
*/
|
||||||
|
public Bitstream getBitstream(Context context, Process process, String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return all the Bitstreams for a given process
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param process The process that holds the Bitstreams to be searched in
|
||||||
|
* @return The list of Bitstreams
|
||||||
|
*/
|
||||||
|
public List<Bitstream> getBitstreams(Context context, Process process);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the total amount of Process objects in the dataase
|
* Returns the total amount of Process objects in the dataase
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
@@ -136,4 +181,12 @@ public interface ProcessService {
|
|||||||
*/
|
*/
|
||||||
int countTotal(Context context) throws SQLException;
|
int countTotal(Context context) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will return a list of Strings where each String represents the type of a Bitstream in the Process given
|
||||||
|
* @param context The DSpace context
|
||||||
|
* @param process The Process object that we'll use to find the bitstreams
|
||||||
|
* @return A list of Strings where each String represents a fileType that is in the Process
|
||||||
|
*/
|
||||||
|
public List<String> getFileTypesForProcessBitstreams(Context context, Process process);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service will deal with logic to handle DSpaceRunnable objects
|
* This service will deal with logic to handle DSpaceRunnable objects
|
||||||
@@ -18,16 +19,29 @@ import org.dspace.scripts.DSpaceRunnable;
|
|||||||
public interface ScriptService {
|
public interface ScriptService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return the DSpaceRunnable that has the name that's equal to the name given in the parameters
|
* This method will return the ScriptConfiguration that has the name that's equal to the name given in the
|
||||||
|
* parameters
|
||||||
* @param name The name that the script has to match
|
* @param name The name that the script has to match
|
||||||
* @return The matching DSpaceRunnable script
|
* @return The matching ScriptConfiguration
|
||||||
*/
|
*/
|
||||||
DSpaceRunnable getScriptForName(String name);
|
ScriptConfiguration getScriptConfiguration(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will return a list of DSpaceRunnable objects for which the given Context is authorized to use them
|
* This method will return a list of ScriptConfiguration objects for which the given Context is authorized
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @return The list of accessible DSpaceRunnable scripts for this context
|
* @return The list of accessible ScriptConfiguration scripts for this context
|
||||||
*/
|
*/
|
||||||
List<DSpaceRunnable> getDSpaceRunnables(Context context);
|
List<ScriptConfiguration> getScriptConfigurations(Context context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will create a new instance of the DSpaceRunnable that's linked with this Scriptconfiguration
|
||||||
|
* It'll grab the DSpaceRunnable class from the ScriptConfiguration's variables and create a new instance of it
|
||||||
|
* to return
|
||||||
|
* @param scriptToExecute The relevant ScriptConfiguration
|
||||||
|
* @return The new instance of the DSpaceRunnable class
|
||||||
|
* @throws IllegalAccessException If something goes wrong
|
||||||
|
* @throws InstantiationException If something goes wrong
|
||||||
|
*/
|
||||||
|
DSpaceRunnable createDSpaceRunnableForScriptConfiguration(ScriptConfiguration scriptToExecute)
|
||||||
|
throws IllegalAccessException, InstantiationException;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
id,collection,dc.contributor.author
|
||||||
|
+,"123456789/2","Donald, SmithImported"
|
|
@@ -82,9 +82,9 @@
|
|||||||
<!--Step will be to select a Creative Commons License -->
|
<!--Step will be to select a Creative Commons License -->
|
||||||
<!-- Uncomment this step to allow the user to select a Creative Commons
|
<!-- Uncomment this step to allow the user to select a Creative Commons
|
||||||
license -->
|
license -->
|
||||||
<!-- <step id="creative-commons"> <heading>submit.progressbar.CClicense</heading>
|
<step id="cclicense"> <heading>submit.progressbar.CClicense</heading>
|
||||||
<processing-class>org.dspace.submit.step.CCLicenseStep</processing-class>
|
<processing-class>org.dspace.app.rest.submit.step.CCLicenseStep</processing-class>
|
||||||
<type>cclicense</type> </step> -->
|
<type>cclicense</type> </step>
|
||||||
|
|
||||||
<!--Step will be to Check for potential duplicate -->
|
<!--Step will be to Check for potential duplicate -->
|
||||||
<!-- <step id="detect-duplicate"> <heading>submit.progressbar.detect.duplicate</heading>
|
<!-- <step id="detect-duplicate"> <heading>submit.progressbar.detect.duplicate</heading>
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
|
|
||||||
<!--Step will be to Sign off on the License -->
|
<!--Step will be to Sign off on the License -->
|
||||||
<step id="license"/>
|
<step id="license"/>
|
||||||
<!-- <step id="creative-commons"/> -->
|
<step id="cclicense"/>
|
||||||
<!-- <step id="verify"/> -->
|
<!-- <step id="verify"/> -->
|
||||||
</submission-process>
|
</submission-process>
|
||||||
|
|
||||||
|
@@ -108,3 +108,15 @@ plugin.sequence.java.util.Collection = \
|
|||||||
java.util.LinkedList, \
|
java.util.LinkedList, \
|
||||||
java.util.Stack, \
|
java.util.Stack, \
|
||||||
java.util.TreeSet
|
java.util.TreeSet
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# PROPERTIES USED TO TEST CONFIGURATION #
|
||||||
|
# PROPERTY EXPOSURE VIA REST #
|
||||||
|
###########################################
|
||||||
|
rest.properties.exposed = configuration.exposed.single.value
|
||||||
|
rest.properties.exposed = configuration.exposed.array.value
|
||||||
|
rest.properties.exposed = configuration.not.existing
|
||||||
|
|
||||||
|
configuration.not.exposed = secret_value
|
||||||
|
configuration.exposed.single.value = public_value
|
||||||
|
configuration.exposed.array.value = public_value_1, public_value_2
|
||||||
|
@@ -4,13 +4,23 @@
|
|||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||||
|
|
||||||
<bean id="indexClient" class="org.dspace.discovery.IndexClient" scope="prototype">
|
<bean id="index-discovery" class="org.dspace.discovery.IndexDiscoveryScriptConfiguration">
|
||||||
<property name="name" value="index-discovery"/>
|
|
||||||
<property name="description" value="Update Discovery Solr Search Index"/>
|
<property name="description" value="Update Discovery Solr Search Index"/>
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.discovery.IndexClient"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="MockScript" class="org.dspace.scripts.impl.MockDSpaceRunnableScript" scope="prototype">
|
<bean id="metadata-import" class="org.dspace.app.bulkedit.MetadataImportCliScriptConfiguration">
|
||||||
<property name="name" value="mock-script" />
|
<property name="description" value="Import metadata after batch editing" />
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.app.bulkedit.MetadataImportCLI"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="metadata-export" class="org.dspace.app.bulkedit.MetadataExportScriptConfiguration">
|
||||||
|
<property name="description" value="Export metadata for batch editing"/>
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.app.bulkedit.MetadataExport"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="mock-script" class="org.dspace.scripts.MockDSpaceRunnableScriptConfiguration" scope="prototype">
|
||||||
<property name="description" value="Mocking a script for testing purposes" />
|
<property name="description" value="Mocking a script for testing purposes" />
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.scripts.impl.MockDSpaceRunnableScript"/>
|
||||||
</bean>
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -18,6 +18,7 @@ import java.io.OutputStreamWriter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.AbstractUnitTest;
|
import org.dspace.AbstractUnitTest;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -67,7 +68,7 @@ public class DSpaceCSVTest extends AbstractUnitTest {
|
|||||||
out = null;
|
out = null;
|
||||||
|
|
||||||
// Test the CSV parsing was OK
|
// Test the CSV parsing was OK
|
||||||
DSpaceCSV dcsv = new DSpaceCSV(new File(filename), context);
|
DSpaceCSV dcsv = new DSpaceCSV(FileUtils.openInputStream(new File(filename)), context);
|
||||||
String[] lines = dcsv.getCSVLinesAsStringArray();
|
String[] lines = dcsv.getCSVLinesAsStringArray();
|
||||||
assertThat("testDSpaceCSV Good CSV", lines.length, equalTo(8));
|
assertThat("testDSpaceCSV Good CSV", lines.length, equalTo(8));
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ public class DSpaceCSVTest extends AbstractUnitTest {
|
|||||||
|
|
||||||
// Test the CSV parsing was OK
|
// Test the CSV parsing was OK
|
||||||
try {
|
try {
|
||||||
dcsv = new DSpaceCSV(new File(filename), context);
|
dcsv = new DSpaceCSV(FileUtils.openInputStream(new File(filename)), context);
|
||||||
lines = dcsv.getCSVLinesAsStringArray();
|
lines = dcsv.getCSVLinesAsStringArray();
|
||||||
|
|
||||||
fail("An exception should have been thrown due to bad CSV");
|
fail("An exception should have been thrown due to bad CSV");
|
||||||
@@ -124,7 +125,7 @@ public class DSpaceCSVTest extends AbstractUnitTest {
|
|||||||
|
|
||||||
// Test the CSV parsing was OK
|
// Test the CSV parsing was OK
|
||||||
try {
|
try {
|
||||||
dcsv = new DSpaceCSV(new File(filename), context);
|
dcsv = new DSpaceCSV(FileUtils.openInputStream(new File(filename)), context);
|
||||||
lines = dcsv.getCSVLinesAsStringArray();
|
lines = dcsv.getCSVLinesAsStringArray();
|
||||||
|
|
||||||
fail("An exception should have been thrown due to bad CSV");
|
fail("An exception should have been thrown due to bad CSV");
|
||||||
|
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.dspace.AbstractIntegrationTest;
|
||||||
|
import org.dspace.app.launcher.ScriptLauncher;
|
||||||
|
import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
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.InstallItemService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MetadataExportTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||||
|
private CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||||
|
private WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||||
|
private InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService();
|
||||||
|
private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metadataExportToCsvTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Community community = communityService.create(null, context);
|
||||||
|
Collection collection = collectionService.create(context, community);
|
||||||
|
WorkspaceItem wi = workspaceItemService.create(context, collection, true);
|
||||||
|
Item item = wi.getItem();
|
||||||
|
itemService.addMetadata(context, item, "dc", "contributor", "author", null, "Donald, Smith");
|
||||||
|
item = installItemService.installItem(context, wi);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String fileLocation = configurationService.getProperty("dspace.dir") + testProps.get("test.exportcsv")
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
String[] args = new String[] {"metadata-export", "-i", String.valueOf(item.getHandle()), "-f", fileLocation};
|
||||||
|
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||||
|
|
||||||
|
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||||
|
File file = new File(fileLocation);
|
||||||
|
String fileContent = IOUtils.toString(new FileInputStream(file), StandardCharsets.UTF_8);
|
||||||
|
assertTrue(fileContent.contains("Donald, Smith"));
|
||||||
|
assertTrue(fileContent.contains(String.valueOf(item.getID())));
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
itemService.delete(context, itemService.find(context, item.getID()));
|
||||||
|
collectionService.delete(context, collectionService.find(context, collection.getID()));
|
||||||
|
communityService.delete(context, communityService.find(context, community.getID()));
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.bulkedit;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.AbstractIntegrationTest;
|
||||||
|
import org.dspace.app.launcher.ScriptLauncher;
|
||||||
|
import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MetadataImportTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();
|
||||||
|
private CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||||
|
private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metadataImportTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Community community = communityService.create(null, context);
|
||||||
|
Collection collection = collectionService.create(context, community);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String fileLocation = new File(testProps.get("test.importcsv").toString()).getAbsolutePath();
|
||||||
|
String[] args = new String[] {"metadata-import", "-f", fileLocation, "-e", eperson.getEmail(), "-s"};
|
||||||
|
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||||
|
|
||||||
|
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||||
|
Item importedItem = itemService.findAll(context).next();
|
||||||
|
assertTrue(
|
||||||
|
StringUtils.equals(
|
||||||
|
itemService.getMetadata(importedItem, "dc", "contributor", "author", Item.ANY).get(0).getValue(),
|
||||||
|
"Donald, SmithImported"));
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
itemService.delete(context, itemService.find(context, importedItem.getID()));
|
||||||
|
collectionService.delete(context, collectionService.find(context, collection.getID()));
|
||||||
|
communityService.delete(context, communityService.find(context, community.getID()));
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.scripts.handler.impl;
|
||||||
|
|
||||||
|
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will be used as a DSpaceRunnableHandler for the Tests so that we can stop the handler
|
||||||
|
* from calling System.exit() when a script would throw an exception
|
||||||
|
*/
|
||||||
|
public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler {
|
||||||
|
|
||||||
|
private Exception exception = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We're overriding this method so that we can stop the script from doing the System.exit() if
|
||||||
|
* an exception within the script is thrown
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void handleException(String message, Exception e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the exception
|
||||||
|
* @return the exception value of this TestDSpaceRunnableHandler
|
||||||
|
*/
|
||||||
|
public Exception getException() {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* 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.license;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock implementation for the Creative commons license connector service.
|
||||||
|
* This class will return a structure of CC Licenses similar to the CC License API but without having to contact it
|
||||||
|
*/
|
||||||
|
public class MockCCLicenseConnectorServiceImpl extends CCLicenseConnectorServiceImpl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves mock CC Licenses for the provided language
|
||||||
|
* @param language - the language
|
||||||
|
* @return a map of mocked licenses with the id and the license
|
||||||
|
*/
|
||||||
|
public Map<String, CCLicense> retrieveLicenses(String language) {
|
||||||
|
Map<String, CCLicense> ccLicenses = new HashMap<>();
|
||||||
|
CCLicense mockLicense1 = createMockLicense(1, new int[]{3, 2, 3});
|
||||||
|
CCLicense mockLicense2 = createMockLicense(2, new int[]{2});
|
||||||
|
CCLicense mockLicense3 = createMockLicense(3, new int[]{});
|
||||||
|
|
||||||
|
ccLicenses.put(mockLicense1.getLicenseId(), mockLicense1);
|
||||||
|
ccLicenses.put(mockLicense2.getLicenseId(), mockLicense2);
|
||||||
|
ccLicenses.put(mockLicense3.getLicenseId(), mockLicense3);
|
||||||
|
|
||||||
|
return ccLicenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CCLicense createMockLicense(int count, int[] amountOfFieldsAndEnums) {
|
||||||
|
String licenseId = "license" + count;
|
||||||
|
String licenseName = "License " + count + " - Name";
|
||||||
|
List<CCLicenseField> mockLicenseFields = createMockLicenseFields(count, amountOfFieldsAndEnums);
|
||||||
|
return new CCLicense(licenseId, licenseName, mockLicenseFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CCLicenseField> createMockLicenseFields(int count, int[] amountOfFieldsAndEnums) {
|
||||||
|
List<CCLicenseField> ccLicenseFields = new LinkedList<>();
|
||||||
|
for (int index = 0; index < amountOfFieldsAndEnums.length; index++) {
|
||||||
|
String licenseFieldId = "license" + count + "-field" + index;
|
||||||
|
String licenseFieldLabel = "License " + count + " - Field " + index + " - Label";
|
||||||
|
String licenseFieldDescription = "License " + count + " - Field " + index + " - Description";
|
||||||
|
List<CCLicenseFieldEnum> mockLicenseFields = createMockLicenseFields(count,
|
||||||
|
index,
|
||||||
|
amountOfFieldsAndEnums[index]);
|
||||||
|
ccLicenseFields.add(new CCLicenseField(licenseFieldId,
|
||||||
|
licenseFieldLabel,
|
||||||
|
licenseFieldDescription,
|
||||||
|
mockLicenseFields));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ccLicenseFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CCLicenseFieldEnum> createMockLicenseFields(int count, int index, int amountOfEnums) {
|
||||||
|
List<CCLicenseFieldEnum> ccLicenseFieldEnumList = new LinkedList<>();
|
||||||
|
for (int i = 0; i < amountOfEnums; i++) {
|
||||||
|
String enumId = "license" + count + "-field" + index + "-enum" + i;
|
||||||
|
String enumLabel = "License " + count + " - Field " + index + " - Enum " + i + " - Label";
|
||||||
|
String enumDescription = "License " + count + " - Field " + index + " - Enum " + i + " - " +
|
||||||
|
"Description";
|
||||||
|
ccLicenseFieldEnumList.add(new CCLicenseFieldEnum(enumId, enumLabel, enumDescription));
|
||||||
|
}
|
||||||
|
return ccLicenseFieldEnumList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a mock CC License URI
|
||||||
|
*
|
||||||
|
* @param licenseId - the ID of the license
|
||||||
|
* @param language - the language for which to retrieve the full answerMap
|
||||||
|
* @param answerMap - the answers to the different field questions
|
||||||
|
* @return the CC License URI
|
||||||
|
*/
|
||||||
|
public String retrieveRightsByQuestion(final String licenseId,
|
||||||
|
final String language,
|
||||||
|
final Map<String, String> answerMap) {
|
||||||
|
|
||||||
|
return "mock-license-uri";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a mock license RDF document.
|
||||||
|
* When the uri contains "invalid", null will be returned to simulate that no document was found for the provided
|
||||||
|
* URI
|
||||||
|
*
|
||||||
|
* @param licenseURI - The license URI for which to retrieve the license RDF document
|
||||||
|
* @return a mock license RDF document or null when the URI contains invalid
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
|
||||||
|
if (!StringUtils.contains(licenseURI, "invalid")) {
|
||||||
|
InputStream cclicense = null;
|
||||||
|
try {
|
||||||
|
cclicense = getClass().getResourceAsStream("cc-license-rdf.xml");
|
||||||
|
|
||||||
|
Document doc = parser.build(cclicense);
|
||||||
|
return doc;
|
||||||
|
} catch (JDOMException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (cclicense != null) {
|
||||||
|
cclicense.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.scripts;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
import org.dspace.scripts.impl.MockDSpaceRunnableScript;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
public class MockDSpaceRunnableScriptConfiguration<T extends MockDSpaceRunnableScript> extends ScriptConfiguration<T> {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
private Class<T> dspaceRunnableClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getDspaceRunnableClass() {
|
||||||
|
return dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the dspaceRunnableClass
|
||||||
|
* @param dspaceRunnableClass The dspaceRunnableClass to be set on this MetadataExportScriptConfiguration
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||||
|
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowedToExecute(Context context) {
|
||||||
|
try {
|
||||||
|
return authorizeService.isAdmin(context);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getOptions() {
|
||||||
|
if (options == null) {
|
||||||
|
Options options = new Options();
|
||||||
|
|
||||||
|
options.addOption("r", "remove", true, "description r");
|
||||||
|
options.getOption("r").setType(String.class);
|
||||||
|
options.addOption("i", "index", false, "description i");
|
||||||
|
options.getOption("i").setType(boolean.class);
|
||||||
|
options.getOption("i").setRequired(true);
|
||||||
|
options.addOption("f", "file", true, "source file");
|
||||||
|
options.getOption("f").setType(InputStream.class);
|
||||||
|
options.getOption("f").setRequired(false);
|
||||||
|
super.options = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,19 +7,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.scripts.impl;
|
package org.dspace.scripts.impl;
|
||||||
|
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.scripts.MockDSpaceRunnableScriptConfiguration;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
public class MockDSpaceRunnableScript extends DSpaceRunnable {
|
public class MockDSpaceRunnableScript extends DSpaceRunnable<MockDSpaceRunnableScriptConfiguration> {
|
||||||
|
@Override
|
||||||
private MockDSpaceRunnableScript() {
|
public void internalRun() throws Exception {
|
||||||
Options options = constructOptions();
|
|
||||||
this.options = options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void internalRun() throws Exception {
|
public MockDSpaceRunnableScriptConfiguration getScriptConfiguration() {
|
||||||
|
return new DSpace().getServiceManager()
|
||||||
|
.getServiceByName("mock-script", MockDSpaceRunnableScriptConfiguration.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -28,15 +29,4 @@ public class MockDSpaceRunnableScript extends DSpaceRunnable {
|
|||||||
throw new ParseException("-i is a mandatory parameter");
|
throw new ParseException("-i is a mandatory parameter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Options constructOptions() {
|
|
||||||
Options options = new Options();
|
|
||||||
|
|
||||||
options.addOption("r", "remove", true, "description r");
|
|
||||||
options.getOption("r").setType(String.class);
|
|
||||||
options.addOption("i", "index", true, "description i");
|
|
||||||
options.getOption("i").setType(boolean.class);
|
|
||||||
options.getOption("i").setRequired(true);
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -11,3 +11,5 @@ test.folder = ./target/testing/
|
|||||||
|
|
||||||
# Path of the test bitstream (to use in BitstreamTest and elsewhere)
|
# Path of the test bitstream (to use in BitstreamTest and elsewhere)
|
||||||
test.bitstream = ./target/testing/dspace/assetstore/ConstitutionofIreland.pdf
|
test.bitstream = ./target/testing/dspace/assetstore/ConstitutionofIreland.pdf
|
||||||
|
test.exportcsv = ./target/testing/dspace/assetstore/test.csv
|
||||||
|
test.importcsv = ./target/testing/dspace/assetstore/testImport.csv
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
<!-- This is the path to the root [dspace-src] directory. -->
|
||||||
<root.basedir>${basedir}/..</root.basedir>
|
<root.basedir>${basedir}/..</root.basedir>
|
||||||
<spring-security.version>5.3.1.RELEASE</spring-security.version>
|
<spring-security.version>5.3.3.RELEASE</spring-security.version>
|
||||||
</properties>
|
</properties>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@@ -172,6 +172,21 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- Verify OS license headers for all source code files -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.mycila</groupId>
|
||||||
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/src/test/resources/**</exclude>
|
||||||
|
<exclude>**/src/test/data/**</exclude>
|
||||||
|
<!--Skip license check of third party files included/customized from HAL Browser -->
|
||||||
|
<exclude>src/main/webapp/index.html</exclude>
|
||||||
|
<exclude>src/main/webapp/login.html</exclude>
|
||||||
|
<exclude>src/main/webapp/js/hal/**</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@@ -242,6 +257,23 @@
|
|||||||
<version>${spring-hal-browser.version}</version>
|
<version>${spring-hal-browser.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- WebJars dependencies used to update/enhance the default HAL Browser -->
|
||||||
|
<!-- Pull in current version of JQuery via WebJars
|
||||||
|
Made available at: webjars/jquery/dist/jquery.min.js -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars.bowergithub.jquery</groupId>
|
||||||
|
<artifactId>jquery-dist</artifactId>
|
||||||
|
<version>3.5.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Pull in current version of Toastr (toastrjs.com) via WebJars
|
||||||
|
Made available at: webjars/toastr/build/toastr.min.js -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars.bowergithub.codeseven</groupId>
|
||||||
|
<artifactId>toastr</artifactId>
|
||||||
|
<version>2.1.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Add in Spring Security for AuthN and AuthZ -->
|
<!-- Add in Spring Security for AuthN and AuthZ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@@ -32,6 +32,7 @@ import org.springframework.web.context.request.RequestContextListener;
|
|||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,6 +150,18 @@ public class Application extends SpringBootServletInitializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new ResourceHandler to allow us to use WebJars.org to pull in web dependencies
|
||||||
|
* dynamically for HAL Browser, and access them off the /webjars path.
|
||||||
|
* @param registry ResourceHandlerRegistry
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry
|
||||||
|
.addResourceHandler("/webjars/**")
|
||||||
|
.addResourceLocations("/webjars/");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArgumentResolvers(@NonNull List<HandlerMethodArgumentResolver> argumentResolvers) {
|
public void addArgumentResolvers(@NonNull List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
argumentResolvers.add(new SearchFilterResolver());
|
argumentResolvers.add(new SearchFilterResolver());
|
||||||
|
@@ -81,7 +81,7 @@ public class RelationshipTypeRestController {
|
|||||||
List<RelationshipType> list = relationshipTypeService.findByEntityType(context, entityType, -1, -1);
|
List<RelationshipType> list = relationshipTypeService.findByEntityType(context, entityType, -1, -1);
|
||||||
|
|
||||||
Page<RelationshipTypeRest> relationshipTypeRestPage = converter
|
Page<RelationshipTypeRest> relationshipTypeRestPage = converter
|
||||||
.toRestPage(list, pageable, list.size(), utils.obtainProjection());
|
.toRestPage(list, pageable, utils.obtainProjection());
|
||||||
|
|
||||||
Page<RelationshipTypeResource> relationshipTypeResources = relationshipTypeRestPage
|
Page<RelationshipTypeResource> relationshipTypeResources = relationshipTypeRestPage
|
||||||
.map(relationshipTypeRest -> new RelationshipTypeResource(relationshipTypeRest, utils));
|
.map(relationshipTypeRest -> new RelationshipTypeResource(relationshipTypeRest, utils));
|
||||||
|
@@ -342,7 +342,15 @@ public class RestResourceController implements InitializingBean {
|
|||||||
return findRelEntryInternal(request, response, apiCategory, model, id, rel, relid, page, assembler);
|
return findRelEntryInternal(request, response, apiCategory, model, id, rel, relid, page, assembler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT +
|
||||||
|
"/{rel}/{relid}")
|
||||||
|
public RepresentationModel findRel(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
@PathVariable String apiCategory,
|
||||||
|
@PathVariable String model, @PathVariable Integer id, @PathVariable String rel,
|
||||||
|
@PathVariable String relid,
|
||||||
|
Pageable page, PagedResourcesAssembler assembler) throws Throwable {
|
||||||
|
return findRelEntryInternal(request, response, apiCategory, model, id.toString(), rel, relid, page, assembler);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Execute a POST request;
|
* Execute a POST request;
|
||||||
*
|
*
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest;
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.converter.ConverterService;
|
import org.dspace.app.rest.converter.ConverterService;
|
||||||
@@ -14,6 +16,9 @@ import org.dspace.app.rest.model.ProcessRest;
|
|||||||
import org.dspace.app.rest.model.ScriptRest;
|
import org.dspace.app.rest.model.ScriptRest;
|
||||||
import org.dspace.app.rest.model.hateoas.ProcessResource;
|
import org.dspace.app.rest.model.hateoas.ProcessResource;
|
||||||
import org.dspace.app.rest.repository.ScriptRestRepository;
|
import org.dspace.app.rest.repository.ScriptRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.rest.webmvc.ControllerUtils;
|
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||||
import org.springframework.hateoas.RepresentationModel;
|
import org.springframework.hateoas.RepresentationModel;
|
||||||
@@ -24,7 +29,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This controller adds additional subresource methods to allow connecting scripts with processes
|
* This controller adds additional subresource methods to allow connecting scripts with processes
|
||||||
@@ -41,6 +48,9 @@ public class ScriptProcessesController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ScriptRestRepository scriptRestRepository;
|
private ScriptRestRepository scriptRestRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method can be called by sending a POST request to the system/scripts/{name}/processes endpoint
|
* This method can be called by sending a POST request to the system/scripts/{name}/processes endpoint
|
||||||
* This will start a process for the script that matches the given name
|
* This will start a process for the script that matches the given name
|
||||||
@@ -50,13 +60,16 @@ public class ScriptProcessesController {
|
|||||||
*/
|
*/
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
public ResponseEntity<RepresentationModel<?>> startProcess(@PathVariable(name = "name") String scriptName)
|
public ResponseEntity<RepresentationModel<?>> startProcess(@PathVariable(name = "name") String scriptName,
|
||||||
|
@RequestParam(name = "file") List<MultipartFile> files)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("Starting Process for Script with name: " + scriptName);
|
log.trace("Starting Process for Script with name: " + scriptName);
|
||||||
}
|
}
|
||||||
ProcessRest processRest = scriptRestRepository.startProcess(scriptName);
|
Context context = ContextUtil.obtainContext(requestService.getCurrentRequest().getServletRequest());
|
||||||
|
ProcessRest processRest = scriptRestRepository.startProcess(context, scriptName, files);
|
||||||
ProcessResource processResource = converter.toResource(processRest);
|
ProcessResource processResource = converter.toResource(processRest);
|
||||||
|
context.complete();
|
||||||
return ControllerUtils.toResponseEntity(HttpStatus.ACCEPTED, new HttpHeaders(), processResource);
|
return ControllerUtils.toResponseEntity(HttpStatus.ACCEPTED, new HttpHeaders(), processResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.app.rest.converter.ConverterService;
|
||||||
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseUrlRest;
|
||||||
|
import org.dspace.app.rest.model.wrapper.SubmissionCCLicenseUrl;
|
||||||
|
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.license.service.CreativeCommonsService;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Repository is responsible for handling the CC License URIs.
|
||||||
|
* It only supports a search method
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component(SubmissionCCLicenseUrlRest.CATEGORY + "." + SubmissionCCLicenseUrlRest.NAME)
|
||||||
|
public class SubmissionCCLicenseUrlRepository extends DSpaceRestRepository<SubmissionCCLicenseUrlRest, String>
|
||||||
|
implements InitializingBean {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected Utils utils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected CreativeCommonsService creativeCommonsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected ConverterService converter;
|
||||||
|
|
||||||
|
protected RequestService requestService = new DSpace().getRequestService();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DiscoverableEndpointsService discoverableEndpointsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the CC License URI based on the license ID and answers in the field questions, provided as parameters
|
||||||
|
* to this request
|
||||||
|
*
|
||||||
|
* @return the CC License URI as a SubmissionCCLicenseUrlRest
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
|
@SearchRestMethod(name = "rightsByQuestions")
|
||||||
|
public SubmissionCCLicenseUrlRest findByRightsByQuestions() {
|
||||||
|
ServletRequest servletRequest = requestService.getCurrentRequest()
|
||||||
|
.getServletRequest();
|
||||||
|
Map<String, String[]> requestParameterMap = servletRequest
|
||||||
|
.getParameterMap();
|
||||||
|
Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
String licenseId = servletRequest.getParameter("license");
|
||||||
|
if (StringUtils.isBlank(licenseId)) {
|
||||||
|
throw new DSpaceBadRequestException(
|
||||||
|
"A \"license\" parameter needs to be provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through parameters to find answer parameters, adding them to the parameterMap. Zero or more answers
|
||||||
|
// may exist, as some CC licenses do not require answers
|
||||||
|
for (String parameter : requestParameterMap.keySet()) {
|
||||||
|
if (StringUtils.startsWith(parameter, "answer_")) {
|
||||||
|
String field = StringUtils.substringAfter(parameter, "answer_");
|
||||||
|
String answer = "";
|
||||||
|
if (requestParameterMap.get(parameter).length > 0) {
|
||||||
|
answer = requestParameterMap.get(parameter)[0];
|
||||||
|
}
|
||||||
|
parameterMap.put(field, answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> fullParamMap = creativeCommonsService.retrieveFullAnswerMap(licenseId, parameterMap);
|
||||||
|
if (fullParamMap == null) {
|
||||||
|
throw new ResourceNotFoundException("No CC License could be matched on the provided ID: " + licenseId);
|
||||||
|
}
|
||||||
|
boolean licenseContainsCorrectInfo = creativeCommonsService.verifyLicenseInformation(licenseId, fullParamMap);
|
||||||
|
if (!licenseContainsCorrectInfo) {
|
||||||
|
throw new DSpaceBadRequestException(
|
||||||
|
"The provided answers do not match the required fields for the provided license.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String licenseUri = creativeCommonsService.retrieveLicenseUri(licenseId, fullParamMap);
|
||||||
|
|
||||||
|
SubmissionCCLicenseUrl submissionCCLicenseUrl = new SubmissionCCLicenseUrl(licenseUri, licenseUri);
|
||||||
|
if (StringUtils.isBlank(licenseUri)) {
|
||||||
|
throw new ResourceNotFoundException("No CC License URI could be found for ID: " + licenseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return converter.toRest(submissionCCLicenseUrl, utils.obtainProjection());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The findOne method is not supported in this repository
|
||||||
|
*/
|
||||||
|
@PreAuthorize("permitAll()")
|
||||||
|
public SubmissionCCLicenseUrlRest findOne(final Context context, final String s) {
|
||||||
|
throw new RepositoryMethodNotImplementedException(SubmissionCCLicenseUrlRest.NAME, "findOne");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The findAll method is not supported in this repository
|
||||||
|
*/
|
||||||
|
public Page<SubmissionCCLicenseUrlRest> findAll(final Context context, final Pageable pageable) {
|
||||||
|
throw new RepositoryMethodNotImplementedException(SubmissionCCLicenseUrlRest.NAME, "findAll");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<SubmissionCCLicenseUrlRest> getDomainClass() {
|
||||||
|
return SubmissionCCLicenseUrlRest.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
discoverableEndpointsService.register(this, Arrays.asList(
|
||||||
|
new Link("/api/" + SubmissionCCLicenseUrlRest.CATEGORY + "/" +
|
||||||
|
SubmissionCCLicenseUrlRest.NAME + "/search",
|
||||||
|
SubmissionCCLicenseUrlRest.NAME + "-search")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -72,7 +72,7 @@ public class WorkflowDefinitionCollectionsLinkRepository extends AbstractDSpaceR
|
|||||||
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context,
|
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context,
|
||||||
workflowName));
|
workflowName));
|
||||||
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
||||||
return converter.toRestPage(utils.getPage(collectionsMappedToWorkflow, pageable),
|
return converter.toRestPage(collectionsMappedToWorkflow, pageable,
|
||||||
projection);
|
projection);
|
||||||
} else {
|
} else {
|
||||||
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
|
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
|
||||||
|
@@ -55,7 +55,7 @@ public class WorkflowDefinitionStepsLinkRepository extends AbstractDSpaceRestRep
|
|||||||
try {
|
try {
|
||||||
List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps();
|
List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps();
|
||||||
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
||||||
return converter.toRestPage(utils.getPage(steps, pageable), projection);
|
return converter.toRestPage(steps, pageable, projection);
|
||||||
} catch (WorkflowConfigurationException e) {
|
} catch (WorkflowConfigurationException e) {
|
||||||
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
|
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,6 @@ public class WorkflowStepActionsLinkRepository extends AbstractDSpaceRestReposit
|
|||||||
Projection projection) {
|
Projection projection) {
|
||||||
List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions();
|
List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions();
|
||||||
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
|
||||||
return converter.toRestPage(utils.getPage(actions, pageable), projection);
|
return converter.toRestPage(actions, pageable, projection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,33 +7,44 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest.converter;
|
package org.dspace.app.rest.converter;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.app.rest.link.HalLinkFactory;
|
import org.dspace.app.rest.link.HalLinkFactory;
|
||||||
import org.dspace.app.rest.link.HalLinkService;
|
import org.dspace.app.rest.link.HalLinkService;
|
||||||
|
import org.dspace.app.rest.model.BaseObjectRest;
|
||||||
import org.dspace.app.rest.model.RestAddressableModel;
|
import org.dspace.app.rest.model.RestAddressableModel;
|
||||||
import org.dspace.app.rest.model.RestModel;
|
import org.dspace.app.rest.model.RestModel;
|
||||||
import org.dspace.app.rest.model.hateoas.HALResource;
|
import org.dspace.app.rest.model.hateoas.HALResource;
|
||||||
import org.dspace.app.rest.projection.DefaultProjection;
|
import org.dspace.app.rest.projection.DefaultProjection;
|
||||||
import org.dspace.app.rest.projection.Projection;
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
||||||
|
import org.dspace.app.rest.security.DSpacePermissionEvaluator;
|
||||||
|
import org.dspace.app.rest.security.WebSecurityExpressionEvaluator;
|
||||||
import org.dspace.app.rest.utils.Utils;
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.hateoas.EntityModel;
|
import org.springframework.hateoas.EntityModel;
|
||||||
import org.springframework.hateoas.Link;
|
import org.springframework.hateoas.Link;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -64,6 +75,15 @@ public class ConverterService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private List<Projection> projections;
|
private List<Projection> projections;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSpacePermissionEvaluator dSpacePermissionEvaluator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebSecurityExpressionEvaluator webSecurityExpressionEvaluator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter} and
|
* Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter} and
|
||||||
* the given projection.
|
* the given projection.
|
||||||
@@ -86,18 +106,74 @@ public class ConverterService {
|
|||||||
M transformedModel = projection.transformModel(modelObject);
|
M transformedModel = projection.transformModel(modelObject);
|
||||||
DSpaceConverter<M, R> converter = requireConverter(modelObject.getClass());
|
DSpaceConverter<M, R> converter = requireConverter(modelObject.getClass());
|
||||||
R restObject = converter.convert(transformedModel, projection);
|
R restObject = converter.convert(transformedModel, projection);
|
||||||
|
if (restObject instanceof BaseObjectRest) {
|
||||||
|
BaseObjectRest baseObjectRest = (BaseObjectRest) restObject;
|
||||||
|
// This section will verify whether the current user has permissions to retrieve the
|
||||||
|
// rest object. It'll only return the REST object if the permission is granted.
|
||||||
|
// If permission isn't granted, it'll return null
|
||||||
|
String preAuthorizeValue = getPreAuthorizeAnnotationForBaseObject(baseObjectRest);
|
||||||
|
if (!webSecurityExpressionEvaluator
|
||||||
|
.evaluate(preAuthorizeValue, requestService.getCurrentRequest().getHttpServletRequest(),
|
||||||
|
requestService.getCurrentRequest().getHttpServletResponse(),
|
||||||
|
String.valueOf(baseObjectRest.getId()))) {
|
||||||
|
log.debug("Access denied on " + restObject.getClass() + " with id: " +
|
||||||
|
((BaseObjectRest) restObject).getId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (restObject instanceof RestModel) {
|
if (restObject instanceof RestModel) {
|
||||||
return (R) projection.transformRest((RestModel) restObject);
|
return (R) projection.transformRest((RestModel) restObject);
|
||||||
}
|
}
|
||||||
return restObject;
|
return restObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getPreAuthorizeAnnotationForBaseObject(BaseObjectRest restObject) {
|
||||||
|
Annotation preAuthorize = getAnnotationForRestObject(restObject);
|
||||||
|
if (preAuthorize == null) {
|
||||||
|
preAuthorize = getDefaultFindOnePreAuthorize();
|
||||||
|
|
||||||
|
}
|
||||||
|
return parseAnnotation(preAuthorize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseAnnotation(Annotation preAuthorize) {
|
||||||
|
if (preAuthorize != null) {
|
||||||
|
return (String) AnnotationUtils.getValue(preAuthorize);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation getAnnotationForRestObject(BaseObjectRest restObject) {
|
||||||
|
BaseObjectRest baseObjectRest = restObject;
|
||||||
|
DSpaceRestRepository repositoryToUse = utils
|
||||||
|
.getResourceRepositoryByCategoryAndModel(baseObjectRest.getCategory(), baseObjectRest.getType());
|
||||||
|
Annotation preAuthorize = null;
|
||||||
|
for (Method m : repositoryToUse.getClass().getMethods()) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(m.getName(), "findOne")) {
|
||||||
|
preAuthorize = AnnotationUtils.findAnnotation(m, PreAuthorize.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return preAuthorize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation getDefaultFindOnePreAuthorize() {
|
||||||
|
for (Method m : DSpaceRestRepository.class.getMethods()) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(m.getName(), "findOne")) {
|
||||||
|
Annotation annotation = AnnotationUtils.findAnnotation(m, PreAuthorize.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
return annotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a list of model objects to a page of rest objects using the given {@link Projection}.
|
* Converts a list of model objects to a page of rest objects using the given {@link Projection}.
|
||||||
*
|
*
|
||||||
* @param modelObjects the list of model objects.
|
* @param modelObjects the list of model objects.
|
||||||
* @param pageable the pageable.
|
* @param pageable the pageable.
|
||||||
* @param total the total number of items.
|
|
||||||
* @param projection the projection to use.
|
* @param projection the projection to use.
|
||||||
* @param <M> the model object class.
|
* @param <M> the model object class.
|
||||||
* @param <R> the rest object class.
|
* @param <R> the rest object class.
|
||||||
@@ -105,25 +181,48 @@ public class ConverterService {
|
|||||||
* @throws IllegalArgumentException if there is no compatible converter.
|
* @throws IllegalArgumentException if there is no compatible converter.
|
||||||
* @throws ClassCastException if the converter's return type is not compatible with the inferred return type.
|
* @throws ClassCastException if the converter's return type is not compatible with the inferred return type.
|
||||||
*/
|
*/
|
||||||
public <M, R> Page<R> toRestPage(List<M> modelObjects, Pageable pageable, long total, Projection projection) {
|
public <M, R> Page<R> toRestPage(List<M> modelObjects, Pageable pageable, Projection projection) {
|
||||||
return new PageImpl<>(modelObjects, pageable, total).map((object) -> toRest(object, projection));
|
List<R> transformedList = new LinkedList<>();
|
||||||
|
for (M modelObject : modelObjects) {
|
||||||
|
R transformedObject = toRest(modelObject, projection);
|
||||||
|
if (transformedObject != null) {
|
||||||
|
transformedList.add(transformedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageable == null) {
|
||||||
|
pageable = utils.getPageable(pageable);
|
||||||
|
}
|
||||||
|
return utils.getPage(transformedList, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a list of model objects to a page of rest objects using the given {@link Projection}.
|
* Converts a list of ModelObjects to a page of Rest Objects using the given {@link Projection}
|
||||||
*
|
* This method differences in the sense that we define a total here instead of the size of the list because
|
||||||
* @param modelObjects the page of model objects.
|
* this method will be called if the list is limited through a DB call already and thus we need to give the
|
||||||
|
* total amount of records in the DB; not the size of the given list
|
||||||
|
* @param modelObjects the list of model objects.
|
||||||
|
* @param pageable the pageable.
|
||||||
|
* @param total The total amount of objects
|
||||||
* @param projection the projection to use.
|
* @param projection the projection to use.
|
||||||
* @param <M> the model object class.
|
* @param <M> the model object class.
|
||||||
* @param <R> the rest object class.
|
* @param <R> the rest object class.
|
||||||
* @return the page.
|
* @return the page.
|
||||||
* @throws IllegalArgumentException if there is no compatible converter.
|
|
||||||
* @throws ClassCastException if the converter's return type is not compatible with the inferred return type.
|
|
||||||
*/
|
*/
|
||||||
public <M, R> Page<R> toRestPage(Page<M> modelObjects, Projection projection) {
|
public <M, R> Page<R> toRestPage(List<M> modelObjects, Pageable pageable, long total, Projection projection) {
|
||||||
return modelObjects.map((object) -> toRest(object, projection));
|
List<R> transformedList = new LinkedList<>();
|
||||||
|
for (M modelObject : modelObjects) {
|
||||||
|
R transformedObject = toRest(modelObject, projection);
|
||||||
|
if (transformedObject != null) {
|
||||||
|
transformedList.add(transformedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageable == null) {
|
||||||
|
pageable = utils.getPageable(pageable);
|
||||||
|
}
|
||||||
|
return new PageImpl(transformedList, pageable, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the converter supporting the given class as input.
|
* Gets the converter supporting the given class as input.
|
||||||
*
|
*
|
||||||
@@ -177,6 +276,9 @@ public class ConverterService {
|
|||||||
* @return the fully converted resource, with all automatic links and embeds applied.
|
* @return the fully converted resource, with all automatic links and embeds applied.
|
||||||
*/
|
*/
|
||||||
public <T extends HALResource> T toResource(RestModel restObject, Link... oldLinks) {
|
public <T extends HALResource> T toResource(RestModel restObject, Link... oldLinks) {
|
||||||
|
if (restObject == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
T halResource = getResource(restObject);
|
T halResource = getResource(restObject);
|
||||||
if (restObject instanceof RestAddressableModel) {
|
if (restObject instanceof RestAddressableModel) {
|
||||||
utils.embedOrLinkClassLevelRels(halResource, oldLinks);
|
utils.embedOrLinkClassLevelRels(halResource, oldLinks);
|
||||||
@@ -288,19 +390,19 @@ public class ConverterService {
|
|||||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||||
provider.addIncludeFilter(new AssignableTypeFilter(EntityModel.class));
|
provider.addIncludeFilter(new AssignableTypeFilter(EntityModel.class));
|
||||||
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(
|
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(
|
||||||
HALResource.class.getPackage().getName().replaceAll("\\.", "/"));
|
HALResource.class.getPackage().getName().replaceAll("\\.", "/"));
|
||||||
for (BeanDefinition beanDefinition : beanDefinitions) {
|
for (BeanDefinition beanDefinition : beanDefinitions) {
|
||||||
String resourceClassName = beanDefinition.getBeanClassName();
|
String resourceClassName = beanDefinition.getBeanClassName();
|
||||||
String resourceClassSimpleName = resourceClassName.substring(resourceClassName.lastIndexOf(".") + 1);
|
String resourceClassSimpleName = resourceClassName.substring(resourceClassName.lastIndexOf(".") + 1);
|
||||||
String restClassSimpleName = resourceClassSimpleName
|
String restClassSimpleName = resourceClassSimpleName
|
||||||
.replaceAll("ResourceWrapper$", "RestWrapper")
|
.replaceAll("ResourceWrapper$", "RestWrapper")
|
||||||
.replaceAll("Resource$", "Rest");
|
.replaceAll("Resource$", "Rest");
|
||||||
String restClassName = RestModel.class.getPackage().getName() + "." + restClassSimpleName;
|
String restClassName = RestModel.class.getPackage().getName() + "." + restClassSimpleName;
|
||||||
try {
|
try {
|
||||||
Class<? extends RestModel> restClass =
|
Class<? extends RestModel> restClass =
|
||||||
(Class<? extends RestModel>) Class.forName(restClassName);
|
(Class<? extends RestModel>) Class.forName(restClassName);
|
||||||
Class<HALResource<? extends RestModel>> resourceClass =
|
Class<HALResource<? extends RestModel>> resourceClass =
|
||||||
(Class<HALResource<? extends RestModel>>) Class.forName(resourceClassName);
|
(Class<HALResource<? extends RestModel>>) Class.forName(resourceClassName);
|
||||||
Constructor compatibleConstructor = null;
|
Constructor compatibleConstructor = null;
|
||||||
for (Constructor constructor : resourceClass.getDeclaredConstructors()) {
|
for (Constructor constructor : resourceClass.getDeclaredConstructors()) {
|
||||||
if (constructor.getParameterCount() == 2 && constructor.getParameterTypes()[1] == Utils.class) {
|
if (constructor.getParameterCount() == 2 && constructor.getParameterTypes()[1] == Utils.class) {
|
||||||
@@ -314,11 +416,11 @@ public class ConverterService {
|
|||||||
resourceConstructors.put(restClass, compatibleConstructor);
|
resourceConstructors.put(restClass, compatibleConstructor);
|
||||||
} else {
|
} else {
|
||||||
log.warn("Skipping registration of resource class " + resourceClassName
|
log.warn("Skipping registration of resource class " + resourceClassName
|
||||||
+ "; compatible constructor not found");
|
+ "; compatible constructor not found");
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
log.warn("Skipping registration of resource class " + resourceClassName
|
log.warn("Skipping registration of resource class " + resourceClassName
|
||||||
+ "; rest class not found: " + restClassName);
|
+ "; rest class not found: " + restClassName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,8 +24,8 @@ public class RootConverter {
|
|||||||
public RootRest convert() {
|
public RootRest convert() {
|
||||||
RootRest rootRest = new RootRest();
|
RootRest rootRest = new RootRest();
|
||||||
rootRest.setDspaceName(configurationService.getProperty("dspace.name"));
|
rootRest.setDspaceName(configurationService.getProperty("dspace.name"));
|
||||||
rootRest.setDspaceURL(configurationService.getProperty("dspace.ui.url"));
|
rootRest.setDspaceUI(configurationService.getProperty("dspace.ui.url"));
|
||||||
rootRest.setDspaceRest(configurationService.getProperty("dspace.server.url"));
|
rootRest.setDspaceServer(configurationService.getProperty("dspace.server.url"));
|
||||||
return rootRest;
|
return rootRest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||||||
import org.dspace.app.rest.model.ParameterRest;
|
import org.dspace.app.rest.model.ParameterRest;
|
||||||
import org.dspace.app.rest.model.ScriptRest;
|
import org.dspace.app.rest.model.ScriptRest;
|
||||||
import org.dspace.app.rest.projection.Projection;
|
import org.dspace.app.rest.projection.Projection;
|
||||||
import org.dspace.scripts.DSpaceRunnable;
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,18 +23,18 @@ import org.springframework.stereotype.Component;
|
|||||||
* of {@link ScriptRest}
|
* of {@link ScriptRest}
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ScriptConverter implements DSpaceConverter<DSpaceRunnable, ScriptRest> {
|
public class ScriptConverter implements DSpaceConverter<ScriptConfiguration, ScriptRest> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScriptRest convert(DSpaceRunnable script, Projection projection) {
|
public ScriptRest convert(ScriptConfiguration scriptConfiguration, Projection projection) {
|
||||||
ScriptRest scriptRest = new ScriptRest();
|
ScriptRest scriptRest = new ScriptRest();
|
||||||
scriptRest.setProjection(projection);
|
scriptRest.setProjection(projection);
|
||||||
scriptRest.setDescription(script.getDescription());
|
scriptRest.setDescription(scriptConfiguration.getDescription());
|
||||||
scriptRest.setId(script.getName());
|
scriptRest.setId(scriptConfiguration.getName());
|
||||||
scriptRest.setName(script.getName());
|
scriptRest.setName(scriptConfiguration.getName());
|
||||||
|
|
||||||
List<ParameterRest> parameterRestList = new LinkedList<>();
|
List<ParameterRest> parameterRestList = new LinkedList<>();
|
||||||
for (Option option : CollectionUtils.emptyIfNull(script.getOptions().getOptions())) {
|
for (Option option : CollectionUtils.emptyIfNull(scriptConfiguration.getOptions().getOptions())) {
|
||||||
ParameterRest parameterRest = new ParameterRest();
|
ParameterRest parameterRest = new ParameterRest();
|
||||||
parameterRest.setDescription(option.getDescription());
|
parameterRest.setDescription(option.getDescription());
|
||||||
parameterRest.setName((option.getOpt() != null ? "-" + option.getOpt() : "--" + option.getLongOpt()));
|
parameterRest.setName((option.getOpt() != null ? "-" + option.getOpt() : "--" + option.getLongOpt()));
|
||||||
@@ -49,7 +49,7 @@ public class ScriptConverter implements DSpaceConverter<DSpaceRunnable, ScriptRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<DSpaceRunnable> getModelClass() {
|
public Class<ScriptConfiguration> getModelClass() {
|
||||||
return DSpaceRunnable.class;
|
return ScriptConfiguration.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.converter;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseFieldRest;
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.license.CCLicense;
|
||||||
|
import org.dspace.license.CCLicenseField;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This converter is responsible for transforming the model representation of an CCLicense to the REST
|
||||||
|
* representation of an CCLicense and vice versa
|
||||||
|
**/
|
||||||
|
@Component
|
||||||
|
public class SubmissionCCLicenseConverter implements DSpaceConverter<CCLicense, SubmissionCCLicenseRest> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConverterService converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a CCLicense to its REST representation
|
||||||
|
* @param modelObject - the CCLicense to convert
|
||||||
|
* @param projection - the projection
|
||||||
|
* @return the corresponding SubmissionCCLicenseRest object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SubmissionCCLicenseRest convert(final CCLicense modelObject, final Projection projection) {
|
||||||
|
SubmissionCCLicenseRest submissionCCLicenseRest = new SubmissionCCLicenseRest();
|
||||||
|
submissionCCLicenseRest.setProjection(projection);
|
||||||
|
submissionCCLicenseRest.setId(modelObject.getLicenseId());
|
||||||
|
submissionCCLicenseRest.setName(modelObject.getLicenseName());
|
||||||
|
|
||||||
|
List<CCLicenseField> ccLicenseFieldList = modelObject.getCcLicenseFieldList();
|
||||||
|
List<SubmissionCCLicenseFieldRest> submissionCCLicenseFieldRests = new LinkedList<>();
|
||||||
|
if (ccLicenseFieldList != null) {
|
||||||
|
for (CCLicenseField ccLicenseField : ccLicenseFieldList) {
|
||||||
|
submissionCCLicenseFieldRests.add(converter.toRest(ccLicenseField, projection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
submissionCCLicenseRest.setFields(submissionCCLicenseFieldRests);
|
||||||
|
return submissionCCLicenseRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<CCLicense> getModelClass() {
|
||||||
|
return CCLicense.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.converter;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseFieldEnumRest;
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseFieldRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.license.CCLicenseField;
|
||||||
|
import org.dspace.license.CCLicenseFieldEnum;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This converter is responsible for transforming the model representation of an CCLicenseField to the REST
|
||||||
|
* representation of an CCLicenseField and vice versa
|
||||||
|
* The CCLicenseField is a sub component of the CCLicense object
|
||||||
|
**/
|
||||||
|
@Component
|
||||||
|
public class SubmissionCCLicenseFieldConverter
|
||||||
|
implements DSpaceConverter<CCLicenseField, SubmissionCCLicenseFieldRest> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConverterService converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a CCLicenseField to its REST representation
|
||||||
|
* @param modelObject - the CCLicenseField to convert
|
||||||
|
* @param projection - the projection
|
||||||
|
* @return the corresponding SubmissionCCLicenseFieldRest object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SubmissionCCLicenseFieldRest convert(final CCLicenseField modelObject, final Projection projection) {
|
||||||
|
SubmissionCCLicenseFieldRest submissionCCLicenseFieldRest = new SubmissionCCLicenseFieldRest();
|
||||||
|
submissionCCLicenseFieldRest.setId(modelObject.getId());
|
||||||
|
submissionCCLicenseFieldRest.setLabel(modelObject.getLabel());
|
||||||
|
submissionCCLicenseFieldRest.setDescription(modelObject.getDescription());
|
||||||
|
|
||||||
|
List<CCLicenseFieldEnum> fieldEnum = modelObject.getFieldEnum();
|
||||||
|
List<SubmissionCCLicenseFieldEnumRest> submissionCCLicenseFieldEnumRests = new LinkedList<>();
|
||||||
|
if (fieldEnum != null) {
|
||||||
|
for (CCLicenseFieldEnum ccLicenseFieldEnum : fieldEnum) {
|
||||||
|
submissionCCLicenseFieldEnumRests.add(converter.toRest(ccLicenseFieldEnum, projection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
submissionCCLicenseFieldRest.setEnums(submissionCCLicenseFieldEnumRests);
|
||||||
|
return submissionCCLicenseFieldRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<CCLicenseField> getModelClass() {
|
||||||
|
return CCLicenseField.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.converter;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseFieldEnumRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.license.CCLicenseFieldEnum;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This converter is responsible for transforming the model representation of an CCLicenseFieldEnum to the REST
|
||||||
|
* representation of an CCLicenseFieldEnum and vice versa
|
||||||
|
* The CCLicenseFieldEnum is a sub component of the CCLicenseField object
|
||||||
|
**/
|
||||||
|
@Component
|
||||||
|
public class SubmissionCCLicenseFieldEnumConverter
|
||||||
|
implements DSpaceConverter<CCLicenseFieldEnum, SubmissionCCLicenseFieldEnumRest> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a CCLicenseFieldEnum to its REST representation
|
||||||
|
*
|
||||||
|
* @param modelObject - the CCLicenseField to convert
|
||||||
|
* @param projection - the projection
|
||||||
|
* @return the corresponding SubmissionCCLicenseFieldEnumRest object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SubmissionCCLicenseFieldEnumRest convert(final CCLicenseFieldEnum modelObject, final Projection projection) {
|
||||||
|
SubmissionCCLicenseFieldEnumRest submissionCCLicenseFieldEnumRest = new SubmissionCCLicenseFieldEnumRest();
|
||||||
|
submissionCCLicenseFieldEnumRest.setId(modelObject.getId());
|
||||||
|
submissionCCLicenseFieldEnumRest.setLabel(modelObject.getLabel());
|
||||||
|
submissionCCLicenseFieldEnumRest.setDescription(modelObject.getDescription());
|
||||||
|
|
||||||
|
return submissionCCLicenseFieldEnumRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<CCLicenseFieldEnum> getModelClass() {
|
||||||
|
return CCLicenseFieldEnum.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.converter;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseUrlRest;
|
||||||
|
import org.dspace.app.rest.model.wrapper.SubmissionCCLicenseUrl;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This converter is responsible for transforming a Submission CC License Url String to the REST
|
||||||
|
* representation SubmissionCCLicenseUrlRest and vice versa
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SubmissionCCLicenseUrlConverter
|
||||||
|
implements DSpaceConverter<SubmissionCCLicenseUrl, SubmissionCCLicenseUrlRest> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Submission CC License Url String to its REST representation
|
||||||
|
* @param modelObject - the CC License Url object to convert
|
||||||
|
* @param projection - the projection
|
||||||
|
* @return the corresponding SubmissionCCLicenseUrlRest object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SubmissionCCLicenseUrlRest convert(SubmissionCCLicenseUrl modelObject, Projection projection) {
|
||||||
|
SubmissionCCLicenseUrlRest submissionCCLicenseUrlRest = new SubmissionCCLicenseUrlRest();
|
||||||
|
submissionCCLicenseUrlRest.setUrl(modelObject.getUrl());
|
||||||
|
submissionCCLicenseUrlRest.setId(modelObject.getId());
|
||||||
|
|
||||||
|
return submissionCCLicenseUrlRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<SubmissionCCLicenseUrl> getModelClass() {
|
||||||
|
return SubmissionCCLicenseUrl.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -29,6 +29,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
|
|||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
|
import org.springframework.web.multipart.MultipartException;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,8 +55,8 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(IllegalArgumentException.class)
|
@ExceptionHandler({IllegalArgumentException.class, MultipartException.class})
|
||||||
protected void handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response,
|
protected void handleWrongRequestException(HttpServletRequest request, HttpServletResponse response,
|
||||||
Exception ex) throws IOException {
|
Exception ex) throws IOException {
|
||||||
sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_BAD_REQUEST);
|
sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@ public class RootHalLinkFactory extends HalLinkFactory<RootResource, RootRestRes
|
|||||||
for (Link endpointLink : discoverableEndpointsService.getDiscoverableEndpoints()) {
|
for (Link endpointLink : discoverableEndpointsService.getDiscoverableEndpoints()) {
|
||||||
list.add(
|
list.add(
|
||||||
buildLink(endpointLink.getRel().value(),
|
buildLink(endpointLink.getRel().value(),
|
||||||
halResource.getContent().getDspaceRest() + endpointLink.getHref()));
|
halResource.getContent().getDspaceServer() + endpointLink.getHref()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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.app.rest.link.process;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
import org.dspace.app.rest.link.HalLinkFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This abstract class offers an easily extendable HalLinkFactory class to use methods on the RestResourceController
|
||||||
|
* and make it more easy to read or define which methods should be found in the getMethodOn methods when building links
|
||||||
|
* @param <T> This parameter should be of type {@link org.dspace.app.rest.model.hateoas.HALResource}
|
||||||
|
*/
|
||||||
|
public abstract class ProcessHalLinkFactory<T> extends HalLinkFactory<T, RestResourceController> {
|
||||||
|
}
|
@@ -10,7 +10,6 @@ package org.dspace.app.rest.link.process;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.dspace.app.rest.RestResourceController;
|
import org.dspace.app.rest.RestResourceController;
|
||||||
import org.dspace.app.rest.link.HalLinkFactory;
|
|
||||||
import org.dspace.app.rest.model.hateoas.ProcessResource;
|
import org.dspace.app.rest.model.hateoas.ProcessResource;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -19,25 +18,28 @@ import org.springframework.hateoas.Link;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class will provide the ProcessResource with links
|
* This HalLinkFactory provides the {@link ProcessResource} with links
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ProcessResourceHalLinkFactory extends HalLinkFactory<ProcessResource, RestResourceController> {
|
public class ProcessResourceHalLinkFactory extends ProcessHalLinkFactory<ProcessResource> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConfigurationService configurationService;
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void addLinks(ProcessResource halResource, Pageable pageable, LinkedList<Link> list) throws Exception {
|
protected void addLinks(ProcessResource halResource, Pageable pageable, LinkedList<Link> list) throws Exception {
|
||||||
String dspaceRestUrl = configurationService.getProperty("dspace.server.url");
|
String dspaceServerUrl = configurationService.getProperty("dspace.server.url");
|
||||||
list.add(
|
list.add(
|
||||||
buildLink("script", dspaceRestUrl + "/api/system/scripts/" + halResource.getContent().getScriptName()));
|
buildLink("script", dspaceServerUrl + "/api/system/scripts/" + halResource.getContent().getScriptName()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Class<RestResourceController> getControllerClass() {
|
protected Class<RestResourceController> getControllerClass() {
|
||||||
return RestResourceController.class;
|
return RestResourceController.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Class<ProcessResource> getResourceClass() {
|
protected Class<ProcessResource> getResourceClass() {
|
||||||
return ProcessResource.class;
|
return ProcessResource.class;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.link.process;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
import org.dspace.app.rest.link.HalLinkFactory;
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseUrlRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.SubmissionCCLicenseUrlResource;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will provide the SubmissionCCLicenseUrlResource with links
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SubmissionCCLicenseUrlResourceHalLinkFactory
|
||||||
|
extends HalLinkFactory<SubmissionCCLicenseUrlResource, RestResourceController> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RequestService requestService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a self link based on the search parameters
|
||||||
|
*
|
||||||
|
* @param halResource - The halResource
|
||||||
|
* @param pageable - The page information
|
||||||
|
* @param list - The list of present links
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void addLinks(SubmissionCCLicenseUrlResource halResource, final Pageable pageable,
|
||||||
|
LinkedList<Link> list)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
halResource.removeLinks();
|
||||||
|
Map<String, String[]> parameterMap = requestService.getCurrentRequest().getHttpServletRequest()
|
||||||
|
.getParameterMap();
|
||||||
|
|
||||||
|
|
||||||
|
UriComponentsBuilder uriComponentsBuilder = uriBuilder(getMethodOn().executeSearchMethods(
|
||||||
|
SubmissionCCLicenseUrlRest.CATEGORY, SubmissionCCLicenseUrlRest.PLURAL, "rightsByQuestions", null, null,
|
||||||
|
null, null, new LinkedMultiValueMap<>()));
|
||||||
|
for (String key : parameterMap.keySet()) {
|
||||||
|
uriComponentsBuilder.queryParam(key, parameterMap.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(buildLink("self", uriComponentsBuilder.build().toUriString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<RestResourceController> getControllerClass() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<SubmissionCCLicenseUrlResource> getResourceClass() {
|
||||||
|
return SubmissionCCLicenseUrlResource.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -12,7 +12,7 @@ import org.dspace.app.rest.ExternalSourcesRestController;
|
|||||||
/**
|
/**
|
||||||
* This class serves as a REST representation for an entry of external data
|
* This class serves as a REST representation for an entry of external data
|
||||||
*/
|
*/
|
||||||
public class ExternalSourceEntryRest extends BaseObjectRest<String> {
|
public class ExternalSourceEntryRest extends RestAddressableModel {
|
||||||
|
|
||||||
public static final String NAME = "externalSourceEntry";
|
public static final String NAME = "externalSourceEntry";
|
||||||
public static final String PLURAL_NAME = "externalSourceEntries";
|
public static final String PLURAL_NAME = "externalSourceEntries";
|
||||||
|
@@ -25,16 +25,16 @@ public class ParameterRest {
|
|||||||
*/
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
/**
|
|
||||||
* The long name of the parameter
|
|
||||||
*/
|
|
||||||
private String nameLong;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean indicating whether the parameter is mandatory or not
|
* Boolean indicating whether the parameter is mandatory or not
|
||||||
*/
|
*/
|
||||||
private boolean mandatory;
|
private boolean mandatory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The long name of the parameter
|
||||||
|
*/
|
||||||
|
private String nameLong;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides a way to list the filetypes present in a given Process by showing them as a list of Strings
|
||||||
|
* It'll be used by {@link org.dspace.app.rest.repository.ProcessFileTypesLinkRepository}
|
||||||
|
*/
|
||||||
|
public class ProcessFileTypesRest extends BaseObjectRest<String> {
|
||||||
|
|
||||||
|
public static final String NAME = "filetypes";
|
||||||
|
public static final String PLURAL_NAME = "filetypes";
|
||||||
|
public static final String CATEGORY = RestAddressableModel.SYSTEM;
|
||||||
|
|
||||||
|
private List<String> values;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the values
|
||||||
|
* @return the values value of this ProcessFileTypesRest
|
||||||
|
*/
|
||||||
|
public List<String> getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the values
|
||||||
|
* @param values The values to be set on this ProcessFileTypesRest
|
||||||
|
*/
|
||||||
|
public void setValues(List<String> values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a value to the list of FileType Strings
|
||||||
|
* @param value The value to be added
|
||||||
|
*/
|
||||||
|
public void addValue(String value) {
|
||||||
|
if (values == null) {
|
||||||
|
values = new LinkedList<>();
|
||||||
|
}
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getController() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
@@ -20,12 +20,23 @@ import org.dspace.scripts.Process;
|
|||||||
/**
|
/**
|
||||||
* This class serves as a REST representation for the {@link Process} class
|
* This class serves as a REST representation for the {@link Process} class
|
||||||
*/
|
*/
|
||||||
|
@LinksRest(links = {
|
||||||
|
@LinkRest(
|
||||||
|
name = ProcessRest.FILES,
|
||||||
|
method = "getFilesFromProcess"
|
||||||
|
),
|
||||||
|
@LinkRest(
|
||||||
|
name = ProcessRest.FILE_TYPES,
|
||||||
|
method = "getFileTypesFromProcess"
|
||||||
|
)
|
||||||
|
})
|
||||||
public class ProcessRest extends BaseObjectRest<Integer> {
|
public class ProcessRest extends BaseObjectRest<Integer> {
|
||||||
public static final String NAME = "process";
|
public static final String NAME = "process";
|
||||||
public static final String PLURAL_NAME = "processes";
|
public static final String PLURAL_NAME = "processes";
|
||||||
public static final String CATEGORY = RestAddressableModel.SYSTEM;
|
public static final String CATEGORY = RestAddressableModel.SYSTEM;
|
||||||
|
|
||||||
|
public static final String FILES = "files";
|
||||||
|
public static final String FILE_TYPES = "filetypes";
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
return CATEGORY;
|
return CATEGORY;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class acts as the REST representation of a DSpace configuration property.
|
||||||
|
* This class acts as a data holder for the PropertyResource
|
||||||
|
*/
|
||||||
|
public class PropertyRest extends BaseObjectRest<String> {
|
||||||
|
public static final String NAME = "property";
|
||||||
|
public static final String CATEGORY = RestAddressableModel.CONFIGURATION;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValues(List<String> values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public List<String> values;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
|
public String getId() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getController() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
@@ -17,9 +17,9 @@ import org.dspace.app.rest.RootRestResourceController;
|
|||||||
public class RootRest extends RestAddressableModel {
|
public class RootRest extends RestAddressableModel {
|
||||||
public static final String NAME = "root";
|
public static final String NAME = "root";
|
||||||
public static final String CATEGORY = RestModel.ROOT;
|
public static final String CATEGORY = RestModel.ROOT;
|
||||||
private String dspaceURL;
|
private String dspaceUI;
|
||||||
private String dspaceName;
|
private String dspaceName;
|
||||||
private String dspaceRest;
|
private String dspaceServer;
|
||||||
|
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
return CATEGORY;
|
return CATEGORY;
|
||||||
@@ -33,13 +33,13 @@ public class RootRest extends RestAddressableModel {
|
|||||||
return RootRestResourceController.class;
|
return RootRestResourceController.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDspaceURL() {
|
public String getDspaceUI() {
|
||||||
|
|
||||||
return dspaceURL;
|
return dspaceUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDspaceURL(String dspaceURL) {
|
public void setDspaceUI(String dspaceUI) {
|
||||||
this.dspaceURL = dspaceURL;
|
this.dspaceUI = dspaceUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDspaceName() {
|
public String getDspaceName() {
|
||||||
@@ -50,12 +50,12 @@ public class RootRest extends RestAddressableModel {
|
|||||||
this.dspaceName = dspaceName;
|
this.dspaceName = dspaceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDspaceRest() {
|
public String getDspaceServer() {
|
||||||
return dspaceRest;
|
return dspaceServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDspaceRest(String dspaceRest) {
|
public void setDspaceServer(String dspaceServerURL) {
|
||||||
this.dspaceRest = dspaceRest;
|
this.dspaceServer = dspaceServerURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,9 +64,9 @@ public class RootRest extends RestAddressableModel {
|
|||||||
new EqualsBuilder().append(this.getCategory(), ((RootRest) object).getCategory())
|
new EqualsBuilder().append(this.getCategory(), ((RootRest) object).getCategory())
|
||||||
.append(this.getType(), ((RootRest) object).getType())
|
.append(this.getType(), ((RootRest) object).getType())
|
||||||
.append(this.getController(), ((RootRest) object).getController())
|
.append(this.getController(), ((RootRest) object).getController())
|
||||||
.append(this.getDspaceURL(), ((RootRest) object).getDspaceURL())
|
.append(this.getDspaceUI(), ((RootRest) object).getDspaceUI())
|
||||||
.append(this.getDspaceName(), ((RootRest) object).getDspaceName())
|
.append(this.getDspaceName(), ((RootRest) object).getDspaceName())
|
||||||
.append(this.getDspaceRest(), ((RootRest) object).getDspaceRest())
|
.append(this.getDspaceServer(), ((RootRest) object).getDspaceServer())
|
||||||
.isEquals());
|
.isEquals());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,8 +77,8 @@ public class RootRest extends RestAddressableModel {
|
|||||||
.append(this.getType())
|
.append(this.getType())
|
||||||
.append(this.getController())
|
.append(this.getController())
|
||||||
.append(this.getDspaceName())
|
.append(this.getDspaceName())
|
||||||
.append(this.getDspaceURL())
|
.append(this.getDspaceUI())
|
||||||
.append(this.getDspaceRest())
|
.append(this.getDspaceServer())
|
||||||
.toHashCode();
|
.toHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the REST representation of the CCLicenseFieldEnum model object and acts as a data sub object
|
||||||
|
* for the SubmissionCCLicenseFieldRest class.
|
||||||
|
* Refer to {@link org.dspace.license.CCLicenseFieldEnum} for explanation of the properties
|
||||||
|
*/
|
||||||
|
public class SubmissionCCLicenseFieldEnumRest {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String label;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(final String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the REST representation of the CCLicenseField model object and acts as a data sub object
|
||||||
|
* for the SubmissionCCLicenseRest class.
|
||||||
|
* Refer to {@link org.dspace.license.CCLicenseField} for explanation of the properties
|
||||||
|
*/
|
||||||
|
public class SubmissionCCLicenseFieldRest {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private List<SubmissionCCLicenseFieldEnumRest> enums;
|
||||||
|
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(final String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubmissionCCLicenseFieldEnumRest> getEnums() {
|
||||||
|
return enums;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnums(final List<SubmissionCCLicenseFieldEnumRest> enums) {
|
||||||
|
this.enums = enums;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the REST representation of the CCLicense model object and acts as a data object
|
||||||
|
* for the SubmissionCCLicenseResource class.
|
||||||
|
* Refer to {@link org.dspace.license.CCLicense} for explanation of the properties
|
||||||
|
*/
|
||||||
|
public class SubmissionCCLicenseRest extends BaseObjectRest<String> {
|
||||||
|
public static final String NAME = "submissioncclicense";
|
||||||
|
public static final String PLURAL = "submissioncclicenses";
|
||||||
|
|
||||||
|
public static final String CATEGORY = RestAddressableModel.CONFIGURATION;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private List<SubmissionCCLicenseFieldRest> fields;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubmissionCCLicenseFieldRest> getFields() {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFields(final List<SubmissionCCLicenseFieldRest> fields) {
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
|
public Class getController() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the REST representation of the CCLicense URL String object and acts as a data object
|
||||||
|
* for the SubmissionCCLicenseUrlRest class.
|
||||||
|
*/
|
||||||
|
public class SubmissionCCLicenseUrlRest extends BaseObjectRest<String> {
|
||||||
|
public static final String NAME = "submissioncclicenseUrl";
|
||||||
|
public static final String PLURAL = "submissioncclicenseUrls";
|
||||||
|
public static final String CATEGORY = RestAddressableModel.CONFIGURATION;
|
||||||
|
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(final String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return SubmissionCCLicenseUrlRest.CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
|
public Class getController() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.ProcessFileTypesRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource object for {@link ProcessFileTypesRest}
|
||||||
|
*/
|
||||||
|
@RelNameDSpaceResource(ProcessFileTypesRest.NAME)
|
||||||
|
public class ProcessFileTypesResource extends HALResource<ProcessFileTypesRest> {
|
||||||
|
|
||||||
|
public ProcessFileTypesResource(ProcessFileTypesRest content) {
|
||||||
|
super(content);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.PropertyRest;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this class is to wrap the information of the PropertyRest into a HAL resource
|
||||||
|
*/
|
||||||
|
public class PropertyResource extends DSpaceResource<PropertyRest> {
|
||||||
|
|
||||||
|
public PropertyResource(PropertyRest data, Utils utils) {
|
||||||
|
super(data, utils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CCLicense HAL Resource. This resource adds the data from the REST object together with embedded objects
|
||||||
|
* and a set of links if applicable
|
||||||
|
*/
|
||||||
|
@RelNameDSpaceResource(SubmissionCCLicenseRest.NAME)
|
||||||
|
public class SubmissionCCLicenseResource extends DSpaceResource<SubmissionCCLicenseRest> {
|
||||||
|
public SubmissionCCLicenseResource(SubmissionCCLicenseRest submissionCCLicenseRest, Utils utils) {
|
||||||
|
super(submissionCCLicenseRest, utils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SubmissionCCLicenseUrlRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubmissionCCLicenseUrl HAL Resource. This resource adds the data from the REST object together with embedded objects
|
||||||
|
* and a set of links if applicable
|
||||||
|
*/
|
||||||
|
@RelNameDSpaceResource(SubmissionCCLicenseUrlRest.NAME)
|
||||||
|
public class SubmissionCCLicenseUrlResource extends DSpaceResource<SubmissionCCLicenseUrlRest> {
|
||||||
|
public SubmissionCCLicenseUrlResource(SubmissionCCLicenseUrlRest submissionCCLicenseUrlRest, Utils utils) {
|
||||||
|
super(submissionCCLicenseUrlRest, utils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.step;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java Bean to expose the section creativecommons representing the CC License during in progress submission.
|
||||||
|
*/
|
||||||
|
public class DataCCLicense implements SectionData {
|
||||||
|
|
||||||
|
private String uri;
|
||||||
|
|
||||||
|
private String rights;
|
||||||
|
|
||||||
|
private BitstreamRest file;
|
||||||
|
|
||||||
|
public String getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUri(final String uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRights() {
|
||||||
|
return rights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRights(final String rights) {
|
||||||
|
this.rights = rights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitstreamRest getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile(final BitstreamRest file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model.wrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a model implementation for {@link org.dspace.app.rest.model.SubmissionCCLicenseUrlRest}
|
||||||
|
* This will simply store a url and an id. it'll be used to create an object with these variables out of information
|
||||||
|
* that came from the back-end. This object will then be used in the
|
||||||
|
* {@link org.dspace.app.rest.converter.SubmissionCCLicenseUrlConverter} to turn it into its REST object
|
||||||
|
*/
|
||||||
|
public class SubmissionCCLicenseUrl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url for ths object
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* The id for this object
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor with two parameters, url and id
|
||||||
|
* @param url The url of this object
|
||||||
|
* @param id The id of this object
|
||||||
|
*/
|
||||||
|
public SubmissionCCLicenseUrl(String url, String id) {
|
||||||
|
this.url = url;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the url
|
||||||
|
* @return the url value of this SubmissionCCLicenseUrl
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the url
|
||||||
|
* @param url The url to be set on this SubmissionCCLicenseUrl
|
||||||
|
*/
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic getter for the id
|
||||||
|
* @return the id value of this SubmissionCCLicenseUrl
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic setter for the id
|
||||||
|
* @param id The id to be set on this SubmissionCCLicenseUrl
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
@@ -8,19 +8,24 @@
|
|||||||
package org.dspace.app.rest.repository;
|
package org.dspace.app.rest.repository;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.DiscoverableEndpointsService;
|
||||||
import org.dspace.app.rest.model.AuthorityRest;
|
import org.dspace.app.rest.model.AuthorityRest;
|
||||||
|
import org.dspace.app.rest.model.AuthorizationRest;
|
||||||
import org.dspace.app.rest.projection.Projection;
|
import org.dspace.app.rest.projection.Projection;
|
||||||
import org.dspace.app.rest.utils.AuthorityUtils;
|
import org.dspace.app.rest.utils.AuthorityUtils;
|
||||||
import org.dspace.content.authority.ChoiceAuthority;
|
import org.dspace.content.authority.ChoiceAuthority;
|
||||||
import org.dspace.content.authority.service.ChoiceAuthorityService;
|
import org.dspace.content.authority.service.ChoiceAuthorityService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -30,7 +35,8 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
|
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
|
||||||
*/
|
*/
|
||||||
@Component(AuthorityRest.CATEGORY + "." + AuthorityRest.NAME)
|
@Component(AuthorityRest.CATEGORY + "." + AuthorityRest.NAME)
|
||||||
public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest, String> {
|
public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest, String>
|
||||||
|
implements InitializingBean {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ChoiceAuthorityService cas;
|
private ChoiceAuthorityService cas;
|
||||||
@@ -38,6 +44,9 @@ public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest,
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AuthorityUtils authorityUtils;
|
private AuthorityUtils authorityUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DiscoverableEndpointsService discoverableEndpointsService;
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public AuthorityRest findOne(Context context, String name) {
|
public AuthorityRest findOne(Context context, String name) {
|
||||||
@@ -63,4 +72,11 @@ public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest,
|
|||||||
public Class<AuthorityRest> getDomainClass() {
|
public Class<AuthorityRest> getDomainClass() {
|
||||||
return AuthorityRest.class;
|
return AuthorityRest.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
discoverableEndpointsService.register(this, Arrays.asList(
|
||||||
|
new Link("/api/" + AuthorizationRest.CATEGORY + "/" + AuthorizationRest.NAME + "/search",
|
||||||
|
AuthorizationRest.NAME + "-search")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,11 +45,10 @@ public class AuthorizationFeatureRestRepository extends DSpaceRestRepository<Aut
|
|||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
public Page<AuthorizationFeatureRest> findAll(Context context, Pageable pageable) {
|
public Page<AuthorizationFeatureRest> findAll(Context context, Pageable pageable) {
|
||||||
return converter.toRestPage(utils.getPage(authorizationFeatureService.findAll(),
|
return converter.toRestPage(authorizationFeatureService.findAll(), pageable, utils.obtainProjection());
|
||||||
pageable), utils.obtainProjection());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
@PreAuthorize("permitAll()")
|
||||||
@Override
|
@Override
|
||||||
public AuthorizationFeatureRest findOne(Context context, String id) {
|
public AuthorizationFeatureRest findOne(Context context, String id) {
|
||||||
AuthorizationFeature authzFeature = authorizationFeatureService.find(id);
|
AuthorizationFeature authzFeature = authorizationFeatureService.find(id);
|
||||||
@@ -64,6 +63,6 @@ public class AuthorizationFeatureRestRepository extends DSpaceRestRepository<Aut
|
|||||||
public Page<AuthorizationFeatureRest> findByResourceType(@Parameter(value = "type", required = true) String type,
|
public Page<AuthorizationFeatureRest> findByResourceType(@Parameter(value = "type", required = true) String type,
|
||||||
Pageable pageable) {
|
Pageable pageable) {
|
||||||
List<AuthorizationFeature> foundFeatures = authorizationFeatureService.findByResourceType(type);
|
List<AuthorizationFeature> foundFeatures = authorizationFeatureService.findByResourceType(type);
|
||||||
return converter.toRestPage(utils.getPage(foundFeatures, pageable), utils.obtainProjection());
|
return converter.toRestPage(foundFeatures, pageable, utils.obtainProjection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -174,7 +174,7 @@ public class AuthorizationRestRepository extends DSpaceRestRepository<Authorizat
|
|||||||
// restore the real current user
|
// restore the real current user
|
||||||
context.restoreContextUser();
|
context.restoreContextUser();
|
||||||
}
|
}
|
||||||
return converter.toRestPage(utils.getPage(authorizations, pageable), utils.obtainProjection());
|
return converter.toRestPage(authorizations, pageable, utils.obtainProjection());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -42,6 +42,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
|
|||||||
BitstreamFormatService bitstreamFormatService;
|
BitstreamFormatService bitstreamFormatService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("permitAll()")
|
||||||
public BitstreamFormatRest findOne(Context context, Integer id) {
|
public BitstreamFormatRest findOne(Context context, Integer id) {
|
||||||
BitstreamFormat bit = null;
|
BitstreamFormat bit = null;
|
||||||
try {
|
try {
|
||||||
@@ -59,7 +60,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
|
|||||||
public Page<BitstreamFormatRest> findAll(Context context, Pageable pageable) {
|
public Page<BitstreamFormatRest> findAll(Context context, Pageable pageable) {
|
||||||
try {
|
try {
|
||||||
List<BitstreamFormat> bit = bitstreamFormatService.findAll(context);
|
List<BitstreamFormat> bit = bitstreamFormatService.findAll(context);
|
||||||
return converter.toRestPage(utils.getPage(bit, pageable), utils.obtainProjection());
|
return converter.toRestPage(bit, pageable, utils.obtainProjection());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -10,17 +10,14 @@ package org.dspace.app.rest.repository;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
import org.dspace.app.rest.model.BitstreamRest;
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
import org.dspace.app.rest.model.BundleRest;
|
import org.dspace.app.rest.model.BundleRest;
|
||||||
import org.dspace.app.rest.model.patch.Patch;
|
import org.dspace.app.rest.model.patch.Patch;
|
||||||
import org.dspace.app.rest.projection.Projection;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
@@ -34,7 +31,6 @@ import org.dspace.content.service.CommunityService;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@@ -71,7 +67,7 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository<Bitstrea
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasPermission(#id, 'BITSTREAM', 'READ')")
|
@PreAuthorize("hasPermission(#id, 'BITSTREAM', 'METADATA_READ')")
|
||||||
public BitstreamRest findOne(Context context, UUID id) {
|
public BitstreamRest findOne(Context context, UUID id) {
|
||||||
Bitstream bit = null;
|
Bitstream bit = null;
|
||||||
try {
|
try {
|
||||||
@@ -95,22 +91,7 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository<Bitstrea
|
|||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
public Page<BitstreamRest> findAll(Context context, Pageable pageable) {
|
public Page<BitstreamRest> findAll(Context context, Pageable pageable) {
|
||||||
List<Bitstream> bit = new ArrayList<Bitstream>();
|
throw new RepositoryMethodNotImplementedException(BitstreamRest.NAME, "findAll");
|
||||||
Iterator<Bitstream> it = null;
|
|
||||||
int total = 0;
|
|
||||||
try {
|
|
||||||
total = bs.countTotal(context);
|
|
||||||
it = bs.findAll(context, pageable.getPageSize(), Math.toIntExact(pageable.getOffset()));
|
|
||||||
while (it.hasNext()) {
|
|
||||||
bit.add(it.next());
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
Projection projection = utils.obtainProjection();
|
|
||||||
Page<BitstreamRest> page = new PageImpl<>(bit, pageable, total)
|
|
||||||
.map((bitstream) -> converter.toRest(bitstream, projection));
|
|
||||||
return page;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -16,6 +16,7 @@ import org.dspace.browse.BrowseIndex;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,6 +28,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class BrowseIndexRestRepository extends DSpaceRestRepository<BrowseIndexRest, String> {
|
public class BrowseIndexRestRepository extends DSpaceRestRepository<BrowseIndexRest, String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("permitAll()")
|
||||||
public BrowseIndexRest findOne(Context context, String name) {
|
public BrowseIndexRest findOne(Context context, String name) {
|
||||||
BrowseIndexRest bi = null;
|
BrowseIndexRest bi = null;
|
||||||
BrowseIndex bix;
|
BrowseIndex bix;
|
||||||
|
@@ -15,7 +15,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import org.dspace.app.rest.model.BitstreamRest;
|
import org.dspace.app.rest.model.BitstreamRest;
|
||||||
import org.dspace.app.rest.model.BundleRest;
|
import org.dspace.app.rest.model.BundleRest;
|
||||||
import org.dspace.app.rest.projection.Projection;
|
import org.dspace.app.rest.projection.Projection;
|
||||||
import org.dspace.content.Bitstream;
|
|
||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.content.service.BundleService;
|
import org.dspace.content.service.BundleService;
|
||||||
@@ -52,8 +51,7 @@ public class BundleBitstreamLinkRepository extends AbstractDSpaceRestRepository
|
|||||||
throw new ResourceNotFoundException("No such bundle: " + bundleId);
|
throw new ResourceNotFoundException("No such bundle: " + bundleId);
|
||||||
}
|
}
|
||||||
Pageable pageable = utils.getPageable(optionalPageable);
|
Pageable pageable = utils.getPageable(optionalPageable);
|
||||||
Page<Bitstream> page = utils.getPage(bundle.getBitstreams(), pageable);
|
return converter.toRestPage(bundle.getBitstreams(), pageable, projection);
|
||||||
return converter.toRestPage(page, projection);
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -74,11 +74,11 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
|
|||||||
this.bundleService = dsoService;
|
this.bundleService = dsoService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasPermission(#uuid, 'BUNDLE', 'READ')")
|
@PreAuthorize("hasPermission(#id, 'BUNDLE', 'READ')")
|
||||||
public BundleRest findOne(Context context, UUID uuid) {
|
public BundleRest findOne(Context context, UUID id) {
|
||||||
Bundle bundle = null;
|
Bundle bundle = null;
|
||||||
try {
|
try {
|
||||||
bundle = bundleService.find(context, uuid);
|
bundle = bundleService.find(context, id);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ package org.dspace.app.rest.repository;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
@@ -16,6 +17,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.app.rest.DiscoverableEndpointsService;
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
import org.dspace.app.rest.exception.RESTAuthorizationException;
|
import org.dspace.app.rest.exception.RESTAuthorizationException;
|
||||||
@@ -42,10 +44,12 @@ import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
|||||||
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
|
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
|
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -56,7 +60,8 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Component(PoolTaskRest.CATEGORY + "." + ClaimedTaskRest.NAME)
|
@Component(PoolTaskRest.CATEGORY + "." + ClaimedTaskRest.NAME)
|
||||||
public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskRest, Integer> {
|
public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskRest, Integer>
|
||||||
|
implements InitializingBean {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(ClaimedTaskRestRepository.class);
|
private static final Logger log = Logger.getLogger(ClaimedTaskRestRepository.class);
|
||||||
|
|
||||||
@@ -78,6 +83,9 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskR
|
|||||||
@Autowired
|
@Autowired
|
||||||
AuthorizeService authorizeService;
|
AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DiscoverableEndpointsService discoverableEndpointsService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasPermission(#id, 'CLAIMEDTASK', 'READ')")
|
@PreAuthorize("hasPermission(#id, 'CLAIMEDTASK', 'READ')")
|
||||||
public ClaimedTaskRest findOne(Context context, Integer id) {
|
public ClaimedTaskRest findOne(Context context, Integer id) {
|
||||||
@@ -108,7 +116,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskR
|
|||||||
if (authorizeService.isAdmin(context) || userID.equals(currentUser.getID())) {
|
if (authorizeService.isAdmin(context) || userID.equals(currentUser.getID())) {
|
||||||
EPerson ep = epersonService.find(context, userID);
|
EPerson ep = epersonService.find(context, userID);
|
||||||
List<ClaimedTask> tasks = claimedTaskService.findByEperson(context, ep);
|
List<ClaimedTask> tasks = claimedTaskService.findByEperson(context, ep);
|
||||||
return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection());
|
return converter.toRestPage(tasks, pageable, utils.obtainProjection());
|
||||||
} else {
|
} else {
|
||||||
throw new RESTAuthorizationException("Only administrators can search for claimed tasks of other users");
|
throw new RESTAuthorizationException("Only administrators can search for claimed tasks of other users");
|
||||||
}
|
}
|
||||||
@@ -188,4 +196,11 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskR
|
|||||||
public Page<ClaimedTaskRest> findAll(Context context, Pageable pageable) {
|
public Page<ClaimedTaskRest> findAll(Context context, Pageable pageable) {
|
||||||
throw new RepositoryMethodNotImplementedException(ClaimedTaskRest.NAME, "findAll");
|
throw new RepositoryMethodNotImplementedException(ClaimedTaskRest.NAME, "findAll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
discoverableEndpointsService.register(this, Arrays.asList(
|
||||||
|
new Link("/api/" + ClaimedTaskRest.CATEGORY + "/" + ClaimedTaskRest.NAME + "/search",
|
||||||
|
ClaimedTaskRest.NAME + "-search")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -72,6 +72,9 @@ public class CollectionBitstreamReadGroupLinkRepository extends AbstractDSpaceRe
|
|||||||
}
|
}
|
||||||
List<Group> bitstreamGroups = authorizeService
|
List<Group> bitstreamGroups = authorizeService
|
||||||
.getAuthorizedGroups(context, collection, Constants.DEFAULT_BITSTREAM_READ);
|
.getAuthorizedGroups(context, collection, Constants.DEFAULT_BITSTREAM_READ);
|
||||||
|
if (bitstreamGroups == null || bitstreamGroups.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Group bitstreamReadGroup = bitstreamGroups.get(0);
|
Group bitstreamReadGroup = bitstreamGroups.get(0);
|
||||||
|
|
||||||
if (bitstreamReadGroup == null) {
|
if (bitstreamReadGroup == null) {
|
||||||
|
@@ -163,9 +163,10 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SearchRestMethod(name = "findAuthorizedByCommunity")
|
@SearchRestMethod(name = "findSubmitAuthorizedByCommunity")
|
||||||
public Page<CollectionRest> findAuthorizedByCommunity(
|
public Page<CollectionRest> findSubmitAuthorizedByCommunity(
|
||||||
@Parameter(value = "uuid", required = true) UUID communityUuid, Pageable pageable) {
|
@Parameter(value = "uuid", required = true) UUID communityUuid, Pageable pageable,
|
||||||
|
@Parameter(value = "query") String q) {
|
||||||
try {
|
try {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
Community com = communityService.find(context, communityUuid);
|
Community com = communityService.find(context, communityUuid);
|
||||||
@@ -174,19 +175,26 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + communityUuid
|
CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + communityUuid
|
||||||
+ " not found");
|
+ " not found");
|
||||||
}
|
}
|
||||||
List<Collection> collections = cs.findAuthorized(context, com, Constants.ADD);
|
List<Collection> collections = cs.findCollectionsWithSubmit(q, context, com,
|
||||||
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection());
|
Math.toIntExact(pageable.getOffset()),
|
||||||
} catch (SQLException e) {
|
Math.toIntExact(pageable.getOffset() + pageable.getPageSize()));
|
||||||
|
int tot = cs.countCollectionsWithSubmit(q, context, com);
|
||||||
|
return converter.toRestPage(collections, pageable, tot , utils.obtainProjection());
|
||||||
|
} catch (SQLException | SearchServiceException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SearchRestMethod(name = "findAuthorized")
|
@SearchRestMethod(name = "findSubmitAuthorized")
|
||||||
public Page<CollectionRest> findAuthorized(Pageable pageable) {
|
public Page<CollectionRest> findSubmitAuthorized(@Parameter(value = "query") String q,
|
||||||
|
Pageable pageable) throws SearchServiceException {
|
||||||
try {
|
try {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
List<Collection> collections = cs.findAuthorizedOptimized(context, Constants.ADD);
|
List<Collection> collections = cs.findCollectionsWithSubmit(q, context, null,
|
||||||
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection());
|
Math.toIntExact(pageable.getOffset()),
|
||||||
|
Math.toIntExact(pageable.getOffset() + pageable.getPageSize()));
|
||||||
|
int tot = cs.countCollectionsWithSubmit(q, context, null);
|
||||||
|
return converter.toRestPage(collections, pageable, tot, utils.obtainProjection());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user