mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 06:53:09 +00:00
(Alexey Maslov) OAI-PMH + OAI-ORE Harvesting Patch
http://jira.dspace.org/jira/browse/DS-289 git-svn-id: http://scm.dspace.org/svn/repo/dspace/trunk@4228 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -176,6 +176,10 @@
|
|||||||
<groupId>com.ibm.icu</groupId>
|
<groupId>com.ibm.icu</groupId>
|
||||||
<artifactId>icu4j</artifactId>
|
<artifactId>icu4j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>oclc-harvester2</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
561
dspace-api/src/main/java/org/dspace/app/harvest/Harvest.java
Normal file
561
dspace-api/src/main/java/org/dspace/app/harvest/Harvest.java
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
/*
|
||||||
|
* Harvest.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-11-28 15:07:34 -0600 (Wed, 28 Nov 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.dspace.app.harvest;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
|
||||||
|
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.PosixParser;
|
||||||
|
import org.apache.xpath.XPathAPI;
|
||||||
|
import org.dspace.app.itemimport.ItemImport;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.browse.IndexBrowse;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.BitstreamFormat;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.FormatIdentifier;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.content.InstallItem;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.ItemIterator;
|
||||||
|
import org.dspace.content.MetadataField;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.content.WorkspaceItem;
|
||||||
|
import org.dspace.harvest.OAIHarvester.HarvestingException;
|
||||||
|
import org.dspace.content.crosswalk.CrosswalkException;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.handle.HandleManager;
|
||||||
|
import org.dspace.workflow.WorkflowManager;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.NamedNodeMap;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for harvested collections.
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class Harvest
|
||||||
|
{
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
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("p", "purge", false, "delete all items in the collection");
|
||||||
|
options.addOption("r", "run", false, "run the standrad harvest procedure");
|
||||||
|
options.addOption("g", "ping", false, "test the OAI server and set");
|
||||||
|
options.addOption("o", "once", false, "run the harvest procedure with specified parameters");
|
||||||
|
options.addOption("s", "setup", false, "Set the collection up for harvesting");
|
||||||
|
options.addOption("S", "start", false, "start the harvest loop");
|
||||||
|
options.addOption("R", "reset", false, "reset harvest status on all collections");
|
||||||
|
options.addOption("P", "purge", false, "purge all harvestable collections");
|
||||||
|
|
||||||
|
|
||||||
|
options.addOption("e", "eperson", true, "eperson");
|
||||||
|
options.addOption("c", "collection", true, "harvesting collection (handle or id)");
|
||||||
|
options.addOption("t", "type", true, "type of harvesting (0 for none)");
|
||||||
|
options.addOption("a", "address", true, "address of the OAI-PMH server");
|
||||||
|
options.addOption("i", "oai_set_id", true, "id of the PMH set representing the harvested collection");
|
||||||
|
options.addOption("m", "metadata_format", true, "the name of the desired metadata format for harvesting, resolved to namespace and crosswalk in dspace.cfg");
|
||||||
|
|
||||||
|
options.addOption("h", "help", false, "help");
|
||||||
|
|
||||||
|
CommandLine line = parser.parse(options, argv);
|
||||||
|
|
||||||
|
String command = null;
|
||||||
|
String eperson = null;
|
||||||
|
String collection = null;
|
||||||
|
String oaiSource = null;
|
||||||
|
String oaiSetID = null;
|
||||||
|
String metadataKey = null;
|
||||||
|
int harvestType = 0;
|
||||||
|
|
||||||
|
if (line.hasOption('h'))
|
||||||
|
{
|
||||||
|
HelpFormatter myhelp = new HelpFormatter();
|
||||||
|
myhelp.printHelp("Harvest\n", options);
|
||||||
|
System.out
|
||||||
|
.println("\nPING OAI server: Harvest -g -s oai_source -i oai_set_id");
|
||||||
|
System.out
|
||||||
|
.println("RUNONCE harvest with arbitrary options: Harvest -o -e eperson -c collection -t harvest_type -a oai_source -i oai_set_id -m metadata_format");
|
||||||
|
System.out
|
||||||
|
.println("SETUP a collection for harvesting: Harvest -s -c collection -t harvest_type -a oai_source -i oai_set_id -m metadata_format");
|
||||||
|
System.out
|
||||||
|
.println("RUN harvest once: Harvest -r -e eperson -c collection");
|
||||||
|
System.out
|
||||||
|
.println("START harvest scheduler: Harvest -S");
|
||||||
|
System.out
|
||||||
|
.println("RESET all harvest status: Harvest -R");
|
||||||
|
System.out
|
||||||
|
.println("PURGE a collection of items and settings: Harvest -p -e eperson -c collection");
|
||||||
|
System.out
|
||||||
|
.println("PURGE all harvestable collections: Harvest -P -e eperson");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.hasOption('s')) {
|
||||||
|
command = "config";
|
||||||
|
}
|
||||||
|
if (line.hasOption('p')) {
|
||||||
|
command = "purge";
|
||||||
|
}
|
||||||
|
if (line.hasOption('r')) {
|
||||||
|
command = "run";
|
||||||
|
}
|
||||||
|
if (line.hasOption('g')) {
|
||||||
|
command = "ping";
|
||||||
|
}
|
||||||
|
if (line.hasOption('o')) {
|
||||||
|
command = "runOnce";
|
||||||
|
}
|
||||||
|
if (line.hasOption('S')) {
|
||||||
|
command = "start";
|
||||||
|
}
|
||||||
|
if (line.hasOption('R')) {
|
||||||
|
command = "reset";
|
||||||
|
}
|
||||||
|
if (line.hasOption('P')) {
|
||||||
|
command = "purgeAll";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (line.hasOption('e')) {
|
||||||
|
eperson = line.getOptionValue('e');
|
||||||
|
}
|
||||||
|
if (line.hasOption('c')) {
|
||||||
|
collection = line.getOptionValue('c');
|
||||||
|
}
|
||||||
|
if (line.hasOption('t')) {
|
||||||
|
harvestType = Integer.parseInt(line.getOptionValue('t'));
|
||||||
|
} else {
|
||||||
|
harvestType = 0;
|
||||||
|
}
|
||||||
|
if (line.hasOption('a')) {
|
||||||
|
oaiSource = line.getOptionValue('a');
|
||||||
|
}
|
||||||
|
if (line.hasOption('i')) {
|
||||||
|
oaiSetID = line.getOptionValue('i');
|
||||||
|
}
|
||||||
|
if (line.hasOption('m')) {
|
||||||
|
metadataKey = line.getOptionValue('m');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate our class
|
||||||
|
Harvest harvester = new Harvest();
|
||||||
|
harvester.context = new Context();
|
||||||
|
|
||||||
|
|
||||||
|
// Check our options
|
||||||
|
if (command == null)
|
||||||
|
{
|
||||||
|
System.out
|
||||||
|
.println("Error - no parameters specified (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
// Run a single harvest cycle on a collection using saved settings.
|
||||||
|
else if (command.equals("run"))
|
||||||
|
{
|
||||||
|
if (collection == null || eperson == null)
|
||||||
|
{
|
||||||
|
System.out
|
||||||
|
.println("Error - a target collection and eperson must be provided");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
harvester.runHarvest(collection, eperson);
|
||||||
|
}
|
||||||
|
// start the harvest loop
|
||||||
|
else if (command.equals("start"))
|
||||||
|
{
|
||||||
|
startHarvester();
|
||||||
|
}
|
||||||
|
// reset harvesting status
|
||||||
|
else if (command.equals("reset"))
|
||||||
|
{
|
||||||
|
resetHarvesting();
|
||||||
|
}
|
||||||
|
// purge all collections that are set up for harvesting (obviously for testing purposes only)
|
||||||
|
else if (command.equals("purgeAll"))
|
||||||
|
{
|
||||||
|
if (eperson == null)
|
||||||
|
{
|
||||||
|
System.out
|
||||||
|
.println("Error - an eperson must be provided");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> cids = HarvestedCollection.findAll(context);
|
||||||
|
System.out.println("Purging the following collections (deleting items and resetting harvest status): " + cids.toString());
|
||||||
|
for (Integer cid : cids)
|
||||||
|
{
|
||||||
|
harvester.purgeCollection(cid.toString(), eperson);
|
||||||
|
}
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
// Delete all items in a collection. Useful for testing fresh harvests.
|
||||||
|
else if (command.equals("purge"))
|
||||||
|
{
|
||||||
|
if (collection == null || eperson == null)
|
||||||
|
{
|
||||||
|
System.out
|
||||||
|
.println("Error - a target collection and eperson must be provided");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
harvester.purgeCollection(collection, eperson);
|
||||||
|
context.complete();
|
||||||
|
|
||||||
|
//TODO: implement this... remove all items and remember to unset "last-harvested" settings
|
||||||
|
}
|
||||||
|
// Configure a collection with the three main settings
|
||||||
|
else if (command.equals("config"))
|
||||||
|
{
|
||||||
|
if (collection == null)
|
||||||
|
{
|
||||||
|
System.out.println("Error - a target collection must be provided");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
if (oaiSource == null || oaiSetID == null)
|
||||||
|
{
|
||||||
|
System.out.println("Error - both the OAI server address and OAI set id must be specified");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
if (metadataKey == null)
|
||||||
|
{
|
||||||
|
System.out.println("Error - a metadata key (commonly the prefix) must be specified for this collection");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
harvester.configureCollection(collection, harvestType, oaiSource, oaiSetID, metadataKey);
|
||||||
|
}
|
||||||
|
else if (command.equals("ping"))
|
||||||
|
{
|
||||||
|
if (oaiSource == null || oaiSetID == null)
|
||||||
|
{
|
||||||
|
System.out.println("Error - both the OAI server address and OAI set id must be specified");
|
||||||
|
System.out.println(" (run with -h flag for details)");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check
|
||||||
|
* @param collectionID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Collection checkCollection(String collectionID)
|
||||||
|
{
|
||||||
|
Collection collection = resolveCollection(collectionID);
|
||||||
|
try {
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collection.getID());
|
||||||
|
if (!hc.isHarvestable()) {
|
||||||
|
System.out.println("Collection '"+ collection.getName() +"' is not set up for harvesting");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
} catch (SQLException se) {
|
||||||
|
se.printStackTrace();
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resolve the ID into a collection and check to see if its harvesting options are set. If so, return
|
||||||
|
* the collection, if not, bail out.
|
||||||
|
*/
|
||||||
|
private Collection resolveCollection(String collectionID) {
|
||||||
|
|
||||||
|
DSpaceObject dso;
|
||||||
|
Collection targetCollection = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// is the ID a handle?
|
||||||
|
if (collectionID.indexOf('/') != -1)
|
||||||
|
{
|
||||||
|
// string has a / so it must be a handle - try and resolve it
|
||||||
|
dso = HandleManager.resolveToObject(context, collectionID);
|
||||||
|
|
||||||
|
// resolved, now make sure it's a collection
|
||||||
|
if (dso == null || dso.getType() != Constants.COLLECTION)
|
||||||
|
targetCollection = null;
|
||||||
|
else
|
||||||
|
targetCollection = (Collection)dso;
|
||||||
|
}
|
||||||
|
// not a handle, try and treat it as an integer collection
|
||||||
|
// database ID
|
||||||
|
else if (collectionID != null)
|
||||||
|
{
|
||||||
|
System.out.println("Looking up by id: " + collectionID + ", parsed as '" + Integer.parseInt(collectionID) + "', " + "in context: " + context);
|
||||||
|
targetCollection = Collection.find(context, Integer.parseInt(collectionID));
|
||||||
|
}
|
||||||
|
// was the collection valid?
|
||||||
|
if (targetCollection == null)
|
||||||
|
{
|
||||||
|
System.out.println("Cannot resolve " + collectionID + " to collection");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException se) {
|
||||||
|
se.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void configureCollection(String collectionID, int type, String oaiSource, String oaiSetId, String mdConfigId) {
|
||||||
|
System.out.println("Running: configure collection");
|
||||||
|
|
||||||
|
Collection collection = resolveCollection(collectionID);
|
||||||
|
System.out.println(collection.getID());
|
||||||
|
|
||||||
|
try {
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collection.getID());
|
||||||
|
if (hc == null) {
|
||||||
|
hc = HarvestedCollection.create(context, collection.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
hc.setHarvestParams(type, oaiSource, oaiSetId, mdConfigId);
|
||||||
|
hc.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
|
hc.update();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
System.out.println("Changes could not be committed");
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges a collection of all harvest-related data and settings. All items in the collection will be deleted.
|
||||||
|
*
|
||||||
|
* @param collectionID
|
||||||
|
* @param email
|
||||||
|
*/
|
||||||
|
private void purgeCollection(String collectionID, String email) {
|
||||||
|
System.out.println("Purging collection of all items and reseting last_harvested and harvest_message: " + collectionID);
|
||||||
|
Collection collection = resolveCollection(collectionID);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EPerson eperson = EPerson.findByEmail(context, email);
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
ItemIterator it = collection.getAllItems();
|
||||||
|
IndexBrowse ib = new IndexBrowse(context);
|
||||||
|
int i=0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
i++;
|
||||||
|
Item item = it.next();
|
||||||
|
System.out.println("Deleting: " + item.getHandle());
|
||||||
|
ib.itemRemoved(item);
|
||||||
|
collection.removeItem(item);
|
||||||
|
// commit every 50 items
|
||||||
|
if (i%50 == 0) {
|
||||||
|
context.commit();
|
||||||
|
i=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collection.getID());
|
||||||
|
if (hc != null) {
|
||||||
|
hc.setHarvestResult(null,"");
|
||||||
|
hc.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
|
hc.setHarvestStartTime(null);
|
||||||
|
hc.update();
|
||||||
|
}
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
context.commit();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
System.out.println("Changes could not be committed");
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a single harvest cycle on the specified collection under the authorization of the supplied EPerson
|
||||||
|
*/
|
||||||
|
private void runHarvest(String collectionID, String email) {
|
||||||
|
System.out.println("Running: a harvest cycle on " + collectionID);
|
||||||
|
|
||||||
|
System.out.print("Initializing the harvester... ");
|
||||||
|
OAIHarvester harvester = null;
|
||||||
|
try {
|
||||||
|
Collection collection = resolveCollection(collectionID);
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collection.getID());
|
||||||
|
harvester = new OAIHarvester(context, collection, hc);
|
||||||
|
System.out.println("success. ");
|
||||||
|
}
|
||||||
|
catch (HarvestingException hex) {
|
||||||
|
System.out.print("failed. ");
|
||||||
|
System.out.println(hex.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
} catch (SQLException se) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
se.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Harvest will not work for an anonymous user
|
||||||
|
EPerson eperson = EPerson.findByEmail(context, email);
|
||||||
|
System.out.println("Harvest started... ");
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
harvester.runHarvest();
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// Not much else we can do at this point
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
System.out.println("Harvest complete. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets harvest_status and harvest_start_time flags for all collections that have a row in the harvested_collections table
|
||||||
|
*/
|
||||||
|
private static void resetHarvesting() {
|
||||||
|
System.out.print("Resetting harvest status flag on all collections... ");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<Integer> cids = HarvestedCollection.findAll(context);
|
||||||
|
for (Integer cid : cids)
|
||||||
|
{
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, cid);
|
||||||
|
//hc.setHarvestResult(null,"");
|
||||||
|
hc.setHarvestStartTime(null);
|
||||||
|
hc.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
|
hc.update();
|
||||||
|
}
|
||||||
|
context.commit();
|
||||||
|
System.out.println("success. ");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
System.out.println("failed. ");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts up the harvest scheduler. Terminating this process will stop the scheduler.
|
||||||
|
*/
|
||||||
|
private static void startHarvester()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
System.out.print("Starting harvest loop... ");
|
||||||
|
OAIHarvester.startNewScheduler();
|
||||||
|
System.out.println("running. ");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -258,9 +258,9 @@ public class Item extends DSpaceObject
|
|||||||
|
|
||||||
// Call update to give the item a last modified date. OK this isn't
|
// Call update to give the item a last modified date. OK this isn't
|
||||||
// amazingly efficient but creates don't happen that often.
|
// amazingly efficient but creates don't happen that often.
|
||||||
context.setIgnoreAuthorization(true);
|
context.turnOffAuthorisationSystem();
|
||||||
i.update();
|
i.update();
|
||||||
context.setIgnoreAuthorization(false);
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
context.addEvent(new Event(Event.CREATE, Constants.ITEM, i.getID(), null));
|
context.addEvent(new Event(Event.CREATE, Constants.ITEM, i.getID(), null));
|
||||||
|
|
||||||
|
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* DIMDisseminationCrosswalk.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-07-30 12:26:50 -0500 (Mon, 30 Jul 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.content.crosswalk;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DCValue;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.packager.PackageDisseminator;
|
||||||
|
import org.dspace.content.packager.PackageException;
|
||||||
|
import org.dspace.content.packager.PackageParameters;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.jdom.output.Format;
|
||||||
|
import org.jdom.output.XMLOutputter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DIM dissemination crosswalk
|
||||||
|
* <p>
|
||||||
|
* Produces the metadata encoded in DSpace Intermediate Format, without the overhead of XSLT processing.
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class DIMDisseminationCrosswalk
|
||||||
|
implements DisseminationCrosswalk
|
||||||
|
{
|
||||||
|
/** log4j category */
|
||||||
|
private static Logger log = Logger.getLogger(OREDisseminationCrosswalk.class);
|
||||||
|
|
||||||
|
// Non-existant XSD schema
|
||||||
|
public static final String DIM_XSD = "null";
|
||||||
|
|
||||||
|
// Namespaces
|
||||||
|
public static final Namespace DIM_NS =
|
||||||
|
Namespace.getNamespace("dim", "http://www.dspace.org/xmlns/dspace/dim");
|
||||||
|
|
||||||
|
private static final Namespace namespaces[] = { DIM_NS };
|
||||||
|
|
||||||
|
private static XMLOutputter outputUgly = new XMLOutputter();
|
||||||
|
private static XMLOutputter outputPretty = new XMLOutputter(Format.getPrettyFormat());
|
||||||
|
private static SAXBuilder builder = new SAXBuilder();
|
||||||
|
|
||||||
|
public Namespace[] getNamespaces()
|
||||||
|
{
|
||||||
|
return namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No schema for DIM */
|
||||||
|
public String getSchemaLocation()
|
||||||
|
{
|
||||||
|
return DIM_NS.getURI() + " " + DIM_XSD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Element disseminateElement(DSpaceObject dso) throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
if (dso.getType() != Constants.ITEM)
|
||||||
|
throw new CrosswalkObjectNotSupported("DIMDisseminationCrosswalk can only crosswalk an Item.");
|
||||||
|
Item item = (Item)dso;
|
||||||
|
|
||||||
|
DCValue[] dc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||||
|
Element dim = new Element("dim", DIM_NS);
|
||||||
|
for (int i = 0; i < dc.length; i++)
|
||||||
|
{
|
||||||
|
Element field = new Element("field", DIM_NS);
|
||||||
|
field.setAttribute("mdschema", dc[i].schema);
|
||||||
|
field.setAttribute("element", dc[i].element);
|
||||||
|
if (dc[i].qualifier != null)
|
||||||
|
field.setAttribute("qualifier", dc[i].qualifier);
|
||||||
|
if (dc[i].language != null)
|
||||||
|
field.setAttribute("lang", dc[i].language);
|
||||||
|
if (dc[i].value != null)
|
||||||
|
field.setText(dc[i].value);
|
||||||
|
dim.addContent(field);
|
||||||
|
}
|
||||||
|
return dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List disseminateList(DSpaceObject dso) throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
List result = new ArrayList(1);
|
||||||
|
result.add(disseminateElement(dso));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only interested in disseminating items at this time */
|
||||||
|
public boolean canDisseminate(DSpaceObject dso)
|
||||||
|
{
|
||||||
|
if (dso.getType() == Constants.ITEM)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean preferList()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* DIMIngestionCrosswalk.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-07-30 12:26:50 -0500 (Mon, 30 Jul 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.content.crosswalk;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DCValue;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.packager.PackageDisseminator;
|
||||||
|
import org.dspace.content.packager.PackageException;
|
||||||
|
import org.dspace.content.packager.PackageParameters;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.jdom.output.Format;
|
||||||
|
import org.jdom.output.XMLOutputter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DIM ingestion crosswalk
|
||||||
|
* <p>
|
||||||
|
* Processes metadata encoded in DSpace Intermediate Format, without the overhead of XSLT processing.
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class DIMIngestionCrosswalk
|
||||||
|
implements IngestionCrosswalk
|
||||||
|
{
|
||||||
|
/** log4j category */
|
||||||
|
private static Logger log = Logger.getLogger(DIMIngestionCrosswalk.class);
|
||||||
|
private static Namespace DIM_NS = Namespace.getNamespace("http://www.dspace.org/xmlns/dspace/dim");
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, List metadata) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
List<Element> elements = metadata;
|
||||||
|
Element wrapper = new Element("wrap",elements.get(0).getNamespace());
|
||||||
|
wrapper.addContent(elements);
|
||||||
|
|
||||||
|
ingest(context,dso,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, Element root) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
if (dso.getType() != Constants.ITEM)
|
||||||
|
throw new CrosswalkObjectNotSupported("DIMIngestionCrosswalk can only crosswalk an Item.");
|
||||||
|
Item item = (Item)dso;
|
||||||
|
|
||||||
|
if (root == null) {
|
||||||
|
System.err.println("The element received by ingest was null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Element> metadata = root.getChildren("field",DIM_NS);
|
||||||
|
for (Element field : metadata) {
|
||||||
|
item.addMetadata(field.getAttributeValue("mdschema"), field.getAttributeValue("element"), field.getAttributeValue("qualifier"),
|
||||||
|
field.getAttributeValue("lang"), field.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* DIMIngestionCrosswalk.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-07-30 12:26:50 -0500 (Mon, 30 Jul 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.content.crosswalk;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DCValue;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.MetadataValue;
|
||||||
|
import org.dspace.content.packager.PackageDisseminator;
|
||||||
|
import org.dspace.content.packager.PackageException;
|
||||||
|
import org.dspace.content.packager.PackageParameters;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.jdom.output.Format;
|
||||||
|
import org.jdom.output.XMLOutputter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DIM ingestion crosswalk
|
||||||
|
* <p>
|
||||||
|
* Processes Dublic Core metadata encased in an oai_dc:dc wrapper
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class OAIDCIngestionCrosswalk
|
||||||
|
implements IngestionCrosswalk
|
||||||
|
{
|
||||||
|
/** log4j category */
|
||||||
|
private static Logger log = Logger.getLogger(OAIDCIngestionCrosswalk.class);
|
||||||
|
private static Namespace DC_NS = Namespace.getNamespace("http://www.dspace.org/xmlns/dspace/dim");
|
||||||
|
private static Namespace OAI_DC_NS = Namespace.getNamespace("http://www.openarchives.org/OAI/2.0/oai_dc/");
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, List metadata) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
List<Element> elements = metadata;
|
||||||
|
Element wrapper = new Element("wrap",elements.get(0).getNamespace());
|
||||||
|
wrapper.addContent(elements);
|
||||||
|
|
||||||
|
ingest(context,dso,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, Element root) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
if (dso.getType() != Constants.ITEM)
|
||||||
|
throw new CrosswalkObjectNotSupported("DIMIngestionCrosswalk can only crosswalk an Item.");
|
||||||
|
Item item = (Item)dso;
|
||||||
|
|
||||||
|
if (root == null) {
|
||||||
|
System.err.println("The element received by ingest was null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Element> metadata = root.getChildren();
|
||||||
|
for (Element element : metadata) {
|
||||||
|
item.addMetadata("dc", element.getName(), null, null, element.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,412 @@
|
|||||||
|
/*
|
||||||
|
* OREDisseminationCrosswalk.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 2108 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-07-30 12:26:50 -0500 (Mon, 30 Jul 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.content.crosswalk;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DCValue;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.packager.PackageDisseminator;
|
||||||
|
import org.dspace.content.packager.PackageException;
|
||||||
|
import org.dspace.content.packager.PackageParameters;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
//import org.dspace.core.Utils;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.jdom.output.Format;
|
||||||
|
import org.jdom.output.XMLOutputter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ORE dissemination crosswalk
|
||||||
|
* <p>
|
||||||
|
* Produces an Atom-encoded ORE aggregation of a DSpace item.
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class OREDisseminationCrosswalk
|
||||||
|
implements DisseminationCrosswalk
|
||||||
|
{
|
||||||
|
/** log4j category */
|
||||||
|
private static Logger log = Logger.getLogger(OREDisseminationCrosswalk.class);
|
||||||
|
|
||||||
|
/* Schema for Atom only available in Relax NG format */
|
||||||
|
public static final String ATOM_RNG = "http://tweety.lanl.gov/public/schemas/2008-06/atom-tron.sch";
|
||||||
|
|
||||||
|
/* Namespaces */
|
||||||
|
public static final Namespace ATOM_NS =
|
||||||
|
Namespace.getNamespace("atom", "http://www.w3.org/2005/Atom");
|
||||||
|
private static final Namespace ORE_NS =
|
||||||
|
Namespace.getNamespace("ore", "http://www.openarchives.org/ore/terms/");
|
||||||
|
private static final Namespace ORE_ATOM =
|
||||||
|
Namespace.getNamespace("oreatom", "http://www.openarchives.org/ore/atom/");
|
||||||
|
private static final Namespace RDF_NS =
|
||||||
|
Namespace.getNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
|
||||||
|
private static final Namespace DCTERMS_NS =
|
||||||
|
Namespace.getNamespace("dcterms", "http://purl.org/dc/terms/");
|
||||||
|
private static final Namespace DS_NS =
|
||||||
|
Namespace.getNamespace("ds","http://www.dspace.org/objectModel/");
|
||||||
|
|
||||||
|
private static final Namespace namespaces[] = { ATOM_NS, ORE_NS, ORE_ATOM, RDF_NS, DCTERMS_NS, DS_NS };
|
||||||
|
|
||||||
|
|
||||||
|
public Namespace[] getNamespaces()
|
||||||
|
{
|
||||||
|
return namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There is (and currently can be) no XSD schema that validates Atom feeds, only RNG */
|
||||||
|
public String getSchemaLocation()
|
||||||
|
{
|
||||||
|
return ATOM_NS.getURI() + " " + ATOM_RNG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disseminate an Atom-encoded ORE ReM mapped from a DSpace Item
|
||||||
|
* @param item
|
||||||
|
* @return
|
||||||
|
* @throws CrosswalkException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
*/
|
||||||
|
private Element disseminateItem(Item item) throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
String oaiUrl = null;
|
||||||
|
String dsUrl = ConfigurationManager.getProperty("dspace.url");
|
||||||
|
|
||||||
|
String remSource = ConfigurationManager.getProperty("ore.authoritative.source");
|
||||||
|
if (remSource == null || remSource.equalsIgnoreCase("oai"))
|
||||||
|
oaiUrl = ConfigurationManager.getProperty("dspace.oai.url");
|
||||||
|
else if (remSource.equalsIgnoreCase("xmlui") || remSource.equalsIgnoreCase("manakin"))
|
||||||
|
oaiUrl = dsUrl;
|
||||||
|
|
||||||
|
if (oaiUrl == null)
|
||||||
|
throw new CrosswalkInternalException("Base uri for the ore generator has not been set. Check the ore.authoritative.source setting.");
|
||||||
|
|
||||||
|
String uriA = oaiUrl + "/metadata/handle/" + item.getHandle() + "/ore.xml";
|
||||||
|
|
||||||
|
// Top level atom feed element
|
||||||
|
Element aggregation = new Element("entry",ATOM_NS);
|
||||||
|
aggregation.addNamespaceDeclaration(ATOM_NS);
|
||||||
|
aggregation.addNamespaceDeclaration(ORE_NS);
|
||||||
|
aggregation.addNamespaceDeclaration(ORE_ATOM);
|
||||||
|
aggregation.addNamespaceDeclaration(DCTERMS_NS);
|
||||||
|
|
||||||
|
// Atom-entry specific info
|
||||||
|
Element atomId = new Element("id",ATOM_NS);
|
||||||
|
atomId.addContent(uriA);
|
||||||
|
aggregation.addContent(atomId);
|
||||||
|
|
||||||
|
Element aggLink;
|
||||||
|
DCValue[] uris = item.getMetadata(MetadataSchema.DC_SCHEMA,"identifier","uri",Item.ANY);
|
||||||
|
for (DCValue uri : uris) {
|
||||||
|
aggLink = new Element("link",ATOM_NS);
|
||||||
|
aggLink.setAttribute("rel", "alternate");
|
||||||
|
aggLink.setAttribute("href", uri.value);
|
||||||
|
aggregation.addContent(aggLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Information about the resource map, as separate entity from the aggregation it describes
|
||||||
|
Element uriALink = new Element("link",ATOM_NS);
|
||||||
|
uriALink.setAttribute("rel", "http://www.openarchives.org/ore/terms/describes");
|
||||||
|
uriALink.setAttribute("href", uriA);
|
||||||
|
|
||||||
|
Element uriRLink = new Element("link",ATOM_NS);
|
||||||
|
uriRLink.setAttribute("rel","self");
|
||||||
|
uriRLink.setAttribute("href", uriA + "#atom");
|
||||||
|
uriRLink.setAttribute("type","application/atom+xml");
|
||||||
|
|
||||||
|
Element remPublished = new Element("published",ATOM_NS);
|
||||||
|
remPublished.addContent(Utils.formatISO8601Date(new Date()));
|
||||||
|
Element remUpdated = new Element("updated",ATOM_NS);
|
||||||
|
remUpdated.addContent(Utils.formatISO8601Date(new Date()));
|
||||||
|
|
||||||
|
Element remCreator = new Element("source",ATOM_NS);
|
||||||
|
Element remGenerator = new Element("generator",ATOM_NS);
|
||||||
|
remGenerator.addContent(ConfigurationManager.getProperty("dspace.name"));
|
||||||
|
remGenerator.setAttribute("uri", oaiUrl);
|
||||||
|
remCreator.addContent(remGenerator);
|
||||||
|
|
||||||
|
aggregation.addContent(uriALink);
|
||||||
|
aggregation.addContent(uriRLink);
|
||||||
|
aggregation.addContent(remPublished);
|
||||||
|
aggregation.addContent(remUpdated);
|
||||||
|
aggregation.addContent(remCreator);
|
||||||
|
|
||||||
|
// Information about the aggregation (item) itself
|
||||||
|
Element aggTitle = new Element("title",ATOM_NS);
|
||||||
|
DCValue[] titles = item.getMetadata(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
|
||||||
|
if (titles != null && titles.length>0)
|
||||||
|
aggTitle.addContent(titles[0].value);
|
||||||
|
else
|
||||||
|
aggTitle.addContent("");
|
||||||
|
aggregation.addContent(aggTitle);
|
||||||
|
|
||||||
|
Element aggAuthor;
|
||||||
|
Element aggAuthorName;
|
||||||
|
DCValue[] authors = item.getMetadata(MetadataSchema.DC_SCHEMA,"contributor","author",Item.ANY);
|
||||||
|
for (DCValue author : authors) {
|
||||||
|
aggAuthor = new Element("author",ATOM_NS);
|
||||||
|
aggAuthorName = new Element("name",ATOM_NS);
|
||||||
|
aggAuthorName.addContent(author.value);
|
||||||
|
aggAuthor.addContent(aggAuthorName);
|
||||||
|
aggregation.addContent(aggAuthor);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element oreCategory = new Element("category",ATOM_NS);
|
||||||
|
oreCategory.setAttribute("scheme", ORE_NS.getURI());
|
||||||
|
oreCategory.setAttribute("term", ORE_NS.getURI()+"Aggregation");
|
||||||
|
oreCategory.setAttribute("label","Aggregation");
|
||||||
|
|
||||||
|
Element updateCategory = new Element("category",ATOM_NS);
|
||||||
|
updateCategory.setAttribute("scheme", ORE_ATOM.getURI()+"modified");
|
||||||
|
updateCategory.setAttribute("term", Utils.formatISO8601Date(item.getLastModified()));
|
||||||
|
|
||||||
|
Element dsCategory = new Element("category",ATOM_NS);
|
||||||
|
dsCategory.setAttribute("scheme", DS_NS.getURI());
|
||||||
|
dsCategory.setAttribute("term", "DSpaceItem");
|
||||||
|
dsCategory.setAttribute("label", "DSpace Item");
|
||||||
|
|
||||||
|
aggregation.addContent(oreCategory);
|
||||||
|
aggregation.addContent(updateCategory);
|
||||||
|
aggregation.addContent(dsCategory);
|
||||||
|
|
||||||
|
|
||||||
|
// metadata section
|
||||||
|
Element arLink;
|
||||||
|
Element rdfDescription, rdfType, dcModified, dcDesc;
|
||||||
|
Element triples = new Element("triples", ORE_ATOM);
|
||||||
|
|
||||||
|
// metadata about the item
|
||||||
|
rdfDescription = new Element("Description", RDF_NS);
|
||||||
|
rdfDescription.setAttribute("about", uriA, RDF_NS);
|
||||||
|
|
||||||
|
rdfType = new Element("type", RDF_NS);
|
||||||
|
rdfType.setAttribute("resource", DS_NS.getURI()+"DSpaceItem", RDF_NS);
|
||||||
|
dcModified = new Element("modified", DCTERMS_NS);
|
||||||
|
dcModified.addContent(Utils.formatISO8601Date(item.getLastModified()));
|
||||||
|
|
||||||
|
rdfDescription.addContent(rdfType);
|
||||||
|
rdfDescription.addContent(dcModified);
|
||||||
|
triples.addContent(rdfDescription);
|
||||||
|
|
||||||
|
// Add a link and an oreatom metadata entry for each bitstream in the item
|
||||||
|
Bundle[] bundles = item.getBundles();
|
||||||
|
Bitstream[] bitstreams;
|
||||||
|
for (Bundle bundle : bundles)
|
||||||
|
{
|
||||||
|
// Omit the special "ORE" bitstream
|
||||||
|
if (bundle.getName().equals("ORE"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bitstreams = bundle.getBitstreams();
|
||||||
|
for (Bitstream bs : bitstreams)
|
||||||
|
{
|
||||||
|
arLink = new Element("link",ATOM_NS);
|
||||||
|
arLink.setAttribute("rel", ORE_NS.getURI()+"aggregates");
|
||||||
|
arLink.setAttribute("href",dsUrl + "/bitstream/handle/" + item.getHandle() + "/" + URLencode(bs.getName()) + "?sequence=" + bs.getSequenceID());
|
||||||
|
arLink.setAttribute("title",bs.getName());
|
||||||
|
arLink.setAttribute("type",bs.getFormat().getMIMEType());
|
||||||
|
arLink.setAttribute("length",Long.toString(bs.getSize()));
|
||||||
|
|
||||||
|
aggregation.addContent(arLink);
|
||||||
|
|
||||||
|
// metadata about the bitstream
|
||||||
|
rdfDescription = new Element("Description", RDF_NS);
|
||||||
|
rdfDescription.setAttribute("about", dsUrl + "/bitstream/handle/" + item.getHandle() + "/" + URLencode(bs.getName()) + "?sequence=" + bs.getSequenceID(), RDF_NS);
|
||||||
|
|
||||||
|
rdfType = new Element("type", RDF_NS);
|
||||||
|
rdfType.setAttribute("resource", DS_NS.getURI()+"DSpaceBitstream", RDF_NS);
|
||||||
|
dcDesc = new Element("description", DCTERMS_NS);
|
||||||
|
dcDesc.addContent(bundle.getName());
|
||||||
|
|
||||||
|
rdfDescription.addContent(rdfType);
|
||||||
|
rdfDescription.addContent(dcDesc);
|
||||||
|
triples.addContent(rdfDescription);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aggregation.addContent(triples);
|
||||||
|
|
||||||
|
// Add a link to the OAI-PMH served metadata (oai_dc is always on)
|
||||||
|
/*
|
||||||
|
Element pmhMeta = new Element("entry",ATOM_NS);
|
||||||
|
|
||||||
|
pUri = new Element("id",ATOM_NS);
|
||||||
|
String oaiId = new String("oai:" + ConfigurationManager.getProperty("dspace.hostname") + ":" + item.getHandle());
|
||||||
|
pUri.addContent(oaiId + "#oai_dc");
|
||||||
|
pmhMeta.addContent(pUri);
|
||||||
|
|
||||||
|
Element pmhAuthor = new Element("author",ATOM_NS);
|
||||||
|
Element pmhAuthorName = new Element("name",ATOM_NS);
|
||||||
|
Element pmhAuthorUri = new Element("uri",ATOM_NS);
|
||||||
|
pmhAuthorName.addContent(ConfigurationManager.getProperty("dspace.name"));
|
||||||
|
pmhAuthorUri.addContent(oaiUrl);
|
||||||
|
pmhAuthor.addContent(pmhAuthorName);
|
||||||
|
pmhAuthor.addContent(pmhAuthorUri);
|
||||||
|
pmhMeta.addContent(pmhAuthor);
|
||||||
|
|
||||||
|
arUri = new Element("link",ATOM_NS);
|
||||||
|
arUri.setAttribute("rel","alternate");
|
||||||
|
arUri.setAttribute("href",oaiUrl + "/request?verb=GetRecord&identifier=" + oaiId + "&metadataprefix=oai_dc");
|
||||||
|
pmhMeta.addContent(arUri);
|
||||||
|
|
||||||
|
Element rdfDesc = new Element("Description",RDF_NS);
|
||||||
|
rdfDesc.setAttribute("about",oaiUrl + "/request?verb=GetRecord&identifier=" + oaiId + "&metadataprefix=oai_dc",RDF_NS);
|
||||||
|
Element dcTerms = new Element("dcterms",DCTERMS_NS);
|
||||||
|
dcTerms.setAttribute("resource","http://www.openarchives.org/OAI/2.0/oai_dc/",RDF_NS);
|
||||||
|
rdfDesc.addContent(dcTerms);
|
||||||
|
pmhMeta.addContent(rdfDesc);
|
||||||
|
|
||||||
|
arUpdated = new Element("updated",ATOM_NS);
|
||||||
|
arUpdated.addContent(Utils.formatISO8601Date(item.getLastModified()));
|
||||||
|
pmhMeta.addContent(arUpdated);
|
||||||
|
|
||||||
|
arTitle = new Element("title",ATOM_NS);
|
||||||
|
arTitle.addContent("");
|
||||||
|
pmhMeta.addContent(arTitle);
|
||||||
|
|
||||||
|
aggregation.addContent(pmhMeta);*/
|
||||||
|
|
||||||
|
return aggregation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element disseminateElement(DSpaceObject dso) throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
switch(dso.getType()) {
|
||||||
|
case Constants.ITEM: return disseminateItem((Item)dso);
|
||||||
|
case Constants.COLLECTION: break;
|
||||||
|
case Constants.COMMUNITY: break;
|
||||||
|
default: throw new CrosswalkObjectNotSupported("ORE implementation unable to disseminate unknown DSpace object.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to escape all chaacters that are not part of the canon set
|
||||||
|
* @param sourceString source unescaped string
|
||||||
|
*/
|
||||||
|
private String URLencode(String sourceString) {
|
||||||
|
Character lowalpha[] = {'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' ,
|
||||||
|
'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' ,
|
||||||
|
's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z'};
|
||||||
|
Character upalpha[] = {'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' ,
|
||||||
|
'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' ,
|
||||||
|
'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z'};
|
||||||
|
Character digit[] = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'};
|
||||||
|
Character mark[] = {'-' , '_' , '.' , '!' , '~' , '*' , '\'' , '(' , ')'};
|
||||||
|
|
||||||
|
// reserved
|
||||||
|
//Character reserved[] = {';' , '/' , '?' , ':' , '@' , '&' , '=' , '+' , '$' , ',' ,'%', '#'};
|
||||||
|
|
||||||
|
Set<Character> URLcharsSet = new HashSet<Character>();
|
||||||
|
URLcharsSet.addAll(Arrays.asList(lowalpha));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(upalpha));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(digit));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(mark));
|
||||||
|
//URLcharsSet.addAll(Arrays.asList(reserved));
|
||||||
|
|
||||||
|
String processedString = new String();
|
||||||
|
for (int i=0; i<sourceString.length(); i++) {
|
||||||
|
char ch = sourceString.charAt(i);
|
||||||
|
if (URLcharsSet.contains(ch)) {
|
||||||
|
processedString += ch;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
processedString += "%" + Integer.toHexString((int)ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List disseminateList(DSpaceObject dso) throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
List result = new ArrayList(1);
|
||||||
|
result.add(disseminateElement(dso));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only interested in disseminating items at this time */
|
||||||
|
public boolean canDisseminate(DSpaceObject dso)
|
||||||
|
{
|
||||||
|
if (dso.getType() == Constants.ITEM || dso.getType() == Constants.COLLECTION || dso.getType() == Constants.COMMUNITY)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean preferList()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
* OREIngestionCrosswalk.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2007-07-30 12:26:50 -0500 (Mon, 30 Jul 2007) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.content.crosswalk;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.ConnectException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.BitstreamFormat;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DCValue;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.FormatIdentifier;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.MetadataSchema;
|
||||||
|
import org.dspace.content.packager.PackageDisseminator;
|
||||||
|
import org.dspace.content.packager.PackageException;
|
||||||
|
import org.dspace.content.packager.PackageParameters;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Utils;
|
||||||
|
import org.jdom.Attribute;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.Namespace;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.jdom.output.Format;
|
||||||
|
import org.jdom.output.XMLOutputter;
|
||||||
|
import org.jdom.xpath.XPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ORE ingestion crosswalk
|
||||||
|
* <p>
|
||||||
|
* Processes an Atom-encoded ORE resource map and attemps to interpret it as a DSpace item
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class OREIngestionCrosswalk
|
||||||
|
implements IngestionCrosswalk
|
||||||
|
{
|
||||||
|
/** log4j category */
|
||||||
|
private static Logger log = Logger.getLogger(OREDisseminationCrosswalk.class);
|
||||||
|
|
||||||
|
/* Namespaces */
|
||||||
|
public static final Namespace ATOM_NS =
|
||||||
|
Namespace.getNamespace("atom", "http://www.w3.org/2005/Atom");
|
||||||
|
private static final Namespace ORE_ATOM =
|
||||||
|
Namespace.getNamespace("oreatom", "http://www.openarchives.org/ore/atom/");
|
||||||
|
private static final Namespace ORE_NS =
|
||||||
|
Namespace.getNamespace("ore", "http://www.openarchives.org/ore/terms/");
|
||||||
|
private static final Namespace RDF_NS =
|
||||||
|
Namespace.getNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
|
||||||
|
private static final Namespace DCTERMS_NS =
|
||||||
|
Namespace.getNamespace("dcterms", "http://purl.org/dc/terms/");
|
||||||
|
private static final Namespace DS_NS =
|
||||||
|
Namespace.getNamespace("ds","http://www.dspace.org/objectModel/");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, List metadata) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
// If this list contains only the root already, just pass it on
|
||||||
|
List<Element> elements = metadata;
|
||||||
|
if (elements.size() == 1) {
|
||||||
|
ingest(context, dso, elements.get(0));
|
||||||
|
}
|
||||||
|
// Otherwise, wrap them up
|
||||||
|
else {
|
||||||
|
Element wrapper = new Element("wrap",elements.get(0).getNamespace());
|
||||||
|
wrapper.addContent(elements);
|
||||||
|
|
||||||
|
ingest(context,dso,wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void ingest(Context context, DSpaceObject dso, Element root) throws CrosswalkException, IOException, SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
Date timeStart = new Date();
|
||||||
|
|
||||||
|
if (dso.getType() != Constants.ITEM)
|
||||||
|
throw new CrosswalkObjectNotSupported("OREIngestionCrosswalk can only crosswalk an Item.");
|
||||||
|
Item item = (Item)dso;
|
||||||
|
|
||||||
|
if (root == null) {
|
||||||
|
System.err.println("The element received by ingest was null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc = new Document();
|
||||||
|
doc.addContent(root.detach());
|
||||||
|
|
||||||
|
XPath xpathLinks;
|
||||||
|
List<Element> aggregatedResources;
|
||||||
|
String entryId;
|
||||||
|
try {
|
||||||
|
xpathLinks = XPath.newInstance("/atom:entry/atom:link[@rel=\"" + ORE_NS.getURI()+"aggregates" + "\"]");
|
||||||
|
xpathLinks.addNamespace(ATOM_NS);
|
||||||
|
aggregatedResources = xpathLinks.selectNodes(doc);
|
||||||
|
|
||||||
|
xpathLinks = XPath.newInstance("/atom:entry/atom:link[@rel='alternate']/@href");
|
||||||
|
xpathLinks.addNamespace(ATOM_NS);
|
||||||
|
entryId = ((Attribute)xpathLinks.selectSingleNode(doc)).getValue();
|
||||||
|
} catch (JDOMException e) {
|
||||||
|
throw new CrosswalkException("JDOM exception occured while ingesting the ORE");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next for each resource, create a bitstream
|
||||||
|
XPath xpathDesc;
|
||||||
|
NumberFormat nf=NumberFormat.getInstance();
|
||||||
|
nf.setGroupingUsed(false);
|
||||||
|
nf.setMinimumIntegerDigits(4);
|
||||||
|
|
||||||
|
int countInt=0;
|
||||||
|
String count;
|
||||||
|
for (Element resource : aggregatedResources)
|
||||||
|
{
|
||||||
|
countInt++;
|
||||||
|
count = nf.format((long)countInt);
|
||||||
|
String href = resource.getAttributeValue("href");
|
||||||
|
log.debug("ORE processing: " + href);
|
||||||
|
|
||||||
|
String bundleName;
|
||||||
|
Element desc = null;
|
||||||
|
try {
|
||||||
|
xpathDesc = XPath.newInstance("/atom:entry/oreatom:triples/rdf:Description[@rdf:about=\"" + this.URLencode(href) + "\"][1]");
|
||||||
|
xpathDesc.addNamespace(ATOM_NS);
|
||||||
|
xpathDesc.addNamespace(ORE_ATOM);
|
||||||
|
xpathDesc.addNamespace(RDF_NS);
|
||||||
|
desc = (Element)xpathDesc.selectSingleNode(doc);
|
||||||
|
} catch (JDOMException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc != null && desc.getChild("type", RDF_NS).getAttributeValue("resource", RDF_NS).equals(DS_NS.getURI() + "DSpaceBitstream"))
|
||||||
|
{
|
||||||
|
bundleName = desc.getChildText("description", DCTERMS_NS);
|
||||||
|
log.debug("Setting bundle name to: " + bundleName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.info("Could not obtain bundle name; using 'ORIGINAL'");
|
||||||
|
bundleName = "ORIGINAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bundle names are not unique, so we just pick the first one if there's more than one.
|
||||||
|
Bundle[] targetBundles = item.getBundles(bundleName);
|
||||||
|
Bundle targetBundle;
|
||||||
|
|
||||||
|
// if null, create the new bundle and add it in
|
||||||
|
if (targetBundles.length == 0) {
|
||||||
|
targetBundle = item.createBundle(bundleName);
|
||||||
|
item.addBundle(targetBundle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
targetBundle = targetBundles[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
URL ARurl = null;
|
||||||
|
InputStream in = null;
|
||||||
|
if (href != null) {
|
||||||
|
try {
|
||||||
|
// Make sure the url string escapes all the oddball characters
|
||||||
|
String processedURL = URLencode(href);
|
||||||
|
// Generate a requeset for the aggregated resource
|
||||||
|
ARurl = new URL(processedURL);
|
||||||
|
in = ARurl.openStream();
|
||||||
|
}
|
||||||
|
catch(FileNotFoundException fe) {
|
||||||
|
log.error("The provided URI failed to return a resource: " + href);
|
||||||
|
}
|
||||||
|
catch(ConnectException fe) {
|
||||||
|
log.error("The provided URI was invalid: " + href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CrosswalkException("Entry did not contain link to resource: " + entryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ingest and update
|
||||||
|
if (in != null) {
|
||||||
|
Bitstream newBitstream = targetBundle.createBitstream(in);
|
||||||
|
|
||||||
|
String bsName = resource.getAttributeValue("title");
|
||||||
|
newBitstream.setName(bsName);
|
||||||
|
|
||||||
|
// Identify the format
|
||||||
|
String mimeString = resource.getAttributeValue("type");
|
||||||
|
BitstreamFormat bsFormat = BitstreamFormat.findByMIMEType(context, mimeString);
|
||||||
|
if (bsFormat == null) {
|
||||||
|
bsFormat = FormatIdentifier.guessFormat(context, newBitstream);
|
||||||
|
}
|
||||||
|
newBitstream.setFormat(bsFormat);
|
||||||
|
newBitstream.update();
|
||||||
|
|
||||||
|
targetBundle.addBitstream(newBitstream);
|
||||||
|
targetBundle.update();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CrosswalkException("Could not retrieve bitstream: " + entryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
log.info("OREIngest for Item "+ item.getID() + " took: " + (new Date().getTime() - timeStart.getTime()) + "ms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to escape all chaacters that are not part of the canon set
|
||||||
|
* @param sourceString source unescaped string
|
||||||
|
*/
|
||||||
|
private String URLencode(String sourceString) {
|
||||||
|
Character lowalpha[] = {'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' ,
|
||||||
|
'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' ,
|
||||||
|
's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z'};
|
||||||
|
Character upalpha[] = {'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' ,
|
||||||
|
'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' ,
|
||||||
|
'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z'};
|
||||||
|
Character digit[] = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'};
|
||||||
|
Character mark[] = {'-' , '_' , '.' , '!' , '~' , '*' , '\'' , '(' , ')'};
|
||||||
|
|
||||||
|
// reserved
|
||||||
|
Character reserved[] = {';' , '/' , '?' , ':' , '@' , '&' , '=' , '+' , '$' , ',' ,'%', '#'};
|
||||||
|
|
||||||
|
Set<Character> URLcharsSet = new HashSet<Character>();
|
||||||
|
URLcharsSet.addAll(Arrays.asList(lowalpha));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(upalpha));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(digit));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(mark));
|
||||||
|
URLcharsSet.addAll(Arrays.asList(reserved));
|
||||||
|
|
||||||
|
String processedString = new String();
|
||||||
|
for (int i=0; i<sourceString.length(); i++) {
|
||||||
|
char ch = sourceString.charAt(i);
|
||||||
|
if (URLcharsSet.contains(ch)) {
|
||||||
|
processedString += ch;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
processedString += "%" + Integer.toHexString((int)ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
144
dspace-api/src/main/java/org/dspace/harvest/HarvestConsumer.java
Normal file
144
dspace-api/src/main/java/org/dspace/harvest/HarvestConsumer.java
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* HarvestConsumer.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 3705 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2009-04-11 12:02:24 -0500 (Sat, 11 Apr 2009) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2007, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.harvest;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.*;
|
||||||
|
import org.dspace.event.Consumer;
|
||||||
|
import org.dspace.event.Event;
|
||||||
|
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for handling cleanup of harvest settings for collections and items
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @version $Revision: 3705 $
|
||||||
|
*
|
||||||
|
* @author Stuart Lewis
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class HarvestConsumer implements Consumer
|
||||||
|
{
|
||||||
|
/** log4j logger */
|
||||||
|
private static Logger log = Logger.getLogger(HarvestConsumer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initalise the consumer
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void initialize()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consume the event
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param event
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void consume(Context context, Event event)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
int st = event.getSubjectType();
|
||||||
|
int et = event.getEventType();
|
||||||
|
int id = event.getSubjectID();
|
||||||
|
|
||||||
|
switch (st)
|
||||||
|
{
|
||||||
|
case Constants.ITEM:
|
||||||
|
if (et == Event.DELETE)
|
||||||
|
{
|
||||||
|
HarvestedItem hi = HarvestedItem.find(context, id);
|
||||||
|
if (hi != null) {
|
||||||
|
log.debug("Deleted item '" + id + "', also deleting associated harvested_item '" + hi.getOaiID() + "'.");
|
||||||
|
hi.delete();
|
||||||
|
hi.update();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log.debug("Deleted item '" + id + "' and the associated harvested_item.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Constants.COLLECTION:
|
||||||
|
if (et == Event.DELETE)
|
||||||
|
{
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, id);
|
||||||
|
if (hc != null) {
|
||||||
|
log.debug("Deleted collection '" + id + "', also deleting associated harvested_collection '" + hc.getOaiSource() + ":" + hc.getOaiSetId() + "'.");
|
||||||
|
hc.delete();
|
||||||
|
hc.update();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log.debug("Deleted collection '" + id + "' and the associated harvested_collection.");
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.warn("consume() got unrecognized event: " + event.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the end of the event
|
||||||
|
*
|
||||||
|
* @param ctx
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void end(Context ctx)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish the event
|
||||||
|
*
|
||||||
|
* @param ctx
|
||||||
|
*/
|
||||||
|
public void finish(Context ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,434 @@
|
|||||||
|
package org.dspace.harvest;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HarvestedCollection.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1.0 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2008/01/01 04:11:09 $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2007, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.storage.rdbms.DatabaseManager;
|
||||||
|
import org.dspace.storage.rdbms.TableRowIterator;
|
||||||
|
import org.dspace.storage.rdbms.TableRow;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class HarvestedCollection
|
||||||
|
{
|
||||||
|
private Context context;
|
||||||
|
private TableRow harvestRow;
|
||||||
|
boolean modified;
|
||||||
|
|
||||||
|
public static final int TYPE_NONE = 0;
|
||||||
|
public static final int TYPE_DMD = 1;
|
||||||
|
public static final int TYPE_DMDREF = 2;
|
||||||
|
public static final int TYPE_FULL = 3;
|
||||||
|
|
||||||
|
public static final int STATUS_READY = 0;
|
||||||
|
public static final int STATUS_BUSY = 1;
|
||||||
|
public static final int STATUS_QUEUED = 2;
|
||||||
|
public static final int STATUS_OAI_ERROR = 3;
|
||||||
|
public static final int STATUS_UNKNOWN_ERROR = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* collection_id | integer | not null
|
||||||
|
harvest_type | integer |
|
||||||
|
oai_source | text |
|
||||||
|
oai_set_id | text |
|
||||||
|
harvest_message | text |
|
||||||
|
metadata_config_id | text |
|
||||||
|
harvest_status | integer |
|
||||||
|
harvest_start_time | timestamp with time zone |
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: make sure this guy knows to lock people out if the status is not zero.
|
||||||
|
// i.e. someone editing a collection's setting from the admin menu should have
|
||||||
|
// to stop an ongoing harvest before they can edit the settings.
|
||||||
|
|
||||||
|
|
||||||
|
HarvestedCollection(Context c, TableRow row)
|
||||||
|
{
|
||||||
|
context = c;
|
||||||
|
harvestRow = row;
|
||||||
|
modified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void exists(Context c) throws SQLException {
|
||||||
|
DatabaseManager.queryTable(c, "harvested_collection", "SELECT COUNT(*) FROM harvested_collection");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the harvest settings corresponding to this collection
|
||||||
|
* @return a HarvestInstance object corresponding to this collection's settings, null if not found.
|
||||||
|
*/
|
||||||
|
public static HarvestedCollection find(Context c, int collectionId) throws SQLException
|
||||||
|
{
|
||||||
|
TableRow row = DatabaseManager.findByUnique(c, "harvested_collection", "collection_id", collectionId);
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HarvestedCollection(c, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new harvest instance row for a specified collection.
|
||||||
|
* @return a new HarvestInstance object
|
||||||
|
*/
|
||||||
|
public static HarvestedCollection create(Context c, int collectionId) throws SQLException {
|
||||||
|
TableRow row = DatabaseManager.create(c, "harvested_collection");
|
||||||
|
row.setColumn("collection_id", collectionId);
|
||||||
|
row.setColumn("harvest_type", 0);
|
||||||
|
DatabaseManager.update(c, row);
|
||||||
|
|
||||||
|
return new HarvestedCollection(c, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the specified collection is harvestable, i.e. whether its harvesting
|
||||||
|
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||||
|
* be in process of being harvested.
|
||||||
|
*/
|
||||||
|
public static boolean isHarvestable(Context c, int collectionId) throws SQLException
|
||||||
|
{
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||||
|
if (hc != null && hc.getHarvestType() > 0 && hc.getOaiSource() != null && hc.getOaiSetId() != null &&
|
||||||
|
hc.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether this harvest instance is actually harvestable, i.e. whether its settings
|
||||||
|
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||||
|
* be in process of being harvested.
|
||||||
|
*/
|
||||||
|
public boolean isHarvestable() throws SQLException
|
||||||
|
{
|
||||||
|
if (this.getHarvestType() > 0 && this.getOaiSource() != null && this.getOaiSetId() != null &&
|
||||||
|
this.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the specified collection is ready for immediate harvest.
|
||||||
|
*/
|
||||||
|
public static boolean isReady(Context c, int collectionId) throws SQLException
|
||||||
|
{
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||||
|
return hc.isReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReady() throws SQLException
|
||||||
|
{
|
||||||
|
if (this.isHarvestable() && (this.getHarvestStatus() == HarvestedCollection.STATUS_READY || this.getHarvestStatus() == HarvestedCollection.STATUS_OAI_ERROR))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Find all collections that are set up for harvesting
|
||||||
|
*
|
||||||
|
* return: list of collection id's
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static List<Integer> findAll(Context c) throws SQLException
|
||||||
|
{
|
||||||
|
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||||
|
"SELECT * FROM harvested_collection");
|
||||||
|
|
||||||
|
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||||
|
while (tri.hasNext())
|
||||||
|
{
|
||||||
|
TableRow row = tri.next();
|
||||||
|
collectionIds.add(row.getIntColumn("collection_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find all collections that are ready for harvesting
|
||||||
|
*
|
||||||
|
* return: list of collection id's
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static List<Integer> findReady(Context c) throws SQLException
|
||||||
|
{
|
||||||
|
int harvestInterval = ConfigurationManager.getIntProperty("harvester.harvestFrequency");
|
||||||
|
if (harvestInterval == 0) harvestInterval = 720;
|
||||||
|
|
||||||
|
int expirationInterval = ConfigurationManager.getIntProperty("harvester.threadTimeout");
|
||||||
|
if (expirationInterval == 0) expirationInterval = 24;
|
||||||
|
|
||||||
|
Date startTime;
|
||||||
|
Date expirationTime;
|
||||||
|
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(new Date());
|
||||||
|
calendar.add(Calendar.MINUTE, -1 * harvestInterval);
|
||||||
|
startTime = calendar.getTime();
|
||||||
|
|
||||||
|
calendar.setTime(startTime);
|
||||||
|
calendar.add(Calendar.HOUR, -2 * expirationInterval);
|
||||||
|
expirationTime = calendar.getTime();
|
||||||
|
|
||||||
|
/* Select all collections whose last_harvest is before our start time, whose harvest_type *is not* 0 and whose status *is* 0 (available) or 3 (OAI Error). */
|
||||||
|
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||||
|
"SELECT * FROM harvested_collection WHERE (last_harvested < ? or last_harvested is null) and harvest_type > ? and (harvest_status = ? or harvest_status = ? or (harvest_status=? and harvest_start_time < ?)) ORDER BY last_harvested",
|
||||||
|
new java.sql.Timestamp(startTime.getTime()), 0, HarvestedCollection.STATUS_READY, HarvestedCollection.STATUS_OAI_ERROR, HarvestedCollection.STATUS_BUSY, new java.sql.Timestamp(expirationTime.getTime()));
|
||||||
|
|
||||||
|
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
while (tri.hasNext())
|
||||||
|
{
|
||||||
|
TableRow row = tri.next();
|
||||||
|
collectionIds.add(row.getIntColumn("collection_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all collections with the specified status flag
|
||||||
|
* @param c
|
||||||
|
* @param status, see HarvestInstance.STATUS_...
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static List<Integer> findByStatus(Context c, int status) throws SQLException {
|
||||||
|
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||||
|
"SELECT * FROM harvested_collection WHERE harvest_status = ?", status);
|
||||||
|
|
||||||
|
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||||
|
while (tri.hasNext())
|
||||||
|
{
|
||||||
|
TableRow row = tri.next();
|
||||||
|
collectionIds.add(row.getIntColumn("collection_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Find the collection that was harvested the longest time ago.
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static Integer findOldestHarvest (Context c) throws SQLException {
|
||||||
|
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||||
|
"select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested asc limit 1", 0, 0);
|
||||||
|
TableRow row = tri.next();
|
||||||
|
|
||||||
|
if (row != null)
|
||||||
|
return row.getIntColumn("collection_id");
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find the collection that was harvested most recently.
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static Integer findNewestHarvest (Context c) throws SQLException {
|
||||||
|
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||||
|
"select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested desc limit 1", 0, 0);
|
||||||
|
TableRow row = tri.next();
|
||||||
|
|
||||||
|
if (row != null)
|
||||||
|
return row.getIntColumn("collection_id");
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to set all harvesting-related parameters at once
|
||||||
|
*/
|
||||||
|
public void setHarvestParams(int type, String oaiSource, String oaiSetId, String mdConfigId) {
|
||||||
|
setHarvestType(type);
|
||||||
|
setOaiSource(oaiSource);
|
||||||
|
setOaiSetId(oaiSetId);
|
||||||
|
setHarvestMetadataConfig(mdConfigId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setters for the appropriate harverting-related columns */
|
||||||
|
public void setHarvestType(int type) {
|
||||||
|
harvestRow.setColumn("harvest_type",type);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current status of the collection.
|
||||||
|
*
|
||||||
|
* @param status a HarvestInstance.STATUS_... constant
|
||||||
|
*/
|
||||||
|
public void setHarvestStatus(int status) {
|
||||||
|
harvestRow.setColumn("harvest_status",status);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOaiSource(String oaiSource) {
|
||||||
|
if (oaiSource == null || oaiSource.length() == 0) {
|
||||||
|
harvestRow.setColumnNull("oai_source");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
harvestRow.setColumn("oai_source",oaiSource);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOaiSetId(String oaiSetId) {
|
||||||
|
if (oaiSetId == null || oaiSetId.length() == 0) {
|
||||||
|
harvestRow.setColumnNull("oai_set_id");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
harvestRow.setColumn("oai_set_id",oaiSetId);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestMetadataConfig(String mdConfigId) {
|
||||||
|
if (mdConfigId == null || mdConfigId.length() == 0) {
|
||||||
|
harvestRow.setColumnNull("metadata_config_id");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
harvestRow.setColumn("metadata_config_id",mdConfigId);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestResult(Date date, String message) {
|
||||||
|
if (date == null) {
|
||||||
|
harvestRow.setColumnNull("last_harvested");
|
||||||
|
} else {
|
||||||
|
harvestRow.setColumn("last_harvested", date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == null || message.length() == 0) {
|
||||||
|
harvestRow.setColumnNull("harvest_message");
|
||||||
|
} else {
|
||||||
|
harvestRow.setColumn("harvest_message", message);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestMessage(String message) {
|
||||||
|
if (message == null || message.length() == 0) {
|
||||||
|
harvestRow.setColumnNull("harvest_message");
|
||||||
|
} else {
|
||||||
|
harvestRow.setColumn("harvest_message", message);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHarvestStartTime(Date date) {
|
||||||
|
if (date == null) {
|
||||||
|
harvestRow.setColumnNull("harvest_start_time");
|
||||||
|
} else {
|
||||||
|
harvestRow.setColumn("harvest_start_time", date);
|
||||||
|
}
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getting for the appropriate harverting-related columns */
|
||||||
|
public int getCollectionId() {
|
||||||
|
return harvestRow.getIntColumn("collection_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHarvestType() {
|
||||||
|
return harvestRow.getIntColumn("harvest_type");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHarvestStatus() {
|
||||||
|
return harvestRow.getIntColumn("harvest_status");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOaiSource() {
|
||||||
|
return harvestRow.getStringColumn("oai_source");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOaiSetId() {
|
||||||
|
return harvestRow.getStringColumn("oai_set_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHarvestMetadataConfig() {
|
||||||
|
return harvestRow.getStringColumn("metadata_config_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHarvestMessage() {
|
||||||
|
return harvestRow.getStringColumn("harvest_message");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getHarvestDate() {
|
||||||
|
return harvestRow.getDateColumn("last_harvested");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getHarvestStartTime() {
|
||||||
|
return harvestRow.getDateColumn("harvest_start_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void delete() throws SQLException {
|
||||||
|
DatabaseManager.delete(context, harvestRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() throws SQLException, IOException, AuthorizeException
|
||||||
|
{
|
||||||
|
DatabaseManager.update(context, harvestRow);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
203
dspace-api/src/main/java/org/dspace/harvest/HarvestedItem.java
Normal file
203
dspace-api/src/main/java/org/dspace/harvest/HarvestedItem.java
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* Item.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 4196 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2009-08-06 08:29:46 -0500 (Thu, 06 Aug 2009) $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2009, The DSpace Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the DSpace Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.harvest;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.storage.rdbms.DatabaseManager;
|
||||||
|
import org.dspace.storage.rdbms.TableRow;
|
||||||
|
import org.dspace.storage.rdbms.TableRowIterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class HarvestedItem
|
||||||
|
{
|
||||||
|
private Context context;
|
||||||
|
private TableRow harvestRow;
|
||||||
|
boolean modified;
|
||||||
|
|
||||||
|
|
||||||
|
HarvestedItem(Context c, TableRow row)
|
||||||
|
{
|
||||||
|
context = c;
|
||||||
|
harvestRow = row;
|
||||||
|
modified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void exists(Context c) throws SQLException {
|
||||||
|
DatabaseManager.queryTable(c, "harvested_item", "SELECT COUNT(*) FROM harvested_item");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the harvest parameters corresponding to the specified DSpace item
|
||||||
|
* @return a HarvestedItem object corresponding to this item, null if not found.
|
||||||
|
*/
|
||||||
|
public static HarvestedItem find(Context c, int item_id) throws SQLException
|
||||||
|
{
|
||||||
|
TableRow row = DatabaseManager.findByUnique(c, "harvested_item", "item_id", item_id);
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HarvestedItem(c, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* select foo.item_id from (select item.item_id, item.owning_collection from item join item2bundle on item.item_id=item2bundle.item_id where item2bundle.bundle_id=22) as foo join collection on foo.owning_collection=collection.collection_id where collection.collection_id=5;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a DSpace Item that corresponds to this particular combination of owning collection and OAI ID.
|
||||||
|
* @param context
|
||||||
|
* @param itemOaiID the string used by the OAI-PMH provider to identify the item
|
||||||
|
* @param collectionID id of the local collection that the item should be found in
|
||||||
|
* @return DSpace Item or null if no item was found
|
||||||
|
*/
|
||||||
|
public static Item getItemByOAIId(Context context, String itemOaiID, int collectionID) throws SQLException
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* FYI: This method has to be scoped to a collection. Otherwise, we could have collisions as more
|
||||||
|
* than one collection might be importing the same item. That is OAI_ID's might be unique to the
|
||||||
|
* provider but not to the harvester.
|
||||||
|
*/
|
||||||
|
Item resolvedItem = null;
|
||||||
|
TableRowIterator tri = null;
|
||||||
|
final String selectItemFromOaiId = "SELECT dsi.item_id FROM " +
|
||||||
|
"(SELECT item.item_id, item.owning_collection FROM item JOIN harvested_item ON item.item_id=harvested_item.item_id WHERE harvested_item.oai_id=?) " +
|
||||||
|
"AS dsi JOIN collection ON dsi.owning_collection=collection.collection_id WHERE collection.collection_id=?";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tri = DatabaseManager.query(context, selectItemFromOaiId, itemOaiID, collectionID);
|
||||||
|
|
||||||
|
if (tri.hasNext())
|
||||||
|
{
|
||||||
|
TableRow row = tri.next();
|
||||||
|
int itemID = row.getIntColumn("item_id");
|
||||||
|
resolvedItem = Item.find(context, itemID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (tri != null)
|
||||||
|
tri.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolvedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new harvested item row for a specified item id.
|
||||||
|
* @return a new HarvestedItem object
|
||||||
|
*/
|
||||||
|
public static HarvestedItem create(Context c, int itemId, String itemOAIid) throws SQLException {
|
||||||
|
TableRow row = DatabaseManager.create(c, "harvested_item");
|
||||||
|
row.setColumn("item_id", itemId);
|
||||||
|
row.setColumn("oai_id", itemOAIid);
|
||||||
|
DatabaseManager.update(c, row);
|
||||||
|
|
||||||
|
return new HarvestedItem(c, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getItemID()
|
||||||
|
{
|
||||||
|
String oai_id = harvestRow.getStringColumn("item_id");
|
||||||
|
|
||||||
|
return oai_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the oai_id associated with this item
|
||||||
|
*/
|
||||||
|
public String getOaiID()
|
||||||
|
{
|
||||||
|
String oai_id = harvestRow.getStringColumn("oai_id");
|
||||||
|
|
||||||
|
return oai_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the oai_id associated with this item
|
||||||
|
*/
|
||||||
|
public void setOaiID(String itemOaiID)
|
||||||
|
{
|
||||||
|
harvestRow.setColumn("oai_id",itemOaiID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setHarvestDate(Date date) {
|
||||||
|
if (date == null) {
|
||||||
|
date = new Date();
|
||||||
|
}
|
||||||
|
harvestRow.setColumn("last_harvested", date);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getHarvestDate() {
|
||||||
|
return harvestRow.getDateColumn("last_harvested");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void delete() throws SQLException {
|
||||||
|
DatabaseManager.delete(context, harvestRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void update() throws SQLException, IOException, AuthorizeException {
|
||||||
|
DatabaseManager.update(context, harvestRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1338
dspace-api/src/main/java/org/dspace/harvest/OAIHarvester.java
Normal file
1338
dspace-api/src/main/java/org/dspace/harvest/OAIHarvester.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,7 @@ import org.dspace.content.Community;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.FormatIdentifier;
|
import org.dspace.content.FormatIdentifier;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
import org.dspace.core.Constants;
|
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;
|
||||||
@@ -203,7 +204,11 @@ public class EditCommunitiesServlet extends DSpaceServlet
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case START_EDIT_COLLECTION:
|
case START_EDIT_COLLECTION:
|
||||||
|
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, UIUtil.
|
||||||
|
getIntParameter(request, "collection_id"));
|
||||||
|
request.setAttribute("harvestInstance", hc);
|
||||||
|
|
||||||
// Display the relevant "edit collection" page
|
// Display the relevant "edit collection" page
|
||||||
JSPManager.showJSP(request, response, "/tools/edit-collection.jsp");
|
JSPManager.showJSP(request, response, "/tools/edit-collection.jsp");
|
||||||
|
|
||||||
@@ -551,6 +556,40 @@ public class EditCommunitiesServlet extends DSpaceServlet
|
|||||||
collection.setMetadata("side_bar_text", side);
|
collection.setMetadata("side_bar_text", side);
|
||||||
collection.setMetadata("license", license);
|
collection.setMetadata("license", license);
|
||||||
collection.setMetadata("provenance_description", provenance);
|
collection.setMetadata("provenance_description", provenance);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set the harvesting settings
|
||||||
|
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collection.getID());
|
||||||
|
String contentSource = request.getParameter("source");
|
||||||
|
|
||||||
|
// First, if this is not a harvested collection (anymore), set the harvest type to 0; wipe harvest settings
|
||||||
|
if (contentSource.equals("source_normal"))
|
||||||
|
{
|
||||||
|
if (hc != null)
|
||||||
|
hc.delete();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create a new harvest instance if all the settings check out
|
||||||
|
if (hc == null) {
|
||||||
|
hc = HarvestedCollection.create(context, collection.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
String oaiProvider = request.getParameter("oai_provider");
|
||||||
|
String oaiSetId = request.getParameter("oai_setid");
|
||||||
|
String metadataKey = request.getParameter("metadata_format");
|
||||||
|
String harvestType = request.getParameter("harvest_level");
|
||||||
|
|
||||||
|
hc.setHarvestParams(Integer.parseInt(harvestType), oaiProvider, oaiSetId, metadataKey);
|
||||||
|
hc.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
|
|
||||||
|
hc.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Which button was pressed?
|
// Which button was pressed?
|
||||||
String button = UIUtil.getSubmitButton(request, "submit");
|
String button = UIUtil.getSubmitButton(request, "submit");
|
||||||
|
@@ -56,7 +56,10 @@
|
|||||||
<%@ page import="org.dspace.content.Item" %>
|
<%@ page import="org.dspace.content.Item" %>
|
||||||
<%@ page import="org.dspace.core.Utils" %>
|
<%@ page import="org.dspace.core.Utils" %>
|
||||||
<%@ page import="org.dspace.eperson.Group" %>
|
<%@ page import="org.dspace.eperson.Group" %>
|
||||||
|
<%@ page import="org.dspace.harvest.HarvestedCollection" %>
|
||||||
|
<%@ page import="org.dspace.core.ConfigurationManager" %>
|
||||||
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
|
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
|
||||||
|
<%@ page import="java.util.Enumeration" %>
|
||||||
|
|
||||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
|
||||||
@@ -71,6 +74,8 @@
|
|||||||
Boolean admin = (Boolean)request.getAttribute("is.admin");
|
Boolean admin = (Boolean)request.getAttribute("is.admin");
|
||||||
boolean isAdmin = (admin == null ? false : admin.booleanValue());
|
boolean isAdmin = (admin == null ? false : admin.booleanValue());
|
||||||
|
|
||||||
|
HarvestedCollection hc = (HarvestedCollection) request.getAttribute("harvestInstance");
|
||||||
|
|
||||||
String name = "";
|
String name = "";
|
||||||
String shortDesc = "";
|
String shortDesc = "";
|
||||||
String intro = "";
|
String intro = "";
|
||||||
@@ -78,7 +83,14 @@
|
|||||||
String side = "";
|
String side = "";
|
||||||
String license = "";
|
String license = "";
|
||||||
String provenance = "";
|
String provenance = "";
|
||||||
|
|
||||||
|
String oaiProviderValue= "";
|
||||||
|
String oaiSetIdValue= "";
|
||||||
|
String metadataFormatValue= "";
|
||||||
|
String lastHarvestMsg= "";
|
||||||
|
int harvestLevelValue=0;
|
||||||
|
int harvestStatus= 0;
|
||||||
|
|
||||||
Group[] wfGroups = new Group[3];
|
Group[] wfGroups = new Group[3];
|
||||||
wfGroups[0] = null;
|
wfGroups[0] = null;
|
||||||
wfGroups[1] = null;
|
wfGroups[1] = null;
|
||||||
@@ -115,6 +127,17 @@
|
|||||||
template = collection.getTemplateItem();
|
template = collection.getTemplateItem();
|
||||||
|
|
||||||
logo = collection.getLogo();
|
logo = collection.getLogo();
|
||||||
|
|
||||||
|
/* Harvesting stuff */
|
||||||
|
if (hc != null) {
|
||||||
|
oaiProviderValue = hc.getOaiSource();
|
||||||
|
oaiSetIdValue = hc.getOaiSetId();
|
||||||
|
metadataFormatValue = hc.getHarvestMetadataConfig();
|
||||||
|
harvestLevelValue = hc.getHarvestType();
|
||||||
|
lastHarvestMsg= hc.getHarvestMessage();
|
||||||
|
harvestStatus = hc.getHarvestStatus();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
|
||||||
@@ -314,6 +337,105 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<% if(admin_button ) { %>
|
||||||
|
<%-- ===========================================================
|
||||||
|
Harvesting Settings
|
||||||
|
=========================================================== --%>
|
||||||
|
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
<tr><td colspan="2"><center><h3>Harvesting Settings</h3></center></td></tr>
|
||||||
|
|
||||||
|
<%--
|
||||||
|
oaiProviderValue = hc.getOaiSource();
|
||||||
|
oaiSetIdValue = hc.getOaiSetId();
|
||||||
|
metadataFormatValue = hc.getHarvestMetadataConfig();
|
||||||
|
harvestLevelValue = hc.getHarvestType();
|
||||||
|
String lastHarvestMsg= hc.getHarvestMessage();
|
||||||
|
int harvestStatus = hc.getHarvestStatus();
|
||||||
|
|
||||||
|
if (lastHarvestMsg == null)
|
||||||
|
lastHarvestMsg = "none";
|
||||||
|
--%>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">Content Source</td>
|
||||||
|
<td>
|
||||||
|
<input type="radio" value="source_normal" <% if (harvestLevelValue == 0) { %> checked="checked" <% } %> name="source">This is a standard DSpace collection</input><br/>
|
||||||
|
<input type="radio" value="source_harvested" <% if (harvestLevelValue > 0) { %> checked="checked" <% } %> name="source">This collection harvests its content from an external source</input><br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">OAI Provider</td>
|
||||||
|
<td><input type="text" name="oai_provider" value="<%= oaiProviderValue %>" size="50" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">OAI Set Id</td>
|
||||||
|
<td><input type="text" name="oai_setid" value="<%= oaiSetIdValue %>" size="50" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">Metadata Format</td>
|
||||||
|
<td>
|
||||||
|
<select name="metadata_format" >
|
||||||
|
<%
|
||||||
|
// Add an entry for each instance of ingestion crosswalks configured for harvesting
|
||||||
|
String metaString = "harvester.oai.metadataformats.";
|
||||||
|
Enumeration pe = ConfigurationManager.propertyNames();
|
||||||
|
while (pe.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = (String)pe.nextElement();
|
||||||
|
if (key.startsWith(metaString)) {
|
||||||
|
String metadataString = ConfigurationManager.getProperty(key);
|
||||||
|
String metadataKey = key.substring(metaString.length());
|
||||||
|
String displayName;
|
||||||
|
|
||||||
|
if (metadataString.indexOf(',') != -1)
|
||||||
|
displayName = metadataString.substring(metadataString.indexOf(',') + 1);
|
||||||
|
else
|
||||||
|
displayName = metadataKey + "(" + metadataString + ")";
|
||||||
|
|
||||||
|
%>
|
||||||
|
<option value="<%= metadataKey %>"
|
||||||
|
<% if(metadataKey.equalsIgnoreCase(metadataFormatValue)) { %>
|
||||||
|
selected="selected" <% } %> >
|
||||||
|
<%= displayName %></option>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">Content being Harvested</td>
|
||||||
|
<td>
|
||||||
|
<input type="radio" value="1" <% if (harvestLevelValue != 2 && harvestLevelValue != 3) { %> checked="checked" <% } %> name="harvest_level">Harvest metadata only.</input><br/>
|
||||||
|
<input type="radio" value="2" <% if (harvestLevelValue == 2) { %> checked="checked" <% } %> name="harvest_level">Harvest metadata and references to bitstreams (requires ORE support).</input><br/>
|
||||||
|
<input type="radio" value="3" <% if (harvestLevelValue == 3) { %> checked="checked" <% } %> name="harvest_level">Harvest metadata and bitstreams (requires ORE support).</input><br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">Last Harvest Result</td>
|
||||||
|
<td><%= lastHarvestMsg %></td>
|
||||||
|
</tr>
|
||||||
|
<!--
|
||||||
|
<tr>
|
||||||
|
<td class="submitFormLabel">Current Status</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
@@ -44,6 +44,7 @@ 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.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.apache.avalon.framework.service.ServiceException;
|
import org.apache.avalon.framework.service.ServiceException;
|
||||||
@@ -69,6 +70,9 @@ import org.dspace.app.xmlui.wing.element.Table;
|
|||||||
import org.dspace.app.xmlui.wing.element.TextArea;
|
import org.dspace.app.xmlui.wing.element.TextArea;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.authorize.AuthorizeManager;
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.harvest.OAIHarvester.HarvestScheduler;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@@ -152,6 +156,27 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
private static final Message T_activity_anonymous = message("xmlui.administrative.ControlPanel.activity_anonymous");
|
private static final Message T_activity_anonymous = message("xmlui.administrative.ControlPanel.activity_anonymous");
|
||||||
private static final Message T_activity_none = message("xmlui.administrative.ControlPanel.activity_none");
|
private static final Message T_activity_none = message("xmlui.administrative.ControlPanel.activity_none");
|
||||||
private static final Message T_select_panel = message("xmlui.administrative.ControlPanel.select_panel");
|
private static final Message T_select_panel = message("xmlui.administrative.ControlPanel.select_panel");
|
||||||
|
|
||||||
|
private static final Message T_option_harvest = message("xmlui.administrative.ControlPanel.option_harvest");
|
||||||
|
private static final Message T_harvest_scheduler_head = message("xmlui.administrative.ControlPanel.harvest_scheduler_head");
|
||||||
|
private static final Message T_harvest_label_status = message("xmlui.administrative.ControlPanel.harvest_label_status");
|
||||||
|
private static final Message T_harvest_label_actions = message("xmlui.administrative.ControlPanel.harvest_label_actions");
|
||||||
|
private static final Message T_harvest_submit_start = message("xmlui.administrative.ControlPanel.harvest_submit_start");
|
||||||
|
private static final Message T_harvest_submit_reset = message("xmlui.administrative.ControlPanel.harvest_submit_reset");
|
||||||
|
private static final Message T_harvest_submit_resume = message("xmlui.administrative.ControlPanel.harvest_submit_resume");
|
||||||
|
private static final Message T_harvest_submit_pause = message("xmlui.administrative.ControlPanel.harvest_submit_pause");
|
||||||
|
private static final Message T_harvest_submit_stop = message("xmlui.administrative.ControlPanel.harvest_submit_stop");
|
||||||
|
private static final Message T_harvest_label_collections = message("xmlui.administrative.ControlPanel.harvest_label_collections");
|
||||||
|
private static final Message T_harvest_label_active = message("xmlui.administrative.ControlPanel.harvest_label_active");
|
||||||
|
private static final Message T_harvest_label_queued = message("xmlui.administrative.ControlPanel.harvest_label_queued");
|
||||||
|
private static final Message T_harvest_label_oai_errors = message("xmlui.administrative.ControlPanel.harvest_label_oai_errors");
|
||||||
|
private static final Message T_harvest_label_internal_errors = message("xmlui.administrative.ControlPanel.harvest_label_internal_errors");
|
||||||
|
private static final Message T_harvest_head_generator_settings = message("xmlui.administrative.ControlPanel.harvest_head_generator_settings");
|
||||||
|
private static final Message T_harvest_label_oai_url = message("xmlui.administrative.ControlPanel.harvest_label_oai_url");
|
||||||
|
private static final Message T_harvest_label_oai_source = message("xmlui.administrative.ControlPanel.harvest_label_oai_source");
|
||||||
|
private static final Message T_harvest_head_harvester_settings = message("xmlui.administrative.ControlPanel.harvest_head_harvester_settings");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service manager allows us to access the continuation's
|
* The service manager allows us to access the continuation's
|
||||||
* manager, it is obtained from the servicable API
|
* manager, it is obtained from the servicable API
|
||||||
@@ -159,9 +184,9 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
private ServiceManager serviceManager;
|
private ServiceManager serviceManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The four states that this page can be in.
|
* The five states that this page can be in.
|
||||||
*/
|
*/
|
||||||
private enum OPTIONS {java, dspace, alerts, activity};
|
private enum OPTIONS {java, dspace, alerts, activity, harvest};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From the servicable api, give us a service manager.
|
* From the servicable api, give us a service manager.
|
||||||
@@ -196,6 +221,8 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
option = OPTIONS.alerts;
|
option = OPTIONS.alerts;
|
||||||
if (request.getParameter("activity") != null)
|
if (request.getParameter("activity") != null)
|
||||||
option = OPTIONS.activity;
|
option = OPTIONS.activity;
|
||||||
|
if (request.getParameter("harvest") != null)
|
||||||
|
option = OPTIONS.harvest;
|
||||||
|
|
||||||
Division div = body.addInteractiveDivision("control-panel", contextPath+"/admin/panel", Division.METHOD_POST, "primary administrative");
|
Division div = body.addInteractiveDivision("control-panel", contextPath+"/admin/panel", Division.METHOD_POST, "primary administrative");
|
||||||
div.setHead(T_head);
|
div.setHead(T_head);
|
||||||
@@ -219,6 +246,11 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
else
|
else
|
||||||
options.addItemXref("?alerts",T_option_alerts);
|
options.addItemXref("?alerts",T_option_alerts);
|
||||||
|
|
||||||
|
if (option == OPTIONS.harvest)
|
||||||
|
options.addItem().addHighlight("bold").addXref("?harvest",T_option_harvest);
|
||||||
|
else
|
||||||
|
options.addItemXref("?harvest",T_option_harvest);
|
||||||
|
|
||||||
String userSortTarget = "?activity";
|
String userSortTarget = "?activity";
|
||||||
if (request.getParameter("sortBy") != null)
|
if (request.getParameter("sortBy") != null)
|
||||||
userSortTarget += "&sortBy="+request.getParameter("sortBy");
|
userSortTarget += "&sortBy="+request.getParameter("sortBy");
|
||||||
@@ -237,6 +269,8 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
addAlerts(div);
|
addAlerts(div);
|
||||||
else if (option == OPTIONS.activity)
|
else if (option == OPTIONS.activity)
|
||||||
addActivity(div);
|
addActivity(div);
|
||||||
|
else if (option == OPTIONS.harvest)
|
||||||
|
addHarvest(div);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
div.addPara(T_select_panel);
|
div.addPara(T_select_panel);
|
||||||
@@ -622,4 +656,101 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a section that allows management of the OAI harvester.
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private void addHarvest(Division div) throws WingException, SQLException
|
||||||
|
{
|
||||||
|
// Remember we're in the harvest section
|
||||||
|
div.addHidden("harvest").setValue("true");
|
||||||
|
|
||||||
|
List harvesterControls = div.addList("oai-harvester-controls",List.TYPE_FORM);
|
||||||
|
harvesterControls.setHead(T_harvest_scheduler_head);
|
||||||
|
harvesterControls.addLabel(T_harvest_label_status);
|
||||||
|
Item status = harvesterControls.addItem();
|
||||||
|
status.addContent(HarvestScheduler.getStatus());
|
||||||
|
status.addXref(contextPath + "/admin/panel?harvest", "(refresh)");
|
||||||
|
|
||||||
|
harvesterControls.addLabel(T_harvest_label_actions);
|
||||||
|
Item actionsItem = harvesterControls.addItem();
|
||||||
|
if (HarvestScheduler.status == HarvestScheduler.HARVESTER_STATUS_STOPPED) {
|
||||||
|
actionsItem.addButton("submit_harvest_start").setValue(T_harvest_submit_start);
|
||||||
|
actionsItem.addButton("submit_harvest_reset").setValue(T_harvest_submit_reset);
|
||||||
|
}
|
||||||
|
if (HarvestScheduler.status == HarvestScheduler.HARVESTER_STATUS_PAUSED)
|
||||||
|
actionsItem.addButton("submit_harvest_resume").setValue(T_harvest_submit_resume);
|
||||||
|
if (HarvestScheduler.status == HarvestScheduler.HARVESTER_STATUS_RUNNING ||
|
||||||
|
HarvestScheduler.status == HarvestScheduler.HARVESTER_STATUS_SLEEPING)
|
||||||
|
actionsItem.addButton("submit_harvest_pause").setValue(T_harvest_submit_pause);
|
||||||
|
if (HarvestScheduler.status != HarvestScheduler.HARVESTER_STATUS_STOPPED)
|
||||||
|
actionsItem.addButton("submit_harvest_stop").setValue(T_harvest_submit_stop);
|
||||||
|
|
||||||
|
// Can be retrieved via "{context-path}/admin/collection?collectionID={id}"
|
||||||
|
String baseURL = contextPath + "/admin/collection?collectionID=";
|
||||||
|
|
||||||
|
harvesterControls.addLabel(T_harvest_label_collections);
|
||||||
|
Item allCollectionsItem = harvesterControls.addItem();
|
||||||
|
java.util.List<Integer> allCollections = HarvestedCollection.findAll(context);
|
||||||
|
for (Integer oaiCollection : allCollections) {
|
||||||
|
allCollectionsItem.addXref(baseURL + oaiCollection, oaiCollection.toString());
|
||||||
|
}
|
||||||
|
harvesterControls.addLabel(T_harvest_label_active);
|
||||||
|
Item busyCollectionsItem = harvesterControls.addItem();
|
||||||
|
java.util.List<Integer> busyCollections = HarvestedCollection.findByStatus(context, HarvestedCollection.STATUS_BUSY);
|
||||||
|
for (Integer busyCollection : busyCollections) {
|
||||||
|
busyCollectionsItem.addXref(baseURL + busyCollection, busyCollection.toString());
|
||||||
|
}
|
||||||
|
harvesterControls.addLabel(T_harvest_label_queued);
|
||||||
|
Item queuedCollectionsItem = harvesterControls.addItem();
|
||||||
|
java.util.List<Integer> queuedCollections = HarvestedCollection.findByStatus(context, HarvestedCollection.STATUS_QUEUED);
|
||||||
|
for (Integer queuedCollection : queuedCollections) {
|
||||||
|
queuedCollectionsItem.addXref(baseURL + queuedCollection, queuedCollection.toString());
|
||||||
|
}
|
||||||
|
harvesterControls.addLabel(T_harvest_label_oai_errors);
|
||||||
|
Item oaiErrorsItem = harvesterControls.addItem();
|
||||||
|
java.util.List<Integer> oaiErrors = HarvestedCollection.findByStatus(context, HarvestedCollection.STATUS_OAI_ERROR);
|
||||||
|
for (Integer oaiError : oaiErrors) {
|
||||||
|
oaiErrorsItem.addXref(baseURL + oaiError, oaiError.toString());
|
||||||
|
}
|
||||||
|
harvesterControls.addLabel(T_harvest_label_internal_errors);
|
||||||
|
Item internalErrorsItem = harvesterControls.addItem();
|
||||||
|
java.util.List<Integer> internalErrors = HarvestedCollection.findByStatus(context, HarvestedCollection.STATUS_UNKNOWN_ERROR);
|
||||||
|
for (Integer internalError : internalErrors) {
|
||||||
|
internalErrorsItem.addXref(baseURL + internalError, internalError.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// OAI Generator settings
|
||||||
|
List generatorSettings = div.addList("oai-generator-settings");
|
||||||
|
generatorSettings.setHead(T_harvest_head_generator_settings);
|
||||||
|
|
||||||
|
generatorSettings.addLabel(T_harvest_label_oai_url);
|
||||||
|
String oaiUrl = ConfigurationManager.getProperty("dspace.oai.url");
|
||||||
|
if (oaiUrl != null && oaiUrl != "")
|
||||||
|
generatorSettings.addItem(oaiUrl);
|
||||||
|
|
||||||
|
generatorSettings.addLabel(T_harvest_label_oai_source);
|
||||||
|
String oaiAuthoritativeSource = ConfigurationManager.getProperty("ore.authoritative.source");
|
||||||
|
if (oaiAuthoritativeSource != null && oaiAuthoritativeSource != "")
|
||||||
|
generatorSettings.addItem(oaiAuthoritativeSource);
|
||||||
|
else
|
||||||
|
generatorSettings.addItem("oai");
|
||||||
|
|
||||||
|
// OAI Harvester settings (just iterate over all the values that start with "harvester")
|
||||||
|
List harvesterSettings = div.addList("oai-harvester-settings");
|
||||||
|
harvesterSettings.setHead(T_harvest_head_harvester_settings);
|
||||||
|
|
||||||
|
String metaString = "harvester.";
|
||||||
|
Enumeration pe = ConfigurationManager.propertyNames();
|
||||||
|
while (pe.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = (String)pe.nextElement();
|
||||||
|
if (key.startsWith(metaString)) {
|
||||||
|
harvesterSettings.addLabel(key);
|
||||||
|
harvesterSettings.addItem(ConfigurationManager.getProperty(key) + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,8 @@ import org.apache.cocoon.environment.ObjectModelHelper;
|
|||||||
import org.apache.cocoon.environment.Redirector;
|
import org.apache.cocoon.environment.Redirector;
|
||||||
import org.apache.cocoon.environment.Request;
|
import org.apache.cocoon.environment.Request;
|
||||||
import org.apache.cocoon.environment.SourceResolver;
|
import org.apache.cocoon.environment.SourceResolver;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.harvest.OAIHarvester.HarvestScheduler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the alert system based upon the form submitted from the control panel.
|
* Update the alert system based upon the form submitted from the control panel.
|
||||||
@@ -127,7 +129,22 @@ public class ControlPanelAction extends AbstractAction
|
|||||||
{
|
{
|
||||||
SystemwideAlerts.deactivateAlert();
|
SystemwideAlerts.deactivateAlert();
|
||||||
}
|
}
|
||||||
|
else if (request.getParameter("submit_harvest_start") != null) {
|
||||||
|
OAIHarvester.startNewScheduler();
|
||||||
|
}
|
||||||
|
else if (request.getParameter("submit_harvest_resume") != null) {
|
||||||
|
OAIHarvester.resumeScheduler();
|
||||||
|
}
|
||||||
|
else if (request.getParameter("submit_harvest_pause") != null) {
|
||||||
|
OAIHarvester.pauseScheduler();
|
||||||
|
}
|
||||||
|
else if (request.getParameter("submit_harvest_stop") != null) {
|
||||||
|
OAIHarvester.stopScheduler();
|
||||||
|
}
|
||||||
|
else if (request.getParameter("submit_harvest_reset") != null) {
|
||||||
|
OAIHarvester.resetScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,8 +42,13 @@ import java.io.ByteArrayInputStream;
|
|||||||
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.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
|
||||||
import org.apache.cocoon.environment.Request;
|
import org.apache.cocoon.environment.Request;
|
||||||
import org.apache.cocoon.servlet.multipart.Part;
|
import org.apache.cocoon.servlet.multipart.Part;
|
||||||
import org.dspace.app.xmlui.utils.UIException;
|
import org.dspace.app.xmlui.utils.UIException;
|
||||||
@@ -51,14 +56,24 @@ import org.dspace.app.xmlui.wing.Message;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.authorize.AuthorizeManager;
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
import org.dspace.authorize.ResourcePolicy;
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.browse.BrowseException;
|
||||||
|
import org.dspace.browse.IndexBrowse;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.ItemIterator;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.harvest.OAIHarvester.HarvestScheduler;
|
||||||
|
import org.dspace.harvest.OAIHarvester.HarvestingException;
|
||||||
|
import org.dspace.content.crosswalk.CrosswalkException;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
import org.jdom.JDOMException;
|
import org.jdom.JDOMException;
|
||||||
import org.jdom.input.SAXBuilder;
|
import org.jdom.input.SAXBuilder;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods to processes actions on Communities and Collections.
|
* Utility methods to processes actions on Communities and Collections.
|
||||||
@@ -164,6 +179,203 @@ public class FlowContainerUtils
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the collection harvesting options form.
|
||||||
|
*
|
||||||
|
* @param context The current DSpace context.
|
||||||
|
* @param collectionID The collection id.
|
||||||
|
* @param request the Cocoon request object
|
||||||
|
* @return A process result's object.
|
||||||
|
*/
|
||||||
|
public static FlowResult processSetupCollectionHarvesting(Context context, int collectionID, Request request) throws SQLException, IOException, AuthorizeException
|
||||||
|
{
|
||||||
|
FlowResult result = new FlowResult();
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
|
||||||
|
String contentSource = request.getParameter("source");
|
||||||
|
|
||||||
|
// First, if this is not a harvested collection (anymore), set the harvest type to 0; possibly also wipe harvest settings
|
||||||
|
if (contentSource.equals("source_normal"))
|
||||||
|
{
|
||||||
|
if (hc != null)
|
||||||
|
hc.delete();
|
||||||
|
|
||||||
|
result.setContinue(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FlowResult subResult = testOAISettings(context, request);
|
||||||
|
|
||||||
|
// create a new harvest instance if all the settings check out
|
||||||
|
if (hc == null) {
|
||||||
|
hc = HarvestedCollection.create(context, collectionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the supplied options all check out, set the harvesting parameters on the collection
|
||||||
|
if (subResult.getErrors().isEmpty()) {
|
||||||
|
String oaiProvider = request.getParameter("oai_provider");
|
||||||
|
String oaiSetId = request.getParameter("oai_setid");
|
||||||
|
String metadataKey = request.getParameter("metadata_format");
|
||||||
|
String harvestType = request.getParameter("harvest_level");
|
||||||
|
|
||||||
|
hc.setHarvestParams(Integer.parseInt(harvestType), oaiProvider, oaiSetId, metadataKey);
|
||||||
|
hc.setHarvestStatus(HarvestedCollection.STATUS_READY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setErrors(subResult.getErrors());
|
||||||
|
result.setContinue(false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
hc.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save everything
|
||||||
|
context.commit();
|
||||||
|
|
||||||
|
// No notice...
|
||||||
|
//result.setMessage(new Message("default","Harvesting options successfully modified."));
|
||||||
|
result.setOutcome(true);
|
||||||
|
result.setContinue(true);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the collection's harvest settings to immediately perform a harvest cycle.
|
||||||
|
*
|
||||||
|
* @param context The current DSpace context.
|
||||||
|
* @param collectionID The collection id.
|
||||||
|
* @param request the Cocoon request object
|
||||||
|
* @return A process result's object.
|
||||||
|
* @throws TransformerException
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* @throws CrosswalkException
|
||||||
|
*/
|
||||||
|
public static FlowResult processRunCollectionHarvest(Context context, int collectionID, Request request) throws SQLException, IOException, AuthorizeException, CrosswalkException, ParserConfigurationException, SAXException, TransformerException
|
||||||
|
{
|
||||||
|
FlowResult result = new FlowResult();
|
||||||
|
OAIHarvester harvester;
|
||||||
|
List<String> testErrors = new ArrayList<String>();
|
||||||
|
Collection collection = Collection.find(context, collectionID);
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
|
||||||
|
//TODO: is there a cleaner way to do this?
|
||||||
|
try {
|
||||||
|
if (HarvestScheduler.status != HarvestScheduler.HARVESTER_STATUS_STOPPED) {
|
||||||
|
synchronized(HarvestScheduler.lock) {
|
||||||
|
HarvestScheduler.interrupt = HarvestScheduler.HARVESTER_INTERRUPT_INSERT_THREAD;
|
||||||
|
HarvestScheduler.interruptValue = collection.getID();
|
||||||
|
HarvestScheduler.lock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
harvester = new OAIHarvester(context, collection, hc);
|
||||||
|
harvester.runHarvest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
testErrors.add(e.getMessage());
|
||||||
|
result.setErrors(testErrors);
|
||||||
|
result.setContinue(false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setContinue(true);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge the collection of all items, then run a fresh harvest cycle.
|
||||||
|
*
|
||||||
|
* @param context The current DSpace context.
|
||||||
|
* @param collectionID The collection id.
|
||||||
|
* @param request the Cocoon request object
|
||||||
|
* @return A process result's object.
|
||||||
|
* @throws TransformerException
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* @throws CrosswalkException
|
||||||
|
* @throws BrowseException
|
||||||
|
*/
|
||||||
|
public static FlowResult processReimportCollection(Context context, int collectionID, Request request) throws SQLException, IOException, AuthorizeException, CrosswalkException, ParserConfigurationException, SAXException, TransformerException, BrowseException
|
||||||
|
{
|
||||||
|
FlowResult result = new FlowResult();
|
||||||
|
Collection collection = Collection.find(context, collectionID);
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
|
||||||
|
ItemIterator it = collection.getAllItems();
|
||||||
|
//IndexBrowse ib = new IndexBrowse(context);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Item item = it.next();
|
||||||
|
//System.out.println("Deleting: " + item.getHandle());
|
||||||
|
//ib.itemRemoved(item);
|
||||||
|
collection.removeItem(item);
|
||||||
|
}
|
||||||
|
hc.setHarvestResult(null,"");
|
||||||
|
hc.update();
|
||||||
|
collection.update();
|
||||||
|
context.commit();
|
||||||
|
|
||||||
|
result = processRunCollectionHarvest(context, collectionID, request);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the supplied OAI settings.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static FlowResult testOAISettings(Context context, Request request)
|
||||||
|
{
|
||||||
|
FlowResult result = new FlowResult();
|
||||||
|
|
||||||
|
String oaiProvider = request.getParameter("oai_provider");
|
||||||
|
String oaiSetId = request.getParameter("oai_setid");
|
||||||
|
String metadataKey = request.getParameter("metadata_format");
|
||||||
|
String harvestType = request.getParameter("harvest_level");
|
||||||
|
int harvestTypeInt = 0;
|
||||||
|
|
||||||
|
if (oaiProvider == null || oaiProvider.length() == 0)
|
||||||
|
result.addError("oai_provider");
|
||||||
|
if (oaiSetId == null || oaiSetId.length() == 0)
|
||||||
|
result.addError("oai_setid");
|
||||||
|
if (metadataKey == null || metadataKey.length() == 0)
|
||||||
|
result.addError("metadata_format");
|
||||||
|
if (harvestType == null || harvestType.length() == 0)
|
||||||
|
result.addError("harvest_level");
|
||||||
|
else
|
||||||
|
harvestTypeInt = Integer.parseInt(harvestType);
|
||||||
|
|
||||||
|
|
||||||
|
if (result.getErrors() == null) {
|
||||||
|
List<String> testErrors = OAIHarvester.verifyOAIharvester(oaiProvider, oaiSetId, metadataKey, (harvestTypeInt>1));
|
||||||
|
result.setErrors(testErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getErrors() == null || result.getErrors().isEmpty()) {
|
||||||
|
result.setOutcome(true);
|
||||||
|
// On a successful test we still want to stay in the loop, not continue out of it
|
||||||
|
//result.setContinue(true);
|
||||||
|
result.setMessage(new Message("default","Harvesting settings are valid."));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setOutcome(false);
|
||||||
|
result.setContinue(false);
|
||||||
|
// don't really need a message when the errors are highlighted already
|
||||||
|
//result.setMessage(new Message("default","Harvesting is not properly configured."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up the id of the template item for a given collection.
|
* Look up the id of the template item for a given collection.
|
||||||
|
@@ -73,6 +73,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
|||||||
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
||||||
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
||||||
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
||||||
|
private static final Message T_options_harvest = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest");
|
||||||
|
|
||||||
private static final Message T_submit_return = message("xmlui.general.return");
|
private static final Message T_submit_return = message("xmlui.general.return");
|
||||||
|
|
||||||
@@ -145,6 +146,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
|||||||
List options = main.addList("options", List.TYPE_SIMPLE, "horizontal");
|
List options = main.addList("options", List.TYPE_SIMPLE, "horizontal");
|
||||||
options.addItem().addXref(baseURL+"&submit_metadata",T_options_metadata);
|
options.addItem().addXref(baseURL+"&submit_metadata",T_options_metadata);
|
||||||
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_roles",T_options_roles);
|
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_roles",T_options_roles);
|
||||||
|
options.addItem().addXref(baseURL+"&submit_harvesting",T_options_harvest);
|
||||||
|
|
||||||
// The table of admin roles
|
// The table of admin roles
|
||||||
Table rolesTable = main.addTable("roles-table", 6, 5);
|
Table rolesTable = main.addTable("roles-table", 6, 5);
|
||||||
|
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* EditCollectionHarvestingForm.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1.0 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2006/07/13 23:20:54 $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.dspace.app.xmlui.aspect.administrative.collection;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Body;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Division;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Item;
|
||||||
|
import org.dspace.app.xmlui.wing.element.List;
|
||||||
|
import org.dspace.app.xmlui.wing.element.PageMeta;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Para;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Radio;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the other form that deals with harvesting. This one comes up when the collection is
|
||||||
|
* edited with the harvesting options set and verified. Allows two actions: "import" and "reingest",
|
||||||
|
* as well as "change", which takes the user to the other harvesting form.
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class EditCollectionHarvestingForm extends AbstractDSpaceTransformer
|
||||||
|
{
|
||||||
|
/** Language Strings */
|
||||||
|
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
|
||||||
|
|
||||||
|
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
||||||
|
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
||||||
|
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
||||||
|
private static final Message T_main_head = message("xmlui.administrative.collection.EditCollectionMetadataForm.main_head");
|
||||||
|
|
||||||
|
private static final Message T_options_harvest = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest");
|
||||||
|
private static final Message T_title = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.title");
|
||||||
|
private static final Message T_trail = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.trail");
|
||||||
|
|
||||||
|
private static final Message T_label_source = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.label_source");
|
||||||
|
private static final Message T_source_normal = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_normal");
|
||||||
|
private static final Message T_source_harvested = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_harvested");
|
||||||
|
|
||||||
|
private static final Message T_submit_return = message("xmlui.general.return");
|
||||||
|
private static final Message T_submit_save = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.submit_save");
|
||||||
|
|
||||||
|
private static final Message T_main_settings_head = message("xmlui.administrative.collection.EditCollectionHarvestingForm.main_settings_head");
|
||||||
|
private static final Message T_label_oai_provider = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_oai_provider");
|
||||||
|
private static final Message T_label_setid = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_setid");
|
||||||
|
private static final Message T_label_metadata_format = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_metadata_format");
|
||||||
|
|
||||||
|
private static final Message T_label_harvest_level = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_level");
|
||||||
|
private static final Message T_label_harvest_result = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_result");
|
||||||
|
private static final Message T_harvest_result_new = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_result_new");
|
||||||
|
|
||||||
|
private static final Message T_label_harvest_status = message("xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_status");
|
||||||
|
private static final Message T_harvest_status_ready = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_ready");
|
||||||
|
private static final Message T_harvest_status_busy = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_busy");
|
||||||
|
private static final Message T_harvest_status_queued = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_queued");
|
||||||
|
private static final Message T_harvest_status_oai_error = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_oai_error");
|
||||||
|
private static final Message T_harvest_status_unknown_error = message("xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_unknown_error");
|
||||||
|
|
||||||
|
private static final Message T_option_md_only = message("xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_only");
|
||||||
|
private static final Message T_option_md_and_ref = message("xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_and_ref");
|
||||||
|
private static final Message T_option_md_and_bs = message("xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_and_bs");
|
||||||
|
|
||||||
|
private static final Message T_submit_change_settings = message("xmlui.administrative.collection.EditCollectionHarvestingForm.submit_change_settings");
|
||||||
|
private static final Message T_submit_import_now = message("xmlui.administrative.collection.EditCollectionHarvestingForm.submit_import_now");
|
||||||
|
private static final Message T_submit_reimport_collection = message("xmlui.administrative.collection.EditCollectionHarvestingForm.submit_reimport_collection");
|
||||||
|
|
||||||
|
|
||||||
|
public void addPageMeta(PageMeta pageMeta) throws WingException
|
||||||
|
{
|
||||||
|
pageMeta.addMetadata("title").addContent(T_title);
|
||||||
|
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
|
||||||
|
pageMeta.addTrail().addContent(T_collection_trail);
|
||||||
|
pageMeta.addTrail().addContent(T_trail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addBody(Body body) throws WingException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
int collectionID = parameters.getParameterAsInteger("collectionID", -1);
|
||||||
|
Collection thisCollection = Collection.find(context, collectionID);
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
|
||||||
|
String baseURL = contextPath + "/admin/collection?administrative-continue=" + knot.getId();
|
||||||
|
|
||||||
|
String oaiProviderValue = hc.getOaiSource();
|
||||||
|
String oaiSetIdValue = hc.getOaiSetId();
|
||||||
|
String metadataFormatValue = hc.getHarvestMetadataConfig();
|
||||||
|
int harvestLevelValue = hc.getHarvestType();
|
||||||
|
int harvestStatusValue = hc.getHarvestStatus();
|
||||||
|
|
||||||
|
// DIVISION: main
|
||||||
|
Division main = body.addInteractiveDivision("collection-harvesting-edit",contextPath+"/admin/collection",Division.METHOD_MULTIPART,"primary administrative collection");
|
||||||
|
main.setHead(T_main_head.parameterize(thisCollection.getMetadata("name")));
|
||||||
|
|
||||||
|
List options = main.addList("options",List.TYPE_SIMPLE,"horizontal");
|
||||||
|
options.addItem().addXref(baseURL+"&submit_metadata",T_options_metadata);
|
||||||
|
options.addItem().addXref(baseURL+"&submit_roles",T_options_roles);
|
||||||
|
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_harvesting",T_options_harvest);
|
||||||
|
|
||||||
|
|
||||||
|
// The top-level, all-setting, countent source radio button
|
||||||
|
List harvestSource = main.addList("harvestSource", "form");
|
||||||
|
|
||||||
|
harvestSource.addLabel(T_label_source);
|
||||||
|
Radio source = harvestSource.addItem().addRadio("source");
|
||||||
|
source.addOption(hc == null, "source_normal", T_source_normal);
|
||||||
|
source.addOption(hc != null, "source_harvested", T_source_harvested);
|
||||||
|
|
||||||
|
List settings = main.addList("harvestSettings", "form");
|
||||||
|
settings.setHead(T_main_settings_head);
|
||||||
|
|
||||||
|
settings.addLabel(T_label_oai_provider);
|
||||||
|
settings.addItem(oaiProviderValue);
|
||||||
|
|
||||||
|
settings.addLabel(T_label_setid);
|
||||||
|
settings.addItem(oaiSetIdValue);
|
||||||
|
|
||||||
|
// The big complex way of getting to our metadata
|
||||||
|
settings.addLabel(T_label_metadata_format);
|
||||||
|
|
||||||
|
String key = "harvester.oai.metadataformats." + metadataFormatValue;
|
||||||
|
String metadataString = ConfigurationManager.getProperty(key);
|
||||||
|
|
||||||
|
String displayName;
|
||||||
|
if (metadataString.indexOf(',') != -1)
|
||||||
|
displayName = metadataString.substring(metadataString.indexOf(',') + 1);
|
||||||
|
else
|
||||||
|
displayName = metadataFormatValue + "(" + metadataString + ")";
|
||||||
|
|
||||||
|
settings.addItem(displayName);
|
||||||
|
|
||||||
|
settings.addLabel(T_label_harvest_level);
|
||||||
|
Item harvestLevel = settings.addItem();
|
||||||
|
switch (harvestLevelValue) {
|
||||||
|
case 1: harvestLevel.addContent(T_option_md_only); break;
|
||||||
|
case 2: harvestLevel.addContent(T_option_md_and_ref); break;
|
||||||
|
default: harvestLevel.addContent(T_option_md_and_bs); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Results of the last harvesting cycle */
|
||||||
|
if (harvestLevelValue > 0) {
|
||||||
|
settings.addLabel(T_label_harvest_result);
|
||||||
|
Item harvestResult = settings.addItem();
|
||||||
|
if (hc.getHarvestMessage() != null) {
|
||||||
|
harvestResult.addContent(hc.getHarvestMessage() + " on " + hc.getHarvestStartTime());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
harvestResult.addContent(T_harvest_result_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Current status */
|
||||||
|
settings.addLabel(T_label_harvest_status);
|
||||||
|
Item harvestStatus = settings.addItem();
|
||||||
|
switch(harvestStatusValue) {
|
||||||
|
case HarvestedCollection.STATUS_READY: harvestStatus.addContent(T_harvest_status_ready); break;
|
||||||
|
case HarvestedCollection.STATUS_BUSY: harvestStatus.addContent(T_harvest_status_busy); break;
|
||||||
|
case HarvestedCollection.STATUS_QUEUED: harvestStatus.addContent(T_harvest_status_queued); break;
|
||||||
|
case HarvestedCollection.STATUS_OAI_ERROR: harvestStatus.addContent(T_harvest_status_oai_error); break;
|
||||||
|
case HarvestedCollection.STATUS_UNKNOWN_ERROR: harvestStatus.addContent(T_harvest_status_unknown_error); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.addLabel();
|
||||||
|
Item harvestButtons = settings.addItem();
|
||||||
|
harvestButtons.addButton("submit_change").setValue(T_submit_change_settings);
|
||||||
|
harvestButtons.addButton("submit_import_now").setValue(T_submit_import_now);
|
||||||
|
harvestButtons.addButton("submit_reimport").setValue(T_submit_reimport_collection);
|
||||||
|
|
||||||
|
Para buttonList = main.addPara();
|
||||||
|
buttonList.addButton("submit_save").setValue(T_submit_save);
|
||||||
|
buttonList.addButton("submit_return").setValue(T_submit_return);
|
||||||
|
|
||||||
|
main.addHidden("administrative-continue").setValue(knot.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -73,6 +73,7 @@ public class EditCollectionMetadataForm extends AbstractDSpaceTransformer
|
|||||||
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
||||||
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
||||||
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
||||||
|
private static final Message T_options_harvest = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest");
|
||||||
|
|
||||||
private static final Message T_submit_return = message("xmlui.general.return");
|
private static final Message T_submit_return = message("xmlui.general.return");
|
||||||
|
|
||||||
@@ -135,6 +136,7 @@ public class EditCollectionMetadataForm extends AbstractDSpaceTransformer
|
|||||||
List options = main.addList("options",List.TYPE_SIMPLE,"horizontal");
|
List options = main.addList("options",List.TYPE_SIMPLE,"horizontal");
|
||||||
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_metadata",T_options_metadata);
|
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_metadata",T_options_metadata);
|
||||||
options.addItem().addXref(baseURL+"&submit_roles",T_options_roles);
|
options.addItem().addXref(baseURL+"&submit_roles",T_options_roles);
|
||||||
|
options.addItem().addXref(baseURL+"&submit_harvesting",T_options_harvest);
|
||||||
|
|
||||||
|
|
||||||
// The grand list of metadata options
|
// The grand list of metadata options
|
||||||
|
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* SetupCollectionHarvestingForm.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1.0 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2006/07/13 23:20:54 $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.dspace.app.xmlui.aspect.administrative.collection;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.dspace.app.xmlui.aspect.administrative.FlowContainerUtils;
|
||||||
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Body;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Button;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Division;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Item;
|
||||||
|
import org.dspace.app.xmlui.wing.element.List;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Option;
|
||||||
|
import org.dspace.app.xmlui.wing.element.PageMeta;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Para;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Radio;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Select;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Text;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presents the user (in this case an administrator over the collection) with the
|
||||||
|
* form to edit that collection's metadata, logo, and item template.
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class SetupCollectionHarvestingForm extends AbstractDSpaceTransformer
|
||||||
|
{
|
||||||
|
/** Language Strings */
|
||||||
|
private static final Message T_dspace_home =
|
||||||
|
message("xmlui.general.dspace_home");
|
||||||
|
|
||||||
|
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
||||||
|
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
||||||
|
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
||||||
|
private static final Message T_main_head = message("xmlui.administrative.collection.EditCollectionMetadataForm.main_head");
|
||||||
|
|
||||||
|
private static final Message T_options_harvest = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest");
|
||||||
|
private static final Message T_title = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.title");
|
||||||
|
private static final Message T_trail = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.trail");
|
||||||
|
|
||||||
|
private static final Message T_label_source = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.label_source");
|
||||||
|
private static final Message T_source_normal = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_normal");
|
||||||
|
private static final Message T_source_harvested = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_harvested");
|
||||||
|
|
||||||
|
private static final Message T_submit_return = message("xmlui.general.return");
|
||||||
|
private static final Message T_submit_save = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.submit_save");
|
||||||
|
|
||||||
|
private static final Message T_main_settings_head = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.main_settings_head");
|
||||||
|
private static final Message T_options_head = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.options_head");
|
||||||
|
|
||||||
|
private static final Message T_label_oai_provider = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.label_oai_provider");
|
||||||
|
private static final Message T_label_setid = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.label_setid");
|
||||||
|
private static final Message T_label_metadata_format = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.label_metadata_format");
|
||||||
|
|
||||||
|
private static final Message T_help_oaiurl = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.help_oaiurl");
|
||||||
|
private static final Message T_error_oaiurl = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.error_oaiurl");
|
||||||
|
private static final Message T_help_oaisetid = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.help_oaisetid");
|
||||||
|
private static final Message T_error_oaisetid = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.error_oaisetid");
|
||||||
|
|
||||||
|
private static final Message T_label_harvest_level = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.label_harvest_level");
|
||||||
|
|
||||||
|
private static final Message T_option_md_only = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_only");
|
||||||
|
private static final Message T_option_md_and_ref = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_and_ref");
|
||||||
|
private static final Message T_option_md_and_bs = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_and_bs");
|
||||||
|
|
||||||
|
private static final Message T_submit_test = message("xmlui.administrative.collection.SetupCollectionHarvestingForm.submit_test");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void addPageMeta(PageMeta pageMeta) throws WingException
|
||||||
|
{
|
||||||
|
pageMeta.addMetadata("title").addContent(T_title);
|
||||||
|
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
|
||||||
|
pageMeta.addTrail().addContent(T_collection_trail);
|
||||||
|
pageMeta.addTrail().addContent(T_trail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addBody(Body body) throws WingException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
int collectionID = parameters.getParameterAsInteger("collectionID", -1);
|
||||||
|
Collection thisCollection = Collection.find(context, collectionID);
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
String baseURL = contextPath + "/admin/collection?administrative-continue=" + knot.getId();
|
||||||
|
|
||||||
|
String errorString = parameters.getParameter("errors",null);
|
||||||
|
String[] errors = errorString.split(",");
|
||||||
|
HashMap<String,String> errorMap = new HashMap<String,String>();
|
||||||
|
for (String error : errors) {
|
||||||
|
//System.out.println(errorString);
|
||||||
|
String[] errorPieces = error.split(":",2);
|
||||||
|
|
||||||
|
if (errorPieces.length > 1)
|
||||||
|
errorMap.put(errorPieces[0], errorPieces[1]);
|
||||||
|
else
|
||||||
|
errorMap.put(errorPieces[0], errorPieces[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String oaiProviderValue;
|
||||||
|
String oaiSetIdValue;
|
||||||
|
String metadataFormatValue;
|
||||||
|
int harvestLevelValue;
|
||||||
|
|
||||||
|
if (hc != null && request.getParameter("submit_test") == null) {
|
||||||
|
oaiProviderValue = hc.getOaiSource();
|
||||||
|
oaiSetIdValue = hc.getOaiSetId();
|
||||||
|
metadataFormatValue = hc.getHarvestMetadataConfig();
|
||||||
|
harvestLevelValue = hc.getHarvestType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oaiProviderValue = parameters.getParameter("oaiProviderValue", "");
|
||||||
|
oaiSetIdValue = parameters.getParameter("oaiSetIdValue", "");
|
||||||
|
metadataFormatValue = parameters.getParameter("metadataFormatValue", "");
|
||||||
|
String harvestLevelString = parameters.getParameter("harvestLevelValue","0");
|
||||||
|
if (harvestLevelString.length() == 0)
|
||||||
|
harvestLevelValue = 0;
|
||||||
|
else
|
||||||
|
harvestLevelValue = Integer.parseInt(harvestLevelString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DIVISION: main
|
||||||
|
Division main = body.addInteractiveDivision("collection-harvesting-setup",contextPath+"/admin/collection",Division.METHOD_MULTIPART,"primary administrative collection");
|
||||||
|
main.setHead(T_main_head.parameterize(thisCollection.getMetadata("name")));
|
||||||
|
|
||||||
|
List options = main.addList("options",List.TYPE_SIMPLE,"horizontal");
|
||||||
|
options.addItem().addXref(baseURL+"&submit_metadata",T_options_metadata);
|
||||||
|
options.addItem().addXref(baseURL+"&submit_roles",T_options_roles);
|
||||||
|
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_harvesting",T_options_harvest);
|
||||||
|
|
||||||
|
|
||||||
|
// The top-level, all-setting, countent source radio button
|
||||||
|
List harvestSource = main.addList("harvestSource", "form");
|
||||||
|
|
||||||
|
harvestSource.addLabel(T_label_source);
|
||||||
|
Radio source = harvestSource.addItem().addRadio("source");
|
||||||
|
source.addOption(hc == null || harvestLevelValue == -1, "source_normal", T_source_normal);
|
||||||
|
source.addOption(hc != null, "source_harvested", T_source_harvested);
|
||||||
|
|
||||||
|
List settings = main.addList("harvestSettings", "form");
|
||||||
|
settings.setHead(T_main_settings_head);
|
||||||
|
|
||||||
|
settings.addLabel(T_label_oai_provider);
|
||||||
|
Text oaiProvider = settings.addItem().addText("oai_provider");
|
||||||
|
oaiProvider.setSize(40);
|
||||||
|
oaiProvider.setValue(oaiProviderValue);
|
||||||
|
oaiProvider.setHelp(T_help_oaiurl);
|
||||||
|
|
||||||
|
if (errorMap.containsKey(OAIHarvester.OAI_ADDRESS_ERROR)) {
|
||||||
|
oaiProvider.addError(errorMap.get(OAIHarvester.OAI_ADDRESS_ERROR));
|
||||||
|
}
|
||||||
|
if (errorMap.containsKey("oai_provider")) {
|
||||||
|
oaiProvider.addError(T_error_oaiurl);
|
||||||
|
//oaiProvider.addError("You must provide a set id of the target collection.");
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.addLabel(T_label_setid);
|
||||||
|
Text oaiSetId = settings.addItem().addText("oai_setid");
|
||||||
|
oaiSetId.setSize(40);
|
||||||
|
oaiSetId.setValue(oaiSetIdValue);
|
||||||
|
oaiSetId.setHelp(T_help_oaisetid);
|
||||||
|
if (errorMap.containsKey(OAIHarvester.OAI_SET_ERROR)) {
|
||||||
|
oaiSetId.addError(errorMap.get(OAIHarvester.OAI_SET_ERROR));
|
||||||
|
}
|
||||||
|
if (errorMap.containsKey("oai_setid")) {
|
||||||
|
oaiSetId.addError(T_error_oaisetid);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.addLabel(T_label_metadata_format);
|
||||||
|
Select metadataFormat = settings.addItem().addSelect("metadata_format");
|
||||||
|
if (errorMap.containsKey(OAIHarvester.OAI_ORE_ERROR)) {
|
||||||
|
metadataFormat.addError(errorMap.get(OAIHarvester.OAI_ORE_ERROR));
|
||||||
|
}
|
||||||
|
if (errorMap.containsKey(OAIHarvester.OAI_DMD_ERROR)) {
|
||||||
|
metadataFormat.addError(errorMap.get(OAIHarvester.OAI_DMD_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add an entry for each instance of ingestion crosswalks configured for harvesting
|
||||||
|
String metaString = "harvester.oai.metadataformats.";
|
||||||
|
Enumeration pe = ConfigurationManager.propertyNames();
|
||||||
|
while (pe.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = (String)pe.nextElement();
|
||||||
|
if (key.startsWith(metaString)) {
|
||||||
|
String metadataString = ConfigurationManager.getProperty(key);
|
||||||
|
String metadataKey = key.substring(metaString.length());
|
||||||
|
String displayName;
|
||||||
|
|
||||||
|
if (metadataString.indexOf(',') != -1)
|
||||||
|
displayName = metadataString.substring(metadataString.indexOf(',') + 1);
|
||||||
|
else
|
||||||
|
displayName = metadataKey + "(" + metadataString + ")";
|
||||||
|
|
||||||
|
metadataFormat.addOption(metadataKey.equalsIgnoreCase(metadataFormatValue), metadataKey, displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
settings.addLabel();
|
||||||
|
Item harvestButtons = settings.addItem();
|
||||||
|
harvestButtons.addButton("submit_test").setValue(T_submit_test);
|
||||||
|
|
||||||
|
// Various non-critical harvesting options
|
||||||
|
//Division optionsDiv = main.addDivision("collection-harvesting-options","secondary");
|
||||||
|
//optionsDiv.setHead(T_options_head);
|
||||||
|
|
||||||
|
List harvestOptions = main.addList("harvestOptions", "form");
|
||||||
|
harvestOptions.setHead(T_options_head);
|
||||||
|
|
||||||
|
harvestOptions.addLabel(T_label_harvest_level);
|
||||||
|
Radio harvestLevel = harvestOptions.addItem().addRadio("harvest_level");
|
||||||
|
harvestLevel.addOption(harvestLevelValue == 1, 1, T_option_md_only);
|
||||||
|
harvestLevel.addOption(harvestLevelValue == 2, 2, T_option_md_and_ref);
|
||||||
|
harvestLevel.addOption(harvestLevelValue != 1 && harvestLevelValue != 2, 3, T_option_md_and_bs);
|
||||||
|
|
||||||
|
Para buttonList = main.addPara();
|
||||||
|
buttonList.addButton("submit_save").setValue(T_submit_save);
|
||||||
|
buttonList.addButton("submit_return").setValue(T_submit_return);
|
||||||
|
|
||||||
|
main.addHidden("administrative-continue").setValue(knot.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* ToggleCollectionHarvestingForm.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1.0 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2006/07/13 23:20:54 $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.dspace.app.xmlui.aspect.administrative.collection;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.dspace.app.xmlui.aspect.administrative.FlowContainerUtils;
|
||||||
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Body;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Button;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Division;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Item;
|
||||||
|
import org.dspace.app.xmlui.wing.element.List;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Option;
|
||||||
|
import org.dspace.app.xmlui.wing.element.PageMeta;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Para;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Radio;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Select;
|
||||||
|
import org.dspace.app.xmlui.wing.element.Text;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The form displayed for collections that do not have any harvesting settings active
|
||||||
|
* (i.e. do not have a row in the harvest_instance table)
|
||||||
|
*
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class ToggleCollectionHarvestingForm extends AbstractDSpaceTransformer
|
||||||
|
{
|
||||||
|
/** Language Strings */
|
||||||
|
private static final Message T_dspace_home =
|
||||||
|
message("xmlui.general.dspace_home");
|
||||||
|
|
||||||
|
private static final Message T_collection_trail = message("xmlui.administrative.collection.general.collection_trail");
|
||||||
|
private static final Message T_options_metadata = message("xmlui.administrative.collection.general.options_metadata");
|
||||||
|
private static final Message T_options_roles = message("xmlui.administrative.collection.general.options_roles");
|
||||||
|
private static final Message T_main_head = message("xmlui.administrative.collection.EditCollectionMetadataForm.main_head");
|
||||||
|
|
||||||
|
private static final Message T_options_harvest = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest");
|
||||||
|
private static final Message T_title = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.title");
|
||||||
|
private static final Message T_trail = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.trail");
|
||||||
|
|
||||||
|
private static final Message T_label_source = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.label_source");
|
||||||
|
private static final Message T_source_normal = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_normal");
|
||||||
|
private static final Message T_source_harvested = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_harvested");
|
||||||
|
|
||||||
|
private static final Message T_submit_return = message("xmlui.general.return");
|
||||||
|
private static final Message T_submit_save = message("xmlui.administrative.collection.GeneralCollectionHarvestingForm.submit_save");
|
||||||
|
|
||||||
|
|
||||||
|
public void addPageMeta(PageMeta pageMeta) throws WingException
|
||||||
|
{
|
||||||
|
pageMeta.addMetadata("title").addContent(T_title);
|
||||||
|
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
|
||||||
|
pageMeta.addTrail().addContent(T_collection_trail);
|
||||||
|
pageMeta.addTrail().addContent(T_trail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addBody(Body body) throws WingException, SQLException, AuthorizeException
|
||||||
|
{
|
||||||
|
int collectionID = parameters.getParameterAsInteger("collectionID", -1);
|
||||||
|
Collection thisCollection = Collection.find(context, collectionID);
|
||||||
|
|
||||||
|
// This should always be null; it's an error condition for this tranformer to be called when
|
||||||
|
// a harvest instance exists for this collection
|
||||||
|
HarvestedCollection hc = HarvestedCollection.find(context, collectionID);
|
||||||
|
String baseURL = contextPath + "/admin/collection?administrative-continue=" + knot.getId();
|
||||||
|
|
||||||
|
// DIVISION: main
|
||||||
|
Division main = body.addInteractiveDivision("collection-harvesting-setup",contextPath+"/admin/collection",Division.METHOD_MULTIPART,"primary administrative collection");
|
||||||
|
main.setHead(T_main_head.parameterize(thisCollection.getMetadata("name")));
|
||||||
|
|
||||||
|
List options = main.addList("options",List.TYPE_SIMPLE,"horizontal");
|
||||||
|
options.addItem().addXref(baseURL+"&submit_metadata",T_options_metadata);
|
||||||
|
options.addItem().addXref(baseURL+"&submit_roles",T_options_roles);
|
||||||
|
options.addItem().addHighlight("bold").addXref(baseURL+"&submit_harvesting",T_options_harvest);
|
||||||
|
|
||||||
|
|
||||||
|
// The top-level, all-setting, countent source radio button
|
||||||
|
List harvestSource = main.addList("harvestSource", "form");
|
||||||
|
|
||||||
|
harvestSource.addLabel(T_label_source);
|
||||||
|
Radio source = harvestSource.addItem().addRadio("source");
|
||||||
|
source.addOption(hc == null, "source_normal", T_source_normal);
|
||||||
|
source.addOption(hc != null, "source_harvested", T_source_harvested);
|
||||||
|
|
||||||
|
Para buttonList = main.addPara();
|
||||||
|
buttonList.addButton("submit_save").setValue(T_submit_save);
|
||||||
|
buttonList.addButton("submit_return").setValue(T_submit_return);
|
||||||
|
|
||||||
|
main.addHidden("administrative-continue").setValue(knot.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -58,6 +58,7 @@ import org.dspace.app.xmlui.configuration.XMLUIConfiguration;
|
|||||||
import org.dspace.app.xmlui.utils.AuthenticationUtil;
|
import org.dspace.app.xmlui.utils.AuthenticationUtil;
|
||||||
import org.dspace.app.xmlui.utils.ContextUtil;
|
import org.dspace.app.xmlui.utils.ContextUtil;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.harvest.OAIHarvester;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a wrapper servlet around the cocoon servlet that prefroms two functions, 1) it
|
* This is a wrapper servlet around the cocoon servlet that prefroms two functions, 1) it
|
||||||
@@ -212,6 +213,16 @@ public class DSpaceCocoonServletFilter implements Filter
|
|||||||
"DSpace configuration directory. \n\n",t);
|
"DSpace configuration directory. \n\n",t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ConfigurationManager.getBooleanProperty("harvester.autoStart"))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
OAIHarvester.startNewScheduler();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* DSpaceOREGenerator.java
|
||||||
|
*
|
||||||
|
* Version: $Revision: 1.0 $
|
||||||
|
*
|
||||||
|
* Date: $Date: 2008/06/30 05:30:55 $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
|
||||||
|
* Institute of Technology. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||||
|
* Massachusetts Institute of Technology nor the names of their
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.app.xmlui.cocoon;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.cocoon.ProcessingException;
|
||||||
|
import org.apache.cocoon.ResourceNotFoundException;
|
||||||
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.apache.cocoon.generation.AbstractGenerator;
|
||||||
|
import org.dspace.app.xmlui.objectmanager.AbstractAdapter;
|
||||||
|
import org.dspace.app.xmlui.objectmanager.ContainerAdapter;
|
||||||
|
import org.dspace.app.xmlui.objectmanager.ItemAdapter;
|
||||||
|
import org.dspace.app.xmlui.objectmanager.RepositoryAdapter;
|
||||||
|
import org.dspace.app.xmlui.utils.ContextUtil;
|
||||||
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.crosswalk.CrosswalkException;
|
||||||
|
import org.dspace.content.crosswalk.DisseminationCrosswalk;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.LogManager;
|
||||||
|
import org.dspace.core.PluginManager;
|
||||||
|
import org.dspace.handle.HandleManager;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jdom.output.SAXOutputter;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an ORE aggregation of a DSpace Item. The object to be rendered should be an item identified by pasing
|
||||||
|
* in one of the two parameters: handle or internal. The fragment parameter determines the encoding format for
|
||||||
|
* the aggregation; only Atom is supported at this time.
|
||||||
|
|
||||||
|
* @author Alexey Maslov
|
||||||
|
*/
|
||||||
|
public class DSpaceOREGenerator extends AbstractGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generate the ORE Aggregation.
|
||||||
|
*/
|
||||||
|
public void generate() throws IOException, SAXException,
|
||||||
|
ProcessingException {
|
||||||
|
try {
|
||||||
|
// Grab the context.
|
||||||
|
Context context = ContextUtil.obtainContext(objectModel);
|
||||||
|
|
||||||
|
Item item = getItem(context);
|
||||||
|
if (item == null)
|
||||||
|
throw new ResourceNotFoundException("Unable to locate object.");
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate and execute the ORE plugin
|
||||||
|
SAXOutputter out = new SAXOutputter(contentHandler);
|
||||||
|
DisseminationCrosswalk xwalk = (DisseminationCrosswalk)PluginManager.getNamedPlugin(DisseminationCrosswalk.class,"ore");
|
||||||
|
|
||||||
|
Element ore = xwalk.disseminateElement(item);
|
||||||
|
out.output(ore);
|
||||||
|
|
||||||
|
/* Generate the METS document
|
||||||
|
contentHandler.startDocument();
|
||||||
|
adapter.renderMETS(contentHandler,lexicalHandler);
|
||||||
|
contentHandler.endDocument();*/
|
||||||
|
|
||||||
|
} catch (JDOMException je) {
|
||||||
|
throw new ProcessingException(je);
|
||||||
|
} catch (AuthorizeException ae) {
|
||||||
|
throw new ProcessingException(ae);
|
||||||
|
} catch (CrosswalkException ce) {
|
||||||
|
throw new ProcessingException(ce);
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
throw new ProcessingException(sqle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Item getItem(Context context) throws SQLException, CrosswalkException
|
||||||
|
{
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
String contextPath = request.getContextPath();
|
||||||
|
|
||||||
|
// Determine the correct adatper to use for this item
|
||||||
|
String handle = parameters.getParameter("handle",null);
|
||||||
|
String internal = parameters.getParameter("internal",null);
|
||||||
|
|
||||||
|
if (handle != null)
|
||||||
|
{
|
||||||
|
// Specified using a regular handle.
|
||||||
|
DSpaceObject dso = HandleManager.resolveToObject(context, handle);
|
||||||
|
|
||||||
|
// Handles can be either items or containers.
|
||||||
|
if (dso instanceof Item)
|
||||||
|
return (Item)dso;
|
||||||
|
else
|
||||||
|
throw new CrosswalkException("ORE dissemination only available for DSpace Items.");
|
||||||
|
}
|
||||||
|
else if (internal != null)
|
||||||
|
{
|
||||||
|
// Internal identifier, format: "type:id".
|
||||||
|
String[] parts = internal.split(":");
|
||||||
|
|
||||||
|
if (parts.length == 2)
|
||||||
|
{
|
||||||
|
String type = parts[0];
|
||||||
|
int id = Integer.valueOf(parts[1]);
|
||||||
|
|
||||||
|
if ("item".equals(type))
|
||||||
|
{
|
||||||
|
Item item = Item.find(context,id);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new CrosswalkException("ORE dissemination only available for DSpace Items.");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -47,6 +47,7 @@ importClass(Packages.org.dspace.content.Bundle);
|
|||||||
importClass(Packages.org.dspace.content.Item);
|
importClass(Packages.org.dspace.content.Item);
|
||||||
importClass(Packages.org.dspace.content.Collection);
|
importClass(Packages.org.dspace.content.Collection);
|
||||||
importClass(Packages.org.dspace.content.Community);
|
importClass(Packages.org.dspace.content.Community);
|
||||||
|
importClass(Packages.org.dspace.harvest.HarvestedCollection);
|
||||||
importClass(Packages.org.dspace.eperson.EPerson);
|
importClass(Packages.org.dspace.eperson.EPerson);
|
||||||
importClass(Packages.org.dspace.eperson.Group);
|
importClass(Packages.org.dspace.eperson.Group);
|
||||||
|
|
||||||
@@ -2217,6 +2218,11 @@ function doEditCollection(collectionID,newCollectionP)
|
|||||||
// go assign colection roles
|
// go assign colection roles
|
||||||
doAssignCollectionRoles(collectionID);
|
doAssignCollectionRoles(collectionID);
|
||||||
}
|
}
|
||||||
|
else if (cocoon.request.get("submit_harvesting"))
|
||||||
|
{
|
||||||
|
// edit collection harvesting settings
|
||||||
|
doEditCollectionHarvesting(collectionID);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This case should never happen but to prevent an infinite loop
|
// This case should never happen but to prevent an infinite loop
|
||||||
@@ -2243,7 +2249,8 @@ function doEditCollectionMetadata(collectionID)
|
|||||||
assertEditCollection(collectionID);
|
assertEditCollection(collectionID);
|
||||||
result=null;
|
result=null;
|
||||||
|
|
||||||
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") || cocoon.request.get("submit_roles"))
|
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") ||
|
||||||
|
cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting"))
|
||||||
{
|
{
|
||||||
// return to the editCollection function which will determine where to go next.
|
// return to the editCollection function which will determine where to go next.
|
||||||
return null;
|
return null;
|
||||||
@@ -2299,7 +2306,8 @@ function doAssignCollectionRoles(collectionID)
|
|||||||
result = null;
|
result = null;
|
||||||
|
|
||||||
|
|
||||||
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") || cocoon.request.get("submit_roles"))
|
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") ||
|
||||||
|
cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting"))
|
||||||
{
|
{
|
||||||
// return to the editCollection function which will determine where to go next.
|
// return to the editCollection function which will determine where to go next.
|
||||||
return null;
|
return null;
|
||||||
@@ -2391,6 +2399,110 @@ function doAssignCollectionRoles(collectionID)
|
|||||||
}while(true);
|
}while(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up various harvesting options.
|
||||||
|
* From here the user can also move on to edit roles and edit metadata screen.
|
||||||
|
*/
|
||||||
|
function doSetupCollectionHarvesting(collectionID)
|
||||||
|
{
|
||||||
|
assertEditCollection(collectionID);
|
||||||
|
|
||||||
|
var result = null;
|
||||||
|
var oaiProviderValue = null;
|
||||||
|
var oaiSetIdValue = null;
|
||||||
|
var metadataFormatValue = null;
|
||||||
|
var harvestLevelValue = null;
|
||||||
|
|
||||||
|
do {
|
||||||
|
sendPageAndWait("admin/collection/setupHarvesting",{"collectionID":collectionID,"oaiProviderValue":oaiProviderValue,"oaiSetIdValue":oaiSetIdValue,"metadataFormatValue":metadataFormatValue,"harvestLevelValue":harvestLevelValue},result);
|
||||||
|
result = null;
|
||||||
|
oaiProviderValue = cocoon.request.get("oai_provider");
|
||||||
|
oaiSetIdValue = cocoon.request.get("oai_setid");
|
||||||
|
metadataFormatValue = cocoon.request.get("metadata_format");
|
||||||
|
harvestLevelValue = cocoon.request.get("harvest_level");
|
||||||
|
|
||||||
|
assertEditCollection(collectionID);
|
||||||
|
|
||||||
|
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") ||
|
||||||
|
cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting"))
|
||||||
|
{
|
||||||
|
// return to the editCollection function which will determine where to go next.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_save"))
|
||||||
|
{
|
||||||
|
// Save updates
|
||||||
|
result = FlowContainerUtils.processSetupCollectionHarvesting(getDSContext(), collectionID, cocoon.request);
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_test"))
|
||||||
|
{
|
||||||
|
// Ping the OAI server and verify that the address/set/metadata combo is present there
|
||||||
|
// Can get this either in a single GetRecords OAI request or via two separate ones: ListSets and ListMetadataFormats
|
||||||
|
result = FlowContainerUtils.testOAISettings(getDSContext(), cocoon.request);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (!result.getContinue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit existing harvesting options.
|
||||||
|
* From here the user can also move on to edit roles and edit metadata screen.
|
||||||
|
*/
|
||||||
|
function doEditCollectionHarvesting(collectionID)
|
||||||
|
{
|
||||||
|
assertEditCollection(collectionID);
|
||||||
|
|
||||||
|
var result = null;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// If this collection's havresting is not set up properly, redirect to the setup screen
|
||||||
|
if (HarvestedCollection.find(getDSContext(), collectionID) == null) {
|
||||||
|
sendPageAndWait("admin/collection/toggleHarvesting",{"collectionID":collectionID},result);
|
||||||
|
}
|
||||||
|
else if (!HarvestedCollection.isHarvestable(getDSContext(), collectionID)) {
|
||||||
|
doSetupCollectionHarvesting(collectionID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sendPageAndWait("admin/collection/editHarvesting",{"collectionID":collectionID},result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = null;
|
||||||
|
assertEditCollection(collectionID);
|
||||||
|
|
||||||
|
if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") ||
|
||||||
|
cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting"))
|
||||||
|
{
|
||||||
|
// return to the editCollection function which will determine where to go next.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_save"))
|
||||||
|
{
|
||||||
|
// Save updates
|
||||||
|
result = FlowContainerUtils.processSetupCollectionHarvesting(getDSContext(), collectionID, cocoon.request);
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_import_now"))
|
||||||
|
{
|
||||||
|
// Test the settings and run the import immediately
|
||||||
|
result = FlowContainerUtils.processRunCollectionHarvest(getDSContext(), collectionID, cocoon.request);
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_reimport"))
|
||||||
|
{
|
||||||
|
// Test the settings and run the import immediately
|
||||||
|
result = FlowContainerUtils.processReimportCollection(getDSContext(), collectionID, cocoon.request);
|
||||||
|
}
|
||||||
|
else if (cocoon.request.get("submit_change"))
|
||||||
|
{
|
||||||
|
doSetupCollectionHarvesting(collectionID);
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a specified collection role. Under the current implementation, the only roles this applies to
|
* Delete a specified collection role. Under the current implementation, the only roles this applies to
|
||||||
* directly are the workflow steps. Admin and submitter authorizations cannot be deleted once formed, and
|
* directly are the workflow steps. Admin and submitter authorizations cannot be deleted once formed, and
|
||||||
|
@@ -85,6 +85,9 @@ to administer DSpace.
|
|||||||
<map:transformer name="SearchItemForm" src="org.dspace.app.xmlui.aspect.administrative.mapper.SearchItemForm"/>
|
<map:transformer name="SearchItemForm" src="org.dspace.app.xmlui.aspect.administrative.mapper.SearchItemForm"/>
|
||||||
|
|
||||||
<map:transformer name="EditCollectionMetadataForm" src="org.dspace.app.xmlui.aspect.administrative.collection.EditCollectionMetadataForm"/>
|
<map:transformer name="EditCollectionMetadataForm" src="org.dspace.app.xmlui.aspect.administrative.collection.EditCollectionMetadataForm"/>
|
||||||
|
<map:transformer name="ToggleCollectionHarvestingForm" src="org.dspace.app.xmlui.aspect.administrative.collection.ToggleCollectionHarvestingForm"/>
|
||||||
|
<map:transformer name="SetupCollectionHarvestingForm" src="org.dspace.app.xmlui.aspect.administrative.collection.SetupCollectionHarvestingForm"/>
|
||||||
|
<map:transformer name="EditCollectionHarvestingForm" src="org.dspace.app.xmlui.aspect.administrative.collection.EditCollectionHarvestingForm"/>
|
||||||
<map:transformer name="AssignCollectionRoles" src="org.dspace.app.xmlui.aspect.administrative.collection.AssignCollectionRoles"/>
|
<map:transformer name="AssignCollectionRoles" src="org.dspace.app.xmlui.aspect.administrative.collection.AssignCollectionRoles"/>
|
||||||
<map:transformer name="DeleteCollectionRoleConfirm" src="org.dspace.app.xmlui.aspect.administrative.collection.DeleteCollectionRoleConfirm"/>
|
<map:transformer name="DeleteCollectionRoleConfirm" src="org.dspace.app.xmlui.aspect.administrative.collection.DeleteCollectionRoleConfirm"/>
|
||||||
<map:transformer name="DeleteCollectionConfirm" src="org.dspace.app.xmlui.aspect.administrative.collection.DeleteCollectionConfirm"/>
|
<map:transformer name="DeleteCollectionConfirm" src="org.dspace.app.xmlui.aspect.administrative.collection.DeleteCollectionConfirm"/>
|
||||||
@@ -636,6 +639,37 @@ to administer DSpace.
|
|||||||
</map:transform>
|
</map:transform>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
|
<!-- Harvesting options setup form, used for collections that are being edited or set up
|
||||||
|
for the first time -->
|
||||||
|
<map:match pattern="admin/collection/setupHarvesting">
|
||||||
|
<map:transform type="SetupCollectionHarvestingForm">
|
||||||
|
<map:parameter name="collectionID" value="{flow-attribute:collectionID}"/>
|
||||||
|
<map:parameter name="errors" value="{flow-attribute:errors}"/>
|
||||||
|
<map:parameter name="oaiProviderValue" value="{flow-attribute:oaiProviderValue}"/>
|
||||||
|
<map:parameter name="oaiSetIdValue" value="{flow-attribute:oaiSetIdValue}"/>
|
||||||
|
<map:parameter name="metadataFormatValue" value="{flow-attribute:metadataFormatValue}"/>
|
||||||
|
<map:parameter name="harvestLevelValue" value="{flow-attribute:harvestLevelValue}"/>
|
||||||
|
</map:transform>
|
||||||
|
</map:match>
|
||||||
|
|
||||||
|
<!-- Harvesting options setup form, used for collections that are being edited or set up
|
||||||
|
for the first time -->
|
||||||
|
<map:match pattern="admin/collection/editHarvesting">
|
||||||
|
<map:transform type="EditCollectionHarvestingForm">
|
||||||
|
<map:parameter name="collectionID" value="{flow-attribute:collectionID}"/>
|
||||||
|
<map:parameter name="errors" value="{flow-attribute:errors}"/>
|
||||||
|
</map:transform>
|
||||||
|
</map:match>
|
||||||
|
|
||||||
|
<!-- Initial toggle -->
|
||||||
|
<map:match pattern="admin/collection/toggleHarvesting">
|
||||||
|
<map:transform type="ToggleCollectionHarvestingForm">
|
||||||
|
<map:parameter name="collectionID" value="{flow-attribute:collectionID}"/>
|
||||||
|
</map:transform>
|
||||||
|
</map:match>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Confirmation screen for deleteing one of the standard authorization groups -->
|
<!-- Confirmation screen for deleteing one of the standard authorization groups -->
|
||||||
<map:match pattern="admin/collection/deleteRole">
|
<map:match pattern="admin/collection/deleteRole">
|
||||||
<map:transform type="DeleteCollectionRoleConfirm">
|
<map:transform type="DeleteCollectionRoleConfirm">
|
||||||
|
@@ -1470,6 +1470,72 @@
|
|||||||
<message key="xmlui.administrative.collection.CreateCollectionForm.trail">Create Collection</message>
|
<message key="xmlui.administrative.collection.CreateCollectionForm.trail">Create Collection</message>
|
||||||
<message key="xmlui.administrative.collection.CreateCollectionForm.main_head">Enter Metadata for a New Collection of {0}</message>
|
<message key="xmlui.administrative.collection.CreateCollectionForm.main_head">Enter Metadata for a New Collection of {0}</message>
|
||||||
<message key="xmlui.administrative.collection.CreateCollectionForm.submit_save">Create</message>
|
<message key="xmlui.administrative.collection.CreateCollectionForm.submit_save">Create</message>
|
||||||
|
|
||||||
|
<!-- General to the harvesting options under collection -->
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.title">Collection Harvesting Settings</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.trail">Harvesting</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.options_harvest">Content Source</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.label_source">Content source</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_normal">This is a standard DSpace collection</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.source_harvested">This collection harvests its content from an external source</message>
|
||||||
|
<message key="xmlui.administrative.collection.GeneralCollectionHarvestingForm.submit_save">Save</message>
|
||||||
|
|
||||||
|
<!-- org.dspace.app.xmlui.administrative.collection.SetupCollectionHarvestingForm.java -->
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.main_settings_head">Harvested Collection Location</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.options_head">Harvesting Options</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.label_oai_provider">OAI Provider</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.label_setid">OAI Set id</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.label_metadata_format">Metadata Format</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.help_oaiurl">The url of the target repository's OAI provider service</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.error_oaiurl">You must provide a set id of the target collection.</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.help_oaisetid">The persistent identifier used by the OAI provider to desginate the target collection</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.error_oaisetid">You must provide a set id of the target collection.</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.label_harvest_level">Content being harvested</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.label_harvest_level">Content being harvested</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_only">Harvest metadata only.</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_and_ref">Harvest metadata and references to bitstreams (requires ORE support).</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.option_md_and_bs">Harvest metadata and bitstreams (requires ORE support).</message>
|
||||||
|
<message key="xmlui.administrative.collection.SetupCollectionHarvestingForm.submit_test">Test Settings</message>
|
||||||
|
|
||||||
|
<!-- org.dspace.app.xmlui.administrative.collection.EditCollectionHarvestingForm.java -->
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.main_settings_head">Harvested Collection Location</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_oai_provider">OAI Provider</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_setid">OAI Set id</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_metadata_format">Metadata format</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_level">Content being harvested</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_result">Last Harvest Result</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_result_new">This collection has not yet been harvested.</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.label_harvest_status">Current harvest status</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_ready">Collection ready for harvest</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_busy">Collection is currently being harvested</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_queued">Collection is in queue for harvest</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_oai_error">OAI error occured during last harvest</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.harvest_status_unknown_error">Unexpected error occured during last harvest</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_only">Harvest metadata only.</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_and_ref">Harvest metadata and references to bitstreams.</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.option_md_and_bs">Harvest metadata and bitstreams (full replication).</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.submit_change_settings">Change Settings</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.submit_import_now">Import Now</message>
|
||||||
|
<message key="xmlui.administrative.collection.EditCollectionHarvestingForm.submit_reimport_collection">Reset and Reimport Collection</message>
|
||||||
|
|
||||||
|
<message key="xmlui.administrative.ControlPanel.option_harvest">Harvesting</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_scheduler_head">Harvest Scheduler Controls</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_status">Status</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_actions">Actions</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_submit_start">Start Harvester</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_submit_reset">Reset Harvest Status</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_submit_resume">Resume</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_submit_pause">Pause</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_submit_stop">Stop</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_collections">Collections set up for harvesting</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_active">Active harvests</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_queued">Queued harvests</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_oai_errors">OAI errors</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_internal_errors">Internal errors</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_head_generator_settings">Generator Settings</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_oai_url">OAI-PMH URL</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_label_oai_source">ORE source</message>
|
||||||
|
<message key="xmlui.administrative.ControlPanel.harvest_head_harvester_settings">Harvester Settings</message>
|
||||||
|
|
||||||
<!-- General tags for community management -->
|
<!-- General tags for community management -->
|
||||||
<message key="xmlui.administrative.community.general.community_trail">Communities</message>
|
<message key="xmlui.administrative.community.general.community_trail">Communities</message>
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
pool-max="16" src="org.apache.cocoon.generation.DirectoryGenerator"/>
|
pool-max="16" src="org.apache.cocoon.generation.DirectoryGenerator"/>
|
||||||
<map:generator name="DSpaceFeedGenerator" src="org.dspace.app.xmlui.cocoon.DSpaceFeedGenerator"/>
|
<map:generator name="DSpaceFeedGenerator" src="org.dspace.app.xmlui.cocoon.DSpaceFeedGenerator"/>
|
||||||
<map:generator name="DSpaceMETSGenerator" src="org.dspace.app.xmlui.cocoon.DSpaceMETSGenerator"/>
|
<map:generator name="DSpaceMETSGenerator" src="org.dspace.app.xmlui.cocoon.DSpaceMETSGenerator"/>
|
||||||
|
<map:generator name="DSpaceOREGenerator" src="org.dspace.app.xmlui.cocoon.DSpaceOREGenerator"/>
|
||||||
<map:generator name="notifying" src="org.apache.cocoon.sitemap.NotifyingGenerator"/>
|
<map:generator name="notifying" src="org.apache.cocoon.sitemap.NotifyingGenerator"/>
|
||||||
<map:generator name="exception" src="org.apache.cocoon.generation.ExceptionGenerator"/>
|
<map:generator name="exception" src="org.apache.cocoon.generation.ExceptionGenerator"/>
|
||||||
</map:generators>
|
</map:generators>
|
||||||
@@ -309,16 +310,30 @@
|
|||||||
|
|
||||||
|
|
||||||
<map:match pattern="metadata/**">
|
<map:match pattern="metadata/**">
|
||||||
<map:match pattern="metadata/handle/*/*/**">
|
<map:match pattern="metadata/handle/*/*/mets.xml">
|
||||||
<map:generate type="DSpaceMETSGenerator">
|
<map:generate type="DSpaceMETSGenerator">
|
||||||
|
<map:parameter name="handle" value="{1}/{2}"/>
|
||||||
|
<!--<map:parameter name="extra" value="{3}"/>-->
|
||||||
|
</map:generate>
|
||||||
|
<map:serialize type="xml"/>
|
||||||
|
</map:match>
|
||||||
|
<map:match pattern="metadata/internal/*/*/mets.xml">
|
||||||
|
<map:generate type="DSpaceMETSGenerator">
|
||||||
|
<map:parameter name="internal" value="{1}:{2}"/>
|
||||||
|
<!--<map:parameter name="extra" value="{3}"/>-->
|
||||||
|
</map:generate>
|
||||||
|
<map:serialize type="xml"/>
|
||||||
|
</map:match>
|
||||||
|
|
||||||
|
<map:match pattern="metadata/handle/*/*/ore.xml**">
|
||||||
|
<map:generate type="DSpaceOREGenerator">
|
||||||
<map:parameter name="handle" value="{1}/{2}"/>
|
<map:parameter name="handle" value="{1}/{2}"/>
|
||||||
<map:parameter name="extra" value="{3}"/>
|
<map:parameter name="extra" value="{3}"/>
|
||||||
</map:generate>
|
</map:generate>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
<map:match pattern="metadata/internal/*/*/ore.xml**">
|
||||||
<map:match pattern="metadata/internal/*/*/**">
|
<map:generate type="DSpaceOREGenerator">
|
||||||
<map:generate type="DSpaceMETSGenerator">
|
|
||||||
<map:parameter name="internal" value="{1}:{2}"/>
|
<map:parameter name="internal" value="{1}:{2}"/>
|
||||||
<map:parameter name="extra" value="{3}"/>
|
<map:parameter name="extra" value="{3}"/>
|
||||||
</map:generate>
|
</map:generate>
|
||||||
|
@@ -53,6 +53,9 @@
|
|||||||
xmlns:dim="http://www.dspace.org/xmlns/dspace/dim"
|
xmlns:dim="http://www.dspace.org/xmlns/dspace/dim"
|
||||||
xmlns:xlink="http://www.w3.org/TR/xlink/"
|
xmlns:xlink="http://www.w3.org/TR/xlink/"
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:ore="http://www.openarchives.org/ore/terms/"
|
||||||
|
xmlns:oreatom="http://www.openarchives.org/ore/atom/"
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xmlns:xalan="http://xml.apache.org/xalan"
|
xmlns:xalan="http://xml.apache.org/xalan"
|
||||||
xmlns:encoder="xalan://java.net.URLEncoder"
|
xmlns:encoder="xalan://java.net.URLEncoder"
|
||||||
@@ -394,28 +397,32 @@
|
|||||||
|
|
||||||
<!-- Generate the bitstream information from the file section -->
|
<!-- Generate the bitstream information from the file section -->
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="not(./mets:fileSec/mets:fileGrp[@USE='CONTENT'])">
|
<xsl:when test="./mets:fileSec/mets:fileGrp[@USE='CONTENT' or @USE='ORIGINAL']">
|
||||||
<h2><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-head</i18n:text></h2>
|
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='CONTENT' or @USE='ORIGINAL']">
|
||||||
<table class="ds-table file-list">
|
<xsl:with-param name="context" select="."/>
|
||||||
<tr class="ds-table-header-row">
|
<xsl:with-param name="primaryBitstream" select="./mets:structMap[@TYPE='LOGICAL']/mets:div[@TYPE='DSpace Item']/mets:fptr/@FILEID"/>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-file</i18n:text></th>
|
</xsl:apply-templates>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-size</i18n:text></th>
|
</xsl:when>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-format</i18n:text></th>
|
<!-- Special case for handling ORE resource maps stored as DSpace bitstreams -->
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-view</i18n:text></th>
|
<xsl:when test="./mets:fileSec/mets:fileGrp[@USE='ORE']">
|
||||||
</tr>
|
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='ORE']"/>
|
||||||
<tr>
|
</xsl:when>
|
||||||
<td colspan="4">
|
<xsl:otherwise>
|
||||||
<p><i18n:text>xmlui.dri2xhtml.METS-1.0.item-no-files</i18n:text></p>
|
<h2><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-head</i18n:text></h2>
|
||||||
</td>
|
<table class="ds-table file-list">
|
||||||
</tr>
|
<tr class="ds-table-header-row">
|
||||||
</table>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-file</i18n:text></th>
|
||||||
</xsl:when>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-size</i18n:text></th>
|
||||||
<xsl:otherwise>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-format</i18n:text></th>
|
||||||
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='CONTENT']">
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-view</i18n:text></th>
|
||||||
<xsl:with-param name="context" select="."/>
|
</tr>
|
||||||
<xsl:with-param name="primaryBitstream" select="./mets:structMap[@TYPE='LOGICAL']/mets:div[@TYPE='DSpace Item']/mets:fptr/@FILEID"/>
|
<tr>
|
||||||
</xsl:apply-templates>
|
<td colspan="4">
|
||||||
</xsl:otherwise>
|
<p><i18n:text>xmlui.dri2xhtml.METS-1.0.item-no-files</i18n:text></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
|
|
||||||
<!-- Generate the license information from the file section -->
|
<!-- Generate the license information from the file section -->
|
||||||
@@ -633,28 +640,32 @@
|
|||||||
|
|
||||||
<!-- Generate the bitstream information from the file section -->
|
<!-- Generate the bitstream information from the file section -->
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="not(./mets:fileSec/mets:fileGrp[@USE='CONTENT'])">
|
<xsl:when test="./mets:fileSec/mets:fileGrp[@USE='CONTENT' or @USE='ORIGINAL']">
|
||||||
<h2><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-head</i18n:text></h2>
|
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='CONTENT' or @USE='ORIGINAL']">
|
||||||
<table class="ds-table file-list">
|
<xsl:with-param name="context" select="."/>
|
||||||
<tr class="ds-table-header-row">
|
<xsl:with-param name="primaryBitstream" select="./mets:structMap[@TYPE='LOGICAL']/mets:div[@TYPE='DSpace Item']/mets:fptr/@FILEID"/>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-file</i18n:text></th>
|
</xsl:apply-templates>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-size</i18n:text></th>
|
</xsl:when>
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-format</i18n:text></th>
|
<!-- Special case for handling ORE resource maps stored as DSpace bitstreams -->
|
||||||
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-view</i18n:text></th>
|
<xsl:when test="./mets:fileSec/mets:fileGrp[@USE='ORE']">
|
||||||
</tr>
|
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='ORE']"/>
|
||||||
<tr>
|
</xsl:when>
|
||||||
<td colspan="4">
|
<xsl:otherwise>
|
||||||
<p><i18n:text>xmlui.dri2xhtml.METS-1.0.item-no-files</i18n:text></p>
|
<h2><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-head</i18n:text></h2>
|
||||||
</td>
|
<table class="ds-table file-list">
|
||||||
</tr>
|
<tr class="ds-table-header-row">
|
||||||
</table>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-file</i18n:text></th>
|
||||||
</xsl:when>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-size</i18n:text></th>
|
||||||
<xsl:otherwise>
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-format</i18n:text></th>
|
||||||
<xsl:apply-templates select="./mets:fileSec/mets:fileGrp[@USE='CONTENT']">
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-view</i18n:text></th>
|
||||||
<xsl:with-param name="context" select="."/>
|
</tr>
|
||||||
<xsl:with-param name="primaryBitstream" select="./mets:structMap[@TYPE='LOGICAL']/mets:div[@TYPE='DSpace Item']/mets:fptr/@FILEID"/>
|
<tr>
|
||||||
</xsl:apply-templates>
|
<td colspan="4">
|
||||||
</xsl:otherwise>
|
<p><i18n:text>xmlui.dri2xhtml.METS-1.0.item-no-files</i18n:text></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
|
|
||||||
|
|
||||||
@@ -749,8 +760,111 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Rendering the file list from an Atom ReM bitstream stored in the ORE bundle -->
|
||||||
|
<xsl:template match="mets:fileGrp[@USE='ORE']">
|
||||||
|
<xsl:variable name="AtomMapURL" select="concat('cocoon:/',substring-after(mets:file/mets:FLocat[@LOCTYPE='URL']//@*[local-name(.)='href'],$context-path))"/>
|
||||||
|
<h2><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-head</i18n:text></h2>
|
||||||
|
<table class="ds-table file-list">
|
||||||
|
<thead>
|
||||||
|
<tr class="ds-table-header-row">
|
||||||
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-file</i18n:text></th>
|
||||||
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-size</i18n:text></th>
|
||||||
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-format</i18n:text></th>
|
||||||
|
<th><i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-view</i18n:text></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<xsl:apply-templates select="document($AtomMapURL)/atom:entry/atom:link[@rel='http://www.openarchives.org/ore/terms/aggregates']">
|
||||||
|
<xsl:sort select="@title"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Iterate over the links in the ORE resource maps and make them into bitstream references in the file section -->
|
||||||
|
<xsl:template match="atom:link[@rel='http://www.openarchives.org/ore/terms/aggregates']">
|
||||||
|
<tr>
|
||||||
|
<xsl:attribute name="class">
|
||||||
|
<xsl:text>ds-table-row </xsl:text>
|
||||||
|
<xsl:if test="(position() mod 2 = 0)">even </xsl:if>
|
||||||
|
<xsl:if test="(position() mod 2 = 1)">odd </xsl:if>
|
||||||
|
</xsl:attribute>
|
||||||
|
<td>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="@href"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:attribute name="title">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@title">
|
||||||
|
<xsl:value-of select="@title"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="@href"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="string-length(@title) > 50">
|
||||||
|
<xsl:variable name="title_length" select="string-length(@title)"/>
|
||||||
|
<xsl:value-of select="substring(@title,1,15)"/>
|
||||||
|
<xsl:text> ... </xsl:text>
|
||||||
|
<xsl:value-of select="substring(@title,$title_length - 25,$title_length)"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@title">
|
||||||
|
<xsl:value-of select="@title"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="@href"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<!-- File size always comes in bytes and thus needs conversion -->
|
||||||
|
<td>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@length < 1000">
|
||||||
|
<xsl:value-of select="@length"/>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.size-bytes</i18n:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@length < 1000000">
|
||||||
|
<xsl:value-of select="substring(string(@length div 1000),1,5)"/>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.size-kilobytes</i18n:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@length < 1000000001">
|
||||||
|
<xsl:value-of select="substring(string(@length div 1000000),1,5)"/>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.size-megabytes</i18n:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@length > 1000000000">
|
||||||
|
<xsl:value-of select="substring(string(@length div 1000000000),1,5)"/>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.size-gigabytes</i18n:text>
|
||||||
|
</xsl:when>
|
||||||
|
<!-- When one isn't available -->
|
||||||
|
<xsl:otherwise><xsl:text>n/a</xsl:text></xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</td>
|
||||||
|
<!-- Currently format carries forward the mime type. In the original DSpace, this
|
||||||
|
would get resolved to an application via the Bitstream Registry, but we are
|
||||||
|
constrained by the capabilities of METS and can't really pass that info through. -->
|
||||||
|
<td>
|
||||||
|
<xsl:value-of select="substring-before(@type,'/')"/>
|
||||||
|
<xsl:text>/</xsl:text>
|
||||||
|
<xsl:value-of select="substring-after(@type,'/')"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="@href"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.item-files-viewOpen</i18n:text>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- A community rendered in the detailView pattern; default way of viewing a community. -->
|
<!-- A community rendered in the detailView pattern; default way of viewing a community. -->
|
||||||
<xsl:template name="communityDetailView-DIM">
|
<xsl:template name="communityDetailView-DIM">
|
||||||
<div class="detail-view"> 
|
<div class="detail-view"> 
|
||||||
|
@@ -78,6 +78,12 @@
|
|||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-jxpath</groupId>
|
||||||
|
<artifactId>commons-jxpath</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
@@ -35,6 +35,9 @@ dspace.url = http://localhost:8080/jspui
|
|||||||
# DSpace host name - should match base URL. Do not include port number
|
# DSpace host name - should match base URL. Do not include port number
|
||||||
dspace.hostname = localhost
|
dspace.hostname = localhost
|
||||||
|
|
||||||
|
# The base URL of the OAI webapp (do not include /request).
|
||||||
|
dspace.oai.url = ${dspace.hostname}/oai
|
||||||
|
|
||||||
# Name of the site
|
# Name of the site
|
||||||
dspace.name = DSpace at My University
|
dspace.name = DSpace at My University
|
||||||
|
|
||||||
@@ -650,7 +653,11 @@ mets.submission.useCollectionTemplate = false
|
|||||||
# Crosswalk Plugins:
|
# Crosswalk Plugins:
|
||||||
plugin.named.org.dspace.content.crosswalk.IngestionCrosswalk = \
|
plugin.named.org.dspace.content.crosswalk.IngestionCrosswalk = \
|
||||||
org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS \
|
org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS \
|
||||||
org.dspace.content.crosswalk.NullIngestionCrosswalk = NIL
|
org.dspace.content.crosswalk.OREIngestionCrosswalk = ore \
|
||||||
|
org.dspace.content.crosswalk.NullIngestionCrosswalk = NIL \
|
||||||
|
org.dspace.content.crosswalk.QDCCrosswalk = qdc \
|
||||||
|
org.dspace.content.crosswalk.OAIDCIngestionCrosswalk = dc \
|
||||||
|
org.dspace.content.crosswalk.DIMIngestionCrosswalk = dim
|
||||||
|
|
||||||
plugin.selfnamed.org.dspace.content.crosswalk.IngestionCrosswalk = \
|
plugin.selfnamed.org.dspace.content.crosswalk.IngestionCrosswalk = \
|
||||||
org.dspace.content.crosswalk.XSLTIngestionCrosswalk
|
org.dspace.content.crosswalk.XSLTIngestionCrosswalk
|
||||||
@@ -660,7 +667,11 @@ plugin.named.org.dspace.content.crosswalk.DisseminationCrosswalk = \
|
|||||||
org.dspace.content.crosswalk.SimpleDCDisseminationCrosswalk = dc \
|
org.dspace.content.crosswalk.SimpleDCDisseminationCrosswalk = dc \
|
||||||
org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS \
|
org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS \
|
||||||
org.dspace.content.crosswalk.METSDisseminationCrosswalk = METS \
|
org.dspace.content.crosswalk.METSDisseminationCrosswalk = METS \
|
||||||
org.dspace.content.crosswalk.METSDisseminationCrosswalk = mets
|
org.dspace.content.crosswalk.METSDisseminationCrosswalk = mets \
|
||||||
|
org.dspace.content.crosswalk.OREDisseminationCrosswalk = ore \
|
||||||
|
org.dspace.content.crosswalk.QDCCrosswalk = qdc \
|
||||||
|
org.dspace.content.crosswalk.DIMDisseminationCrosswalk = dim
|
||||||
|
|
||||||
|
|
||||||
plugin.selfnamed.org.dspace.content.crosswalk.DisseminationCrosswalk = \
|
plugin.selfnamed.org.dspace.content.crosswalk.DisseminationCrosswalk = \
|
||||||
org.dspace.content.crosswalk.MODSDisseminationCrosswalk , \
|
org.dspace.content.crosswalk.MODSDisseminationCrosswalk , \
|
||||||
@@ -681,7 +692,7 @@ plugin.named.org.dspace.content.packager.PackageIngester = \
|
|||||||
|
|
||||||
# default synchronous dispatcher (same behavior as traditional DSpace)
|
# default synchronous dispatcher (same behavior as traditional DSpace)
|
||||||
event.dispatcher.default.class = org.dspace.event.BasicDispatcher
|
event.dispatcher.default.class = org.dspace.event.BasicDispatcher
|
||||||
event.dispatcher.default.consumers = search, browse, eperson
|
event.dispatcher.default.consumers = search, browse, eperson, harvester
|
||||||
|
|
||||||
# The noindex dispatcher will not create search or browse indexs (usefull for batch item imports)
|
# The noindex dispatcher will not create search or browse indexs (usefull for batch item imports)
|
||||||
event.dispatcher.noindex.class = org.dspace.event.BasicDispatcher
|
event.dispatcher.noindex.class = org.dspace.event.BasicDispatcher
|
||||||
@@ -699,6 +710,10 @@ event.consumer.browse.filters = Community|Collection|Item|Bundle+Add|Create|Modi
|
|||||||
event.consumer.eperson.class = org.dspace.eperson.EPersonConsumer
|
event.consumer.eperson.class = org.dspace.eperson.EPersonConsumer
|
||||||
event.consumer.eperson.filters = EPerson+Create
|
event.consumer.eperson.filters = EPerson+Create
|
||||||
|
|
||||||
|
# consumer to clean up harvesting data
|
||||||
|
event.consumer.harvester.class = org.dspace.harvest.HarvestConsumer
|
||||||
|
event.consumer.harvester.filters = Item+Delete
|
||||||
|
|
||||||
# test consumer for debugging and monitoring
|
# test consumer for debugging and monitoring
|
||||||
#event.consumer.test.class = org.dspace.event.TestConsumer
|
#event.consumer.test.class = org.dspace.event.TestConsumer
|
||||||
#event.consumer.test.filters = All+All
|
#event.consumer.test.filters = All+All
|
||||||
@@ -1688,3 +1703,48 @@ sword.on-behalf-of.enable = true
|
|||||||
plugin.named.org.dspace.sword.SWORDIngester = \
|
plugin.named.org.dspace.sword.SWORDIngester = \
|
||||||
org.dspace.sword.SWORDMETSIngester = http://purl.org/net/sword-types/METSDSpaceSIP \
|
org.dspace.sword.SWORDMETSIngester = http://purl.org/net/sword-types/METSDSpaceSIP \
|
||||||
org.dspace.sword.SimpleFileIngester = SimpleFileIngester
|
org.dspace.sword.SimpleFileIngester = SimpleFileIngester
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
#--------------OAI HARVESTING CONFIGURATIONS--------------------#
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
# These configs are only used by the OAI-ORE related functions #
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
|
### Harvester settings
|
||||||
|
|
||||||
|
# Crosswalk settings; the {name} value must correspond to a declated ingestion crosswalk
|
||||||
|
# harvester.oai.metadataformats.{name} = {namespace},{optional display name}
|
||||||
|
harvester.oai.metadataformats.dc = http://www.openarchives.org/OAI/2.0/oai_dc/, Simple Dublin Core
|
||||||
|
harvester.oai.metadataformats.qdc = http://purl.org/dc/terms/, Qualified Dublin Core
|
||||||
|
harvester.oai.metadataformats.dim = http://www.dspace.org/xmlns/dspace/dim, DSpace Intermediate Metadata
|
||||||
|
|
||||||
|
# Determines whether the harvester scheduling process should be started
|
||||||
|
# automatically when the DSpace webapp is deployed.
|
||||||
|
# default: false
|
||||||
|
harvester.autoStart=false
|
||||||
|
|
||||||
|
# How frequently the harvest scheduler checks the remote provider for updates,
|
||||||
|
# messured in minutes. The default vaule is 12 hours (or 720 minutes)
|
||||||
|
#harvester.harvestFrequency = 720
|
||||||
|
|
||||||
|
# How many harvest process threads the scheduler can spool up at once. Default value is 3.
|
||||||
|
#harvester.maxThreads = 3
|
||||||
|
|
||||||
|
# How much time passess before a harvest thread is terminated. The termination process
|
||||||
|
# waits for the current item to complete ingest and saves progress made up to that point.
|
||||||
|
# Measured in hours. Default value is 24.
|
||||||
|
#harvester.threadTimeout = 24
|
||||||
|
|
||||||
|
# When harvesting an item that contains an unknown schema or field within a schema what
|
||||||
|
# should the harvester do? Either add a new registry item for the field or schema, ignore
|
||||||
|
# the specific field or schema (importing everything else about the item), or fail with
|
||||||
|
# an error. The default value if undefined is: fail.
|
||||||
|
# Possible values: 'fail', 'add', or 'ignore'
|
||||||
|
harvester.unknownField = add
|
||||||
|
harvester.unknownSchema = fail
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
20
dspace/config/emails/harvesting_error
Normal file
20
dspace/config/emails/harvesting_error
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# E-mail sent to designated address when a harvest process fails
|
||||||
|
#
|
||||||
|
# Parameters: {0} Collection id
|
||||||
|
# {1} Date & time
|
||||||
|
# {2} Status flag
|
||||||
|
# {3} Exception message
|
||||||
|
# {4} Exception stack trace
|
||||||
|
#
|
||||||
|
# See org.dspace.core.Email for information on the format of this file.
|
||||||
|
#
|
||||||
|
Subject: DSpace: Harvesting Error
|
||||||
|
Collection {0} failed on harvest:
|
||||||
|
|
||||||
|
Date: {1}
|
||||||
|
Status Flag: {2}
|
||||||
|
|
||||||
|
{3}
|
||||||
|
|
||||||
|
Exception:
|
||||||
|
{4}
|
@@ -38,3 +38,4 @@ Crosswalks.rdf=org.dspace.app.oai.RDFCrosswalk
|
|||||||
# Crosswalks.mods=org.dspace.app.oai.PluginCrosswalk
|
# Crosswalks.mods=org.dspace.app.oai.PluginCrosswalk
|
||||||
# Crosswalks.mets=org.dspace.app.oai.PluginCrosswalk
|
# Crosswalks.mets=org.dspace.app.oai.PluginCrosswalk
|
||||||
# Crosswalks.qdc=org.dspace.app.oai.PluginCrosswalk
|
# Crosswalks.qdc=org.dspace.app.oai.PluginCrosswalk
|
||||||
|
# Crosswalks.dim=org.dspace.app.oai.PluginCrosswalk
|
||||||
|
@@ -109,6 +109,8 @@ CREATE SEQUENCE metadatavalue_seq;
|
|||||||
|
|
||||||
CREATE SEQUENCE group2group_seq;
|
CREATE SEQUENCE group2group_seq;
|
||||||
CREATE SEQUENCE group2groupcache_seq;
|
CREATE SEQUENCE group2groupcache_seq;
|
||||||
|
CREATE SEQUENCE harvested_collection_seq;
|
||||||
|
CREATE SEQUENCE harvested_item_seq;
|
||||||
|
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
-- BitstreamFormatRegistry table
|
-- BitstreamFormatRegistry table
|
||||||
@@ -739,4 +741,41 @@ values
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------
|
||||||
|
-- Create the harvest settings table
|
||||||
|
-------------------------------------------------------
|
||||||
|
-- Values used by the OAIHarvester to harvest a collection
|
||||||
|
-- HarvestInstance is the DAO class for this table
|
||||||
|
|
||||||
|
CREATE TABLE harvested_collection
|
||||||
|
(
|
||||||
|
collection_id INTEGER REFERENCES collection(collection_id) ON DELETE CASCADE,
|
||||||
|
harvest_type INTEGER,
|
||||||
|
oai_source VARCHAR,
|
||||||
|
oai_set_id VARCHAR,
|
||||||
|
harvest_message VARCHAR,
|
||||||
|
metadata_config_id VARCHAR,
|
||||||
|
harvest_status INTEGER,
|
||||||
|
harvest_start_time TIMESTAMP WITH TIME ZONE,
|
||||||
|
last_harvested TIMESTAMP WITH TIME ZONE,
|
||||||
|
id INTEGER PRIMARY KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX harvested_collection_fk_idx ON harvested_collection(collection_id);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE harvested_item
|
||||||
|
(
|
||||||
|
item_id INTEGER REFERENCES item(item_id) ON DELETE CASCADE,
|
||||||
|
last_harvested TIMESTAMP WITH TIME ZONE,
|
||||||
|
oai_id VARCHAR,
|
||||||
|
id INTEGER PRIMARY KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX harvested_item_fk_idx ON harvested_item(item_id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
5
pom.xml
5
pom.xml
@@ -494,6 +494,11 @@
|
|||||||
<artifactId>ojdbc14</artifactId>
|
<artifactId>ojdbc14</artifactId>
|
||||||
<version>10.2.0.2.0</version>
|
<version>10.2.0.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>oclc-harvester2</artifactId>
|
||||||
|
<version>0.1.12</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user