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 {
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested asc limit 1";
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested asc";
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
query, 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 {
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested desc limit 1";
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested desc";
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
query , 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);
}
}