[
https://jira.duraspace.org/browse/DS-1352?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ivan Masár updated DS-1352:
---------------------------
Labels: has-patch (was: )
> Itemimport replace issue
> ------------------------
>
> Key: DS-1352
> URL: https://jira.duraspace.org/browse/DS-1352
> Project: DSpace
> Issue Type: Bug
> Components: DSpace API
> Affects Versions: 1.7.2
> Reporter: Ying
> Labels: has-patch
>
> We use DSpace batch import a lot and sometimes have to replace the
> items to fix the metadata or content issues. However, we found the
> replacement in itemimport is actually deleting the old item, adding a
> new one and then having the old handles back to the item. It generates
> several problems. First, it will delete all relationships, for
> example, if the item is mapped to another collection, the mapping will
> be gone after replacement. Also, when deleting the item, the item's
> internal ID changed and it losts its connection with statistical
> history. Some of our statistics will show replaced items internal ID
> number since the ID changed and it can't match the item title.
> Currently, we fixed that in our DSpace as below. Instead of delete-add items,
> we cleared the metadata and contents of the items and replace that with given
> info.
> 1. Defining a cleanItem method in Item.java
> public void cleanItem() throws SQLException, AuthorizeException,
> IOException
> {
> // Check authorisation here. If we don't, it may happen that we
> remove the
> // metadata but when getting to the point of removing the bundles we
> get an exception
> // leaving the database in an inconsistent state
> AuthorizeManager.authorizeAction(ourContext, this, Constants.ADD);
> log.info(LogManager.getHeader(ourContext, "clean_item", "item_id=" +
> getID()));
> // Remove from cache
> ourContext.removeCached(this, getID());
> try
> {
> // Remove from indices and we will index the new data later
> IndexBrowse ib = new IndexBrowse(ourContext);
> ib.itemRemoved(this);
> }
> catch (BrowseException e)
> {
> log.error("caught exception: ", e);
> throw new SQLException(e.getMessage(), e);
> }
> // Delete the metadata (in memory; will write to db when update is
> called)
> List<DCValue> values = new ArrayList<DCValue>();
> setMetadata(values);
> // Remove bundles
> Bundle[] bunds = getBundles();
> for (int i = 0; i < bunds.length; i++)
> {
> removeBundle(bunds[i]);
> }
> }
> 2. Add replaceItem in the ItemImport.java -
> private void replaceItem(Context c, Item myitem, String path, String
> itemname)
> throws AuthorizeException, SQLException, IOException,
> SAXException, ParserConfigurationException, TransformerException
> {
> System.out.println("Replacing item with directory " + itemname);
> // before cleanup the metadata, save the fields that would normally
> be generated by InstallItem.populateMetadata()
> List<DCValue> saved = new ArrayList<DCValue>();
>
> saved.addAll(Arrays.asList(myitem.getMetadata("dc","date","available",Item.ANY)));
>
> saved.addAll(Arrays.asList(myitem.getMetadata("dc","date","accessioned",Item.ANY)));
>
> saved.addAll(Arrays.asList(myitem.getMetadata("dc","date","issued",Item.ANY)));
>
> saved.addAll(Arrays.asList(myitem.getMetadata("dc","description","provenance",Item.ANY)));
>
> if (! isTest) {
> myitem.cleanItem();
> } else {
> myitem = null;
> }
> // load replacement metadata
> loadMetadata(c, myitem, path + File.separatorChar + itemname +
> File.separatorChar);
> // restore each saved metadata value
> if (! isTest) {
> for (DCValue val : saved) {
> // disable special treatment of provenance
> /*if (val.schema.equals("dc") &&
> val.element.equals("description") && val.qualifier.equals("provenance")) {
> // for provenance, always restore it unless the exact
> same value is already present from replacement
> boolean alreadyPresent = false;
> for (DCValue existing :
> myitem.getMetadata("dc","description","provenance",Item.ANY)) {
> if (existing.value.equals(val.value)) {
> alreadyPresent = true;
> break;
> }
> }
> if (! alreadyPresent) {
> myitem.addMetadata(val.schema, val.element,
> val.qualifier, val.language, val.value);
> }
> } else*/ if (myitem.getMetadata(val.schema, val.element,
> val.qualifier, Item.ANY).length == 0) {
> // for non-provenance, only restore if replacement didn't
> have any values for this element
> myitem.addMetadata(val.schema, val.element,
> val.qualifier, val.language, val.value);
> }
> }
> // make a new provenance item and add it
> String now = DCDate.getCurrent().toString();
> EPerson e = c.getCurrentUser();
> String prov = "Item contents replaced by "+e.getFullName()+"
> ("+e.getEmail()+") on "+now+"\n";
> myitem.addMetadata("dc", "description", "provenance", "en", prov);
> }
> // add replacement bitstreams
> List<String> options = processContentsFile(c, myitem, path +
> File.separatorChar + itemname, "contents");
> // set permissions if specified in contents file
> if (options.size() > 0)
> {
> System.out.println("Processing options");
> processOptions(c, myitem, options);
> }
> if (! isTest) {
> myitem.update();
> c.addEvent(new Event(Event.MODIFY+Event.MODIFY_METADATA,
> Constants.ITEM, myitem.getID(), myitem.getHandle()));
> // set embargo lift date and take away read access if indicated.
> DCDate liftDate = EmbargoManager.getEmbargoDate(c, myitem);
> if (liftDate != null)
> {
> EmbargoManager.setEmbargo(c, myitem, liftDate);
> }
> }
> c.commit();
> return;
> }
> 3. Change replaceItems in ItemImport.java as below
> private void replaceItems(Context c, Collection[] mycollections,
> String sourceDir, String mapFile, boolean template) throws
> Exception
> {
> // verify the source directory
> File d = new java.io.File(sourceDir);
> if (d == null)
> {
> System.out.println("Error, cannot open source directory "
> + sourceDir);
> System.exit(1);
> }
> // read in HashMap first, to get list of handles & source dirs
> Map<String, String> myHash = readMapFile(mapFile);
> // for each handle, re-import the item, discard the new handle
> // and re-assign the old handle
> for (Map.Entry<String, String> mapEntry : myHash.entrySet())
> {
> // get the old handle
> String newItemName = mapEntry.getKey();
> String oldHandle = mapEntry.getValue();
> Item oldItem = null;
> if (oldHandle.indexOf('/') != -1)
> {
> System.out.println("\tReplacing: " + oldHandle);
> // add new item, locate old one
> oldItem = (Item) HandleManager.resolveToObject(c, oldHandle);
> }
> else
> {
> oldItem = Item.find(c, Integer.parseInt(oldHandle));
> }
> /* Rather than exposing public item methods to change handles --
> * two handles can't exist at the same time due to key constraints
> * so would require temp handle being stored, old being copied to
> new and
> * new being copied to old, all a bit messy -- a handle file is
> written to
> * the import directory containing the old handle, the existing
> item is
> * deleted and then the import runs as though it were loading an
> item which
> * had already been assigned a handle (so a new handle is not
> even assigned).
> * As a commit does not occur until after a successful add, it is
> safe to
> * do a delete as any error results in an aborted transaction
> without harming
> * the original item */
> /*File handleFile = new File(sourceDir + File.separatorChar +
> newItemName + File.separatorChar + "handle");
> // SWB fix bug - param should be "false" to not append to
> existing file if present
> PrintWriter handleOut = new PrintWriter(new
> FileWriter(handleFile, false));
> // END SWB
> if (handleOut == null)
> {
> throw new Exception("can't open handle file: " +
> handleFile.getCanonicalPath());
> }
> handleOut.println(oldHandle);
> handleOut.close();
> /*deleteItem(c, oldItem);
> addItem(c, mycollections, sourceDir, newItemName, null,
> template);*/
> replaceItem(c, oldItem, sourceDir, newItemName);
> c.clearCache();
> }
> }
> Best,
> Ying
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
------------------------------------------------------------------------------
Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery
and much more. Keep your Java skills current with LearnJavaNow -
200+ hours of step-by-step video tutorials by Java experts.
SALE $49.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122612
_______________________________________________
Dspace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dspace-devel