mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 10:04:21 +00:00
Merge pull request #10673 from DSpace/backport-10640-to-dspace-7_x
[Port dspace-7_x] Improve CLI RegistryLoader, InitializeEntities, Curation commands
This commit is contained in:
@@ -21,6 +21,13 @@ import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.BitstreamFormat;
|
||||
@@ -41,7 +48,7 @@ import org.xml.sax.SAXException;
|
||||
* <P>
|
||||
* <code>RegistryLoader -bitstream bitstream-formats.xml</code>
|
||||
* <P>
|
||||
* <code>RegistryLoader -dc dc-types.xml</code>
|
||||
* <code>RegistryLoader -metadata dc-types.xml</code>
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @version $Revision$
|
||||
@@ -50,7 +57,7 @@ public class RegistryLoader {
|
||||
/**
|
||||
* log4j category
|
||||
*/
|
||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(RegistryLoader.class);
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(RegistryLoader.class);
|
||||
|
||||
protected static BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance()
|
||||
.getBitstreamFormatService();
|
||||
@@ -67,50 +74,99 @@ public class RegistryLoader {
|
||||
* @throws Exception if error
|
||||
*/
|
||||
public static void main(String[] argv) throws Exception {
|
||||
String usage = "Usage: " + RegistryLoader.class.getName()
|
||||
+ " (-bitstream | -metadata) registry-file.xml";
|
||||
|
||||
Context context = null;
|
||||
// Set up command-line options and parse arguments
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
Options options = createCommandLineOptions();
|
||||
|
||||
try {
|
||||
context = new Context();
|
||||
CommandLine line = parser.parse(options, argv);
|
||||
|
||||
// Check if help option was entered or no options provided
|
||||
if (line.hasOption('h') || line.getOptions().length == 0) {
|
||||
printHelp(options);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Context context = new Context();
|
||||
|
||||
// Can't update registries anonymously, so we need to turn off
|
||||
// authorisation
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
// Work out what we're loading
|
||||
if (argv[0].equalsIgnoreCase("-bitstream")) {
|
||||
RegistryLoader.loadBitstreamFormats(context, argv[1]);
|
||||
} else if (argv[0].equalsIgnoreCase("-metadata")) {
|
||||
// Call MetadataImporter, as it handles Metadata schema updates
|
||||
MetadataImporter.loadRegistry(argv[1], true);
|
||||
} else {
|
||||
System.err.println(usage);
|
||||
try {
|
||||
// Work out what we're loading
|
||||
if (line.hasOption('b')) {
|
||||
String filename = line.getOptionValue('b');
|
||||
if (StringUtils.isEmpty(filename)) {
|
||||
System.err.println("No file path provided for bitstream format registry");
|
||||
printHelp(options);
|
||||
System.exit(1);
|
||||
}
|
||||
RegistryLoader.loadBitstreamFormats(context, filename);
|
||||
} else if (line.hasOption('m')) {
|
||||
String filename = line.getOptionValue('m');
|
||||
if (StringUtils.isEmpty(filename)) {
|
||||
System.err.println("No file path provided for metadata registry");
|
||||
printHelp(options);
|
||||
System.exit(1);
|
||||
}
|
||||
// Call MetadataImporter, as it handles Metadata schema updates
|
||||
MetadataImporter.loadRegistry(filename, true);
|
||||
} else {
|
||||
System.err.println("No registry type specified");
|
||||
printHelp(options);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Commit changes and close Context
|
||||
context.complete();
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
log.fatal(LogHelper.getHeader(context, "error_loading_registries", ""), e);
|
||||
System.err.println("Error: \n - " + e.getMessage());
|
||||
System.exit(1);
|
||||
} finally {
|
||||
// Clean up our context, if it still exists & it was never completed
|
||||
if (context != null && context.isValid()) {
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Commit changes and close Context
|
||||
context.complete();
|
||||
|
||||
System.exit(0);
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
System.err.println(usage);
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println("Error parsing command-line arguments: " + e.getMessage());
|
||||
printHelp(options);
|
||||
System.exit(1);
|
||||
} catch (Exception e) {
|
||||
log.fatal(LogHelper.getHeader(context, "error_loading_registries",
|
||||
""), e);
|
||||
|
||||
System.err.println("Error: \n - " + e.getMessage());
|
||||
System.exit(1);
|
||||
} finally {
|
||||
// Clean up our context, if it still exists & it was never completed
|
||||
if (context != null && context.isValid()) {
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the command-line options
|
||||
* @return the command-line options
|
||||
*/
|
||||
private static Options createCommandLineOptions() {
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("b", "bitstream", true, "load bitstream format registry from specified file");
|
||||
options.addOption("m", "metadata", true, "load metadata registry from specified file");
|
||||
options.addOption("h", "help", false, "print this help message");
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the help message
|
||||
* @param options the command-line options
|
||||
*/
|
||||
private static void printHelp(Options options) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp("RegistryLoader",
|
||||
"Load bitstream format or metadata registries into the database\n",
|
||||
options,
|
||||
"\nExamples:\n" +
|
||||
" RegistryLoader -b bitstream-formats.xml\n" +
|
||||
" RegistryLoader -m dc-types.xml",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Bitstream Format metadata
|
||||
*
|
||||
@@ -221,7 +277,7 @@ public class RegistryLoader {
|
||||
* contains:
|
||||
* <P>
|
||||
* <code>
|
||||
* <foo><mimetype>application/pdf</mimetype></foo>
|
||||
* <foo><mimetype>application/pdf</mimetype></foo>
|
||||
* </code>
|
||||
* passing this the <code>foo</code> node and <code>mimetype</code> will
|
||||
* return <code>application/pdf</code>.
|
||||
@@ -262,10 +318,10 @@ public class RegistryLoader {
|
||||
* document contains:
|
||||
* <P>
|
||||
* <code>
|
||||
* <foo>
|
||||
* <bar>val1</bar>
|
||||
* <bar>val2</bar>
|
||||
* </foo>
|
||||
* <foo>
|
||||
* <bar>val1</bar>
|
||||
* <bar>val2</bar>
|
||||
* </foo>
|
||||
* </code>
|
||||
* passing this the <code>foo</code> node and <code>bar</code> will
|
||||
* return <code>val1</code> and <code>val2</code>.
|
||||
@@ -295,4 +351,4 @@ public class RegistryLoader {
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
@@ -64,20 +64,36 @@ public class InitializeEntities {
|
||||
*/
|
||||
public static void main(String[] argv) throws SQLException, AuthorizeException, ParseException {
|
||||
InitializeEntities initializeEntities = new InitializeEntities();
|
||||
// Set up command-line options and parse arguments
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
Options options = createCommandLineOptions();
|
||||
CommandLine line = parser.parse(options,argv);
|
||||
String fileLocation = getFileLocationFromCommandLine(line);
|
||||
// First of all, check if the help option was entered or a required argument is missing
|
||||
checkHelpEntered(options, line);
|
||||
// Get the file location from the command line
|
||||
String fileLocation = getFileLocationFromCommandLine(line);
|
||||
// Run the script
|
||||
initializeEntities.run(fileLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the help option was entered or a required argument is missing. If so, print help and exit.
|
||||
* @param options the defined command-line options
|
||||
* @param line the parsed command-line arguments
|
||||
*/
|
||||
private static void checkHelpEntered(Options options, CommandLine line) {
|
||||
if (line.hasOption("h")) {
|
||||
if (line.hasOption("h") || !line.hasOption("f")) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp("Intialize Entities", options);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file path from the command-line argument. Exits with exit code 1 if no file argument was entered.
|
||||
* @param line the parsed command-line arguments
|
||||
* @return the file path
|
||||
*/
|
||||
private static String getFileLocationFromCommandLine(CommandLine line) {
|
||||
String query = line.getOptionValue("f");
|
||||
if (StringUtils.isEmpty(query)) {
|
||||
@@ -88,13 +104,25 @@ public class InitializeEntities {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the command-line options
|
||||
* @return the command-line options
|
||||
*/
|
||||
protected static Options createCommandLineOptions() {
|
||||
Options options = new Options();
|
||||
options.addOption("f", "file", true, "the location for the file containing the xml data");
|
||||
options.addOption("f", "file", true, "the path to the file containing the " +
|
||||
"relationship definitions (e.g. ${dspace.dir}/config/entities/relationship-types.xml)");
|
||||
options.addOption("h", "help", false, "print this message");
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the script for the given file location
|
||||
* @param fileLocation the file location
|
||||
* @throws SQLException If something goes wrong initializing context or inserting relationship types
|
||||
* @throws AuthorizeException If the script user fails to authorize while inserting relationship types
|
||||
*/
|
||||
private void run(String fileLocation) throws SQLException, AuthorizeException {
|
||||
Context context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
@@ -102,6 +130,12 @@ public class InitializeEntities {
|
||||
context.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the XML file at fileLocation to create relationship types in the database
|
||||
* @param context DSpace context
|
||||
* @param fileLocation the full or relative file path to the relationship types XML
|
||||
* @throws AuthorizeException If the script user fails to authorize while inserting relationship types
|
||||
*/
|
||||
private void parseXMLToRelations(Context context, String fileLocation) throws AuthorizeException {
|
||||
try {
|
||||
File fXmlFile = new File(fileLocation);
|
||||
@@ -158,15 +192,15 @@ public class InitializeEntities {
|
||||
|
||||
for (int j = 0; j < leftCardinalityList.getLength(); j++) {
|
||||
Node node = leftCardinalityList.item(j);
|
||||
leftCardinalityMin = getString(leftCardinalityMin,(Element) node, "min");
|
||||
leftCardinalityMax = getString(leftCardinalityMax,(Element) node, "max");
|
||||
leftCardinalityMin = getCardinalityMinString(leftCardinalityMin,(Element) node, "min");
|
||||
leftCardinalityMax = getCardinalityMinString(leftCardinalityMax,(Element) node, "max");
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < rightCardinalityList.getLength(); j++) {
|
||||
Node node = rightCardinalityList.item(j);
|
||||
rightCardinalityMin = getString(rightCardinalityMin,(Element) node, "min");
|
||||
rightCardinalityMax = getString(rightCardinalityMax,(Element) node, "max");
|
||||
rightCardinalityMin = getCardinalityMinString(rightCardinalityMin,(Element) node, "min");
|
||||
rightCardinalityMax = getCardinalityMinString(rightCardinalityMax,(Element) node, "max");
|
||||
|
||||
}
|
||||
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
|
||||
@@ -182,13 +216,39 @@ public class InitializeEntities {
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(String leftCardinalityMin,Element node, String minOrMax) {
|
||||
/**
|
||||
* Extract the min or max value for the left or right cardinality from the node text content
|
||||
* @param leftCardinalityMin current left cardinality min
|
||||
* @param node node to extract the min or max value from
|
||||
* @param minOrMax element tag name to parse
|
||||
* @return final left cardinality min
|
||||
*/
|
||||
private String getCardinalityMinString(String leftCardinalityMin, Element node, String minOrMax) {
|
||||
if (node.getElementsByTagName(minOrMax).getLength() > 0) {
|
||||
leftCardinalityMin = node.getElementsByTagName(minOrMax).item(0).getTextContent();
|
||||
}
|
||||
return leftCardinalityMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the relationship type based on values parsed from the XML relationship types configuration
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param leftType left relationship type (e.g. "Publication").
|
||||
* @param rightType right relationship type (e.g. "Journal").
|
||||
* @param leftwardType leftward relationship type (e.g. "isAuthorOfPublication").
|
||||
* @param rightwardType rightward relationship type (e.g. "isPublicationOfAuthor").
|
||||
* @param leftCardinalityMin left cardinality min
|
||||
* @param leftCardinalityMax left cardinality max
|
||||
* @param rightCardinalityMin right cardinality min
|
||||
* @param rightCardinalityMax right cardinality max
|
||||
* @param copyToLeft copy metadata values to left if right side is deleted
|
||||
* @param copyToRight copy metadata values to right if left side is deleted
|
||||
* @param tilted set a tilted relationship side (left or right) if there are many relationships going one way
|
||||
* to help performance (e.g. authors with 1000s of publications)
|
||||
* @throws SQLException if database error occurs while saving the relationship type
|
||||
* @throws AuthorizeException if authorization error occurs while saving the relationship type
|
||||
*/
|
||||
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
|
||||
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
|
||||
String rightCardinalityMin, String rightCardinalityMax,
|
||||
|
@@ -24,6 +24,8 @@ import java.util.UUID;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.dspace.app.util.DSpaceObjectUtilsImpl;
|
||||
import org.dspace.app.util.service.DSpaceObjectUtils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
@@ -35,6 +37,7 @@ import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
@@ -45,7 +48,9 @@ import org.dspace.utils.DSpace;
|
||||
public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
||||
|
||||
protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
|
||||
protected DSpaceObjectUtils dspaceObjectUtils = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||
.getServiceByName(DSpaceObjectUtilsImpl.class.getName(), DSpaceObjectUtilsImpl.class);
|
||||
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||
protected Context context;
|
||||
private CurationClientOptions curationClientOptions;
|
||||
|
||||
@@ -345,9 +350,29 @@ public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
|
||||
|
||||
if (this.commandLine.hasOption('i')) {
|
||||
this.id = this.commandLine.getOptionValue('i').toLowerCase();
|
||||
DSpaceObject dso;
|
||||
if (!this.id.equalsIgnoreCase("all")) {
|
||||
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
|
||||
DSpaceObject dso;
|
||||
// First, try to parse the id as a UUID. If that fails, treat it as a handle.
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(id);
|
||||
} catch (Exception e) {
|
||||
// It's not a UUID, proceed to treat it as a handle.
|
||||
}
|
||||
if (uuid != null) {
|
||||
try {
|
||||
dso = dspaceObjectUtils.findDSpaceObject(context, uuid);
|
||||
if (dso != null) {
|
||||
// We already resolved an object, return early
|
||||
return;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String error = "SQLException trying to find dso with uuid " + uuid;
|
||||
super.handler.logError(error);
|
||||
throw new RuntimeException(error, e);
|
||||
}
|
||||
}
|
||||
// If we get here, the id is not a UUID, so we assume it's a handle.
|
||||
try {
|
||||
dso = handleService.resolveToObject(this.context, id);
|
||||
} catch (SQLException e) {
|
||||
|
Reference in New Issue
Block a user