Item deletion and tombstones supported. SF feature request #620656

git-svn-id: http://scm.dspace.org/svn/repo/trunk@453 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Robert Tansley
2002-10-21 13:56:10 +00:00
parent 8e368711ec
commit c97c8f38a9
16 changed files with 491 additions and 35 deletions

View File

@@ -183,9 +183,11 @@ CREATE TABLE EPersonGroup
------------------------------------------------------- -------------------------------------------------------
CREATE TABLE Item CREATE TABLE Item
( (
item_id INTEGER PRIMARY KEY, item_id INTEGER PRIMARY KEY,
submitter_id INTEGER REFERENCES EPerson(eperson_id), submitter_id INTEGER REFERENCES EPerson(eperson_id),
in_archive BOOL in_archive BOOL,
withdrawn BOOL,
withdrawal_date VARCHAR(21)
); );
------------------------------------------------------- -------------------------------------------------------

View File

@@ -57,15 +57,16 @@
<dspace:layout title="Delete Item" navbar="admin" locbar="link" parentlink="/admin" parenttitle="Administer"> <dspace:layout title="Delete Item" navbar="admin" locbar="link" parentlink="/admin" parenttitle="Administer">
<H1>Delete Item: <%= (handle == null ? item.getID() : handle) %></H1> <H1>Delete Item: <%= (handle == null ? String.valueOf(item.getID()) : handle) %></H1>
<P>Are you sure this item should be completely deleted?</P> <P>Are you sure this item should be completely deleted? Caution:
At present, no tombstone would be left.</P>
<dspace:item item="<%= item %>" style="full" /> <dspace:item item="<%= item %>" style="full" />
<form method=POST> <form method=POST>
<input type="hidden" name="item_id" value="<%= item.getID() %>"> <input type="hidden" name="item_id" value="<%= item.getID() %>">
<input type="hidden" name="action" value="<%= EditItemServlet.CONFIRM_DELETE_ITEM %>"> <input type="hidden" name="action" value="<%= EditItemServlet.CONFIRM_DELETE %>">
<center> <center>
<table width="70%"> <table width="70%">

View File

@@ -0,0 +1,84 @@
<%--
- confirm-withdraw-item.jsp
-
- Version: $Revision$
-
- Date: $Date$
-
- Copyright (c) 2001, 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.
--%>
<%--
- Confirm withdrawal of a item
-
- Attributes:
- item - item we may withdraw
--%>
<%@ page import="org.dspace.app.webui.servlet.admin.EditItemServlet" %>
<%@ page import="org.dspace.content.Item" %>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%
String handle = (String) request.getAttribute("handle");
Item item = (Item) request.getAttribute("item");
%>
<dspace:layout title="Withdraw Item" navbar="admin" locbar="link" parentlink="/admin" parenttitle="Administer">
<H1>Withdraw Item: <%= (handle == null ? String.valueOf(item.getID()) : handle) %></H1>
<P>Are you sure this item should be withdrawn from the archive?</P>
<dspace:item item="<%= item %>" style="full" />
<form method=POST>
<input type="hidden" name="item_id" value="<%= item.getID() %>">
<input type="hidden" name="action" value="<%= EditItemServlet.CONFIRM_WITHDRAW %>">
<center>
<table width="70%">
<tr>
<td align="left">
<input type="submit" name="submit" value="Withdraw">
</td>
<td align="right">
<input type="submit" name="submit_cancel" value="Cancel">
</td>
</tr>
</table>
</center>
</form>
</dspace:layout>

View File

@@ -50,6 +50,7 @@
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %> <%@ page import="java.util.Map" %>
@@ -59,6 +60,7 @@
<%@ page import="org.dspace.content.BitstreamFormat" %> <%@ page import="org.dspace.content.BitstreamFormat" %>
<%@ page import="org.dspace.content.Bundle" %> <%@ page import="org.dspace.content.Bundle" %>
<%@ page import="org.dspace.content.Collection" %> <%@ page import="org.dspace.content.Collection" %>
<%@ page import="org.dspace.content.DCDate" %>
<%@ page import="org.dspace.content.DCValue" %> <%@ page import="org.dspace.content.DCValue" %>
<%@ page import="org.dspace.content.Item" %> <%@ page import="org.dspace.content.Item" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ page import="org.dspace.core.ConfigurationManager" %>
@@ -68,6 +70,8 @@
String handle = (String) request.getAttribute("handle"); String handle = (String) request.getAttribute("handle");
Collection[] collections = (Collection[]) request.getAttribute("collections"); Collection[] collections = (Collection[]) request.getAttribute("collections");
DCType[] dcTypes = (DCType[]) request.getAttribute("dc.types"); DCType[] dcTypes = (DCType[]) request.getAttribute("dc.types");
DCDate withdrawalDate = item.getWithdrawalDate();
%> %>
<dspace:layout title="Edit Item" <dspace:layout title="Edit Item"
@@ -87,9 +91,32 @@
<td class="submitFormLabel">Item&nbsp;internal&nbsp;ID:</td> <td class="submitFormLabel">Item&nbsp;internal&nbsp;ID:</td>
<td class="standard"><%= item.getID() %></td> <td class="standard"><%= item.getID() %></td>
<td class="standard" width="100%" align="right" rowspan=4> <td class="standard" width="100%" align="right" rowspan=4>
<form method=POST> <%
if (withdrawalDate == null)
{
%>
<form method=POST action="<%= request.getContextPath() %>/admin/edit-item">
<input type="hidden" name="item_id" value="<%= item.getID() %>"> <input type="hidden" name="item_id" value="<%= item.getID() %>">
<input type="hidden" name="action" value="<%= EditItemServlet.CONFIRM_DELETE %>"> <input type="hidden" name="action" value="<%= EditItemServlet.START_WITHDRAW %>">
<input type="submit" name="submit" value="Withdraw...">
</form>
<%
}
else
{
%>
<form method=POST action="<%= request.getContextPath() %>/admin/edit-item">
<input type="hidden" name="item_id" value="<%= item.getID() %>">
<input type="hidden" name="action" value="<%= EditItemServlet.REINSTATE %>">
<input type="submit" name="submit" value="Reinstate">
</form>
<%
}
%>
<br>
<form method=POST action="<%= request.getContextPath() %>/admin/edit-item">
<input type="hidden" name="item_id" value="<%= item.getID() %>">
<input type="hidden" name="action" value="<%= EditItemServlet.START_DELETE %>">
<input type="submit" name="submit" value="Delete (Expunge)..."> <input type="submit" name="submit" value="Delete (Expunge)...">
</form> </form>
</td> </td>
@@ -121,8 +148,20 @@
</table> </table>
</center> </center>
<%
if (withdrawalDate != null)
{
%>
<P align=center><strong>This item was withdrawn from DSpace on
<dspace:date date="<%= withdrawalDate %>" /></strong></P>
<%
}
%>
<P>&nbsp;</P> <P>&nbsp;</P>
<form method=POST action="<%= request.getContextPath() %>/admin/edit-item"> <form method=POST action="<%= request.getContextPath() %>/admin/edit-item">
<table class="miscTable"> <table class="miscTable">
<tr> <tr>

View File

@@ -135,7 +135,8 @@
<select name=year> <select name=year>
<option selected value="-1">(Choose year)</option> <option selected value="-1">(Choose year)</option>
<% <%
for (int i = 2001; i >= 1990; i--) int thisYear = new DCDate().getYear();
for (int i = thisYear; i >= 1990; i--)
{ {
%> %>
<option><%= i %></option> <option><%= i %></option>

View File

@@ -61,7 +61,7 @@
labels.add("Groups"); labels.add("Groups");
links.add("groups"); links.add("groups");
labels.add("Correct/<br>Expunge Item"); labels.add("Items");
links.add("edit-item"); links.add("edit-item");
labels.add("Dublin Core<br>Registry"); labels.add("Dublin Core<br>Registry");

61
dspace/jsp/tombstone.jsp Normal file
View File

@@ -0,0 +1,61 @@
<%--
- tombstone.jsp
-
- Version: $Revision$
-
- Date: $Date$
-
- Copyright (c) 2001, 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.
--%>
<%--
- Display a tombstone indicating that an item has been withdrawn.
--%>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<dspace:layout title="Item Withdrawn">
<H1>Item Withdrawn</H1>
<P>The item you are trying to access has been withdrawn from DSpace. If you
have any questions, please contact the administrators.</P>
<dspace:include page="/components/contact-info.jsp" />
<P align=center>
<A HREF="<%= request.getContextPath() %>/">Go to the DSpace home page</A>
</P>
</dspace:layout>

View File

@@ -147,7 +147,14 @@ public class DSpaceOAICatalog extends AbstractCatalog
if (itemInfo == null) if (itemInfo == null)
{ {
throw new IdDoesNotExistException(identifier); if (itemInfo.withdrawn)
{
throw new NoMetadataFormatsException();
}
else
{
throw new IdDoesNotExistException(identifier);
}
} }
else else
{ {
@@ -196,7 +203,8 @@ public class DSpaceOAICatalog extends AbstractCatalog
// Get the relevant OAIItemInfo objects to make headers // Get the relevant OAIItemInfo objects to make headers
DSpaceObject scope = resolveSet(context, set); DSpaceObject scope = resolveSet(context, set);
List itemInfos = Harvest.harvest(context, scope, from, until, List itemInfos = Harvest.harvest(context, scope, from, until,
false, true); // No items, but we need to know containers false, true, true);
// No items, but we need to know containers and withdrawn items
// Build up lists of headers and identifiers // Build up lists of headers and identifiers
Iterator i = itemInfos.iterator(); Iterator i = itemInfos.iterator();
@@ -276,9 +284,15 @@ public class DSpaceOAICatalog extends AbstractCatalog
// First get the item from the DB // First get the item from the DB
try try
{ {
context = new Context(); // Valid IDs start with hdl:
if (identifier.startsWith("hdl:"))
{
context = new Context();
itemInfo = Harvest.getSingle(context, identifier, false); itemInfo = Harvest.getSingle(context,
identifier.substring(4), // Strip "hdl:"
true);
}
} }
catch (SQLException se) catch (SQLException se)
{ {
@@ -354,7 +368,7 @@ public class DSpaceOAICatalog extends AbstractCatalog
// Get the relevant HarvestedItemInfo objects to make headers // Get the relevant HarvestedItemInfo objects to make headers
DSpaceObject scope = resolveSet(context, set); DSpaceObject scope = resolveSet(context, set);
List itemInfos = Harvest.harvest(context, scope, from, until, List itemInfos = Harvest.harvest(context, scope, from, until,
true, true); // Need items and containers true, true, true); // Need items, containers + withdrawals
// Build list of XML records from item info objects // Build list of XML records from item info objects
Iterator i = itemInfos.iterator(); Iterator i = itemInfos.iterator();

View File

@@ -123,8 +123,8 @@ public class DSpaceRecordFactory extends RecordFactory
protected boolean isDeleted(Object nativeItem) protected boolean isDeleted(Object nativeItem)
{ {
// FIXME: Our implentation doesn't know about deletes yet HarvestedItemInfo hii = (HarvestedItemInfo) nativeItem;
return false; return hii.withdrawn;
} }

View File

@@ -54,6 +54,7 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.AuthorizeManager;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.DCDate;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -97,6 +98,14 @@ public class DisplayItemServlet extends DSpaceServlet
// If everything is OK, display the item // If everything is OK, display the item
if (item != null) if (item != null)
{ {
// Tombstone?
DCDate withdrawalDate = item.getWithdrawalDate();
if (withdrawalDate != null)
{
JSPManager.showJSP(request, response, "tombstone.jsp");
return;
}
// Ensure the user has authorisation // Ensure the user has authorisation
AuthorizeManager.authorizeAction(context, item, Constants.READ); AuthorizeManager.authorizeAction(context, item, Constants.READ);

View File

@@ -94,6 +94,15 @@ public class EditItemServlet extends DSpaceServlet
/** User updates item */ /** User updates item */
public static final int UPDATE_ITEM = 3; public static final int UPDATE_ITEM = 3;
/** User starts withdrawal of item */
public static final int START_WITHDRAW = 4;
/** User confirms withdrawal of item */
public static final int CONFIRM_WITHDRAW = 5;
/** User reinstates a withdrawn item */
public static final int REINSTATE = 6;
/** Logger */ /** Logger */
private static Logger log = Logger.getLogger(EditCommunitiesServlet.class); private static Logger log = Logger.getLogger(EditCommunitiesServlet.class);
@@ -215,6 +224,26 @@ public class EditItemServlet extends DSpaceServlet
processUpdateItem(context, request, response, item); processUpdateItem(context, request, response, item);
break; break;
case START_WITHDRAW:
// Show "withdraw item" confirmation page
JSPManager.showJSP(request,
response,
"/admin/confirm-withdraw-item.jsp");
break;
case CONFIRM_WITHDRAW:
// Withdraw the item
item.withdraw();
JSPManager.showJSP(request, response, "/admin/get-item-id.jsp");
context.complete();
break;
case REINSTATE:
item.reinstate();
JSPManager.showJSP(request, response, "/admin/get-item-id.jsp");
context.complete();
break;
default: default:
// Erm... weird action value received. // Erm... weird action value received.
log.warn(LogManager.getHeader(context, log.warn(LogManager.getHeader(context,

View File

@@ -288,7 +288,8 @@ public class Collection implements DSpaceObject
"item", "item",
"SELECT item.* FROM item, collection2item WHERE " + "SELECT item.* FROM item, collection2item WHERE " +
"item.item_id=collection2item.item_id AND " + "item.item_id=collection2item.item_id AND " +
"collection2item.collection_id=" + getID() + ";"); "collection2item.collection_id=" + getID() +
" AND item.in_archive=true");
return new ItemIterator(ourContext, rows); return new ItemIterator(ourContext, rows);
} }

View File

@@ -62,6 +62,7 @@ import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.history.HistoryManager; import org.dspace.history.HistoryManager;
import org.dspace.search.DSIndexer;
import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow; import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.TableRowIterator;
@@ -1063,8 +1064,155 @@ public class Item implements DSpaceObject
/** /**
* Delete the item. Bundles and bitstreams are also deleted if they are * Withdraw the item from the archive. It is kept in place, and the
* not also included in another item. The Dublin Core metadata is deleted. * content and metadata are not deleted, but it is not publicly
* accessible.
*/
public void withdraw()
throws SQLException, AuthorizeException, IOException
{
String timestamp = DCDate.getCurrent().toString();
// Check permission. User must have REMOVE on all collections.
// Build some provenance data while we're at it.
String collectionProv = "";
Collection[] colls = getCollections();
for (int i = 0; i < colls.length; i++)
{
collectionProv = collectionProv + colls[i].getMetadata("name") +
" (ID: " + colls[i].getID() + ")\n";
AuthorizeManager.authorizeAction(ourContext, colls[i],
Constants.REMOVE);
}
// Set withdrawn flag and time stamp
itemRow.setColumn("withdrawn", true);
itemRow.setColumn("withdrawal_date", timestamp);
// in_archive flag is now false
itemRow.setColumn("in_archive", false);
// Add suitable provenance - includes user, date, collections +
// bitstream checksums
EPerson e = ourContext.getCurrentUser();
String prov = "Item withdrawn by " + e.getFullName() + " (" +
e.getEmail() + ") on " + timestamp + "\n" +
"Item was in collections:\n" + collectionProv +
InstallItem.getBitstreamProvenanceMessage(this);
addDC("description", "provenance", "en", prov);
// Update item in DB
update();
// Invoke History system
HistoryManager.saveHistory(ourContext, this, HistoryManager.MODIFY, e,
ourContext.getExtraLogInfo());
// Remove from indicies
Browse.itemRemoved(ourContext, getID());
DSIndexer.unIndexContent(ourContext, this);
// and all of our authorization policies
// FIXME: not very "multiple-inclusion" friendly
AuthorizeManager.removeAllPolicies(ourContext, this);
// Write log
log.info(LogManager.getHeader(ourContext,
"withdraw_item",
"user=" + e.getEmail() + ",item_id=" + getID()));
}
/**
* Reinstate a withdrawn item
*/
public void reinstate()
throws SQLException, AuthorizeException, IOException
{
String timestamp = DCDate.getCurrent().toString();
// Check permission. User must have ADD on all collections.
// Build some provenance data while we're at it.
String collectionProv = "";
Collection[] colls = getCollections();
for (int i = 0; i < colls.length; i++)
{
collectionProv = collectionProv + colls[i].getMetadata("name") +
" (ID: " + colls[i].getID() + ")\n";
AuthorizeManager.authorizeAction(ourContext, colls[i],
Constants.ADD);
}
// Clear withdrawn flag and time stamp
itemRow.setColumn("withdrawn", false);
itemRow.setColumnNull("withdrawal_date");
// in_archive flag is now true
itemRow.setColumn("in_archive", true);
// Add suitable provenance - includes user, date, collections +
// bitstream checksums
EPerson e = ourContext.getCurrentUser();
String prov = "Item reinstated by " + e.getFullName() + " (" +
e.getEmail() + ") on " + timestamp + "\n" +
"Item was in collections:\n" + collectionProv +
InstallItem.getBitstreamProvenanceMessage(this);
addDC("description", "provenance", "en", prov);
// Update item in DB
update();
// Invoke History system
HistoryManager.saveHistory(ourContext, this, HistoryManager.MODIFY, e,
ourContext.getExtraLogInfo());
// Add to indicies
Browse.itemAdded(ourContext, this);
DSIndexer.indexContent(ourContext, this);
// authorization policies
if (colls.length > 0)
{
// FIXME: not multiple inclusion friendly - just apply access
// policies from first collection
List policies = AuthorizeManager.getPoliciesActionFilter(
ourContext, colls[0], Constants.READ );
replaceAllPolicies(policies);
}
// Write log
log.info(LogManager.getHeader(ourContext,
"reinstate_item",
"user=" + e.getEmail() + ",item_id=" + getID()));
}
/**
* Item is withdrawn? If so, return the date it happened.
* <code>null</code> is returned if the item is not withdrawn.
*
* @return the date the item was withdrawn or <code<null</code>
*/
public DCDate getWithdrawalDate()
{
if (itemRow.getBooleanColumn("withdrawn"))
{
return new DCDate(itemRow.getStringColumn("withdrawal_date"));
}
else
{
return null;
}
}
/**
* Delete (expunge) the item. Bundles and bitstreams are also deleted if
* they are not also included in another item. The Dublin Core metadata is
* deleted.
*/ */
void delete() void delete()
throws SQLException, AuthorizeException, IOException throws SQLException, AuthorizeException, IOException
@@ -1087,8 +1235,7 @@ public class Item implements DSpaceObject
{ {
// Remove from Browse indices // Remove from Browse indices
Browse.itemRemoved(ourContext, getID()); Browse.itemRemoved(ourContext, getID());
DSIndexer.unIndexContent(ourContext, this);
// FIXME: Remove from search index
} }
// Delete the Dublin Core // Delete the Dublin Core
@@ -1116,7 +1263,6 @@ public class Item implements DSpaceObject
// Finally remove item row // Finally remove item row
DatabaseManager.delete(ourContext, itemRow); DatabaseManager.delete(ourContext, itemRow);
} }

View File

@@ -319,7 +319,8 @@ public class Subscribe
startDate, startDate,
endDate, endDate,
true, // Need item objects true, // Need item objects
false); // But not containers false, // But not containers
false); // Or withdrawals
// Only add to buffer if there are new items // Only add to buffer if there are new items
if (itemInfos.size() > 0) if (itemInfos.size() > 0)

View File

@@ -49,6 +49,7 @@ import org.apache.log4j.Logger;
import org.dspace.administer.DCType; import org.dspace.administer.DCType;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.DCDate;
import org.dspace.content.DCValue; import org.dspace.content.DCValue;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
@@ -93,6 +94,8 @@ public class Harvest
* @param containers if <code>true</code> the <code>containers</code> * @param containers if <code>true</code> the <code>containers</code>
* field of each <code>HarvestedItemInfo</code> object * field of each <code>HarvestedItemInfo</code> object
* is filled out * is filled out
* @param withdrawn If <code>true</code>, information about withdrawn
* items is included
* @return List of <code>HarvestedItemInfo</code> objects * @return List of <code>HarvestedItemInfo</code> objects
*/ */
public static List harvest(Context context, public static List harvest(Context context,
@@ -100,7 +103,8 @@ public class Harvest
String startDate, String startDate,
String endDate, String endDate,
boolean items, boolean items,
boolean containers) boolean containers,
boolean withdrawn)
throws SQLException throws SQLException
{ {
int dcTypeID = getDateAvailableTypeID(context); int dcTypeID = getDateAvailableTypeID(context);
@@ -110,7 +114,7 @@ public class Harvest
// SQL to add to the WHERE clause of the query // SQL to add to the WHERE clause of the query
String scopeWhereSQL = ""; String scopeWhereSQL = "";
if (scope != null) if (scope != null)
{ {
if (scope.getType() == Constants.COMMUNITY) if (scope.getType() == Constants.COMMUNITY)
@@ -130,12 +134,12 @@ public class Harvest
} }
// Theoretically, no other possibilities, won't bother to check // Theoretically, no other possibilities, won't bother to check
} }
// Put together our query // Put together our query
String query = String query =
"SELECT handle.handle, handle.resource_id, dcvalue.text_value FROM handle, dcvalue" + "SELECT handle.handle, handle.resource_id, dcvalue.text_value FROM handle, dcvalue, item" +
scopeTableSQL + " WHERE handle.resource_type_id=" + Constants.ITEM + scopeTableSQL + " WHERE handle.resource_type_id=" + Constants.ITEM +
" AND handle.resource_id=dcvalue.item_id AND dcvalue.dc_type_id=" + " AND handle.resource_id=dcvalue.item_id AND dcvalue.item_id=item.item_id AND item.withdrawn=false AND dcvalue.dc_type_id=" +
dcTypeID + scopeWhereSQL; dcTypeID + scopeWhereSQL;
if (startDate != null) if (startDate != null)
@@ -165,13 +169,13 @@ public class Harvest
itemInfo.handle = row.getStringColumn("handle"); itemInfo.handle = row.getStringColumn("handle");
itemInfo.itemID = row.getIntColumn("resource_id"); itemInfo.itemID = row.getIntColumn("resource_id");
itemInfo.datestamp = row.getStringColumn("text_value"); itemInfo.datestamp = row.getStringColumn("text_value");
itemInfo.withdrawn = false;
if (containers) if (containers)
{ {
fillContainers(context, itemInfo); fillContainers(context, itemInfo);
} }
if (items) if (items)
{ {
// Get the item // Get the item
@@ -180,7 +184,55 @@ public class Harvest
infoObjects.add(itemInfo); infoObjects.add(itemInfo);
} }
// Add information about deleted items if necessary
if (withdrawn)
{
// Put together our query
query =
"SELECT handle.handle, handle.resource_id, item.withdrawal_date FROM handle, item" +
scopeTableSQL + " WHERE handle.resource_type_id=" + Constants.ITEM +
" AND handle.resource_id=item.item_id AND item.withdrawn=true"
+ scopeWhereSQL;
if (startDate != null)
{
query = query + " AND item.withdrawal_date >= '" + startDate + "'";
}
if (endDate != null)
{
query = query + " AND item.withdrawal_date <= '" + endDate + "'";
}
log.debug(LogManager.getHeader(context,
"harvest SQL (withdrawals)",
query));
// Execute
tri = DatabaseManager.query(context, query);
// Process results of query into HarvestedItemInfo objects
while (tri.hasNext())
{
TableRow row = tri.next();
HarvestedItemInfo itemInfo = new HarvestedItemInfo();
itemInfo.handle = row.getStringColumn("handle");
itemInfo.itemID = row.getIntColumn("resource_id");
itemInfo.datestamp = row.getStringColumn("withdrawal_date");
itemInfo.withdrawn = true;
if (containers)
{
fillContainers(context, itemInfo);
}
// Won't fill out item objects for withdrawn items
infoObjects.add(itemInfo);
}
}
return infoObjects; return infoObjects;
} }
@@ -216,10 +268,23 @@ public class Harvest
itemInfo.item = i; itemInfo.item = i;
itemInfo.handle = handle; itemInfo.handle = handle;
// FIXME: Assume data.available is there
DCValue[] dateAvail = DCDate withdrawalDate = i.getWithdrawalDate();
i.getDC("date", "available", Item.ANY);
itemInfo.datestamp = dateAvail[0].value; if (withdrawalDate == null)
{
// FIXME: Assume data.available is there
DCValue[] dateAvail =
i.getDC("date", "available", Item.ANY);
itemInfo.datestamp = dateAvail[0].value;
itemInfo.withdrawn = false;
}
else
{
itemInfo.datestamp = withdrawalDate.toString();
itemInfo.withdrawn = true;
}
itemInfo.itemID = i.getID(); itemInfo.itemID = i.getID();
// Get the sets // Get the sets

View File

@@ -75,4 +75,7 @@ public class HarvestedItemInfo
* <code>containers[1][1]</code> - ID of collectionB <br> * <code>containers[1][1]</code> - ID of collectionB <br>
*/ */
public int[][] containers; public int[][] containers;
/** True if this item has been withdrawn */
public boolean withdrawn;
} }