/* * BitstreamArranger.java * * Version: $Revision: 0.1 $ * * Date: $Date: 2006/09/29 14:48:28 $ * */ package nl.leidenuniv.dspace.rdf; import java.sql.SQLException; import org.apache.log4j.Logger; import org.dspace.content.DSpaceObject; import org.dspace.core.Context; import org.dspace.core.LogManager; import nl.leidenuniv.dspace.rdf.RDFtriple; import nl.leidenuniv.dspace.rdf.RDFpredicate; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Item; import org.dspace.core.ConfigurationManager; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * A Singleton Class for arranging (ordering in sequence) bitstreams using RDF * * @author Lucas van Schaik * @version $Revision: 0.1 $ */ public class BitstreamArranger { /** log4j logger */ private static Logger log = Logger.getLogger(BitstreamArranger.class); /** BitstreamArranger is a singleton class **/ private static BitstreamArranger singleton; /** the precedes and initial URI's **/ public final static String precedes = "precedes"; public final static String initial = "initial"; private BitstreamArranger() { // BitstreamArranger is a singleton class, so it does not have a public constructor } public static synchronized BitstreamArranger getBitstreamArranger() { if (singleton == null) { singleton = new BitstreamArranger(); } return singleton; } public Bitstream[] getOrderedListOfOriginalBistreams(Context context, Item item) { if (item == null) { return new Bitstream[0]; } List bitstreams = bitstreamsList(context, item, "ORIGINAL"); try { RDFpredicate predicate = initialPredicate(context); RDFtriple triple; Object anObject; if (predicate == null || (triple = RDFtriple.find(context,item,predicate,Bitstream.class)) == null) { //can't make heads or tails out of this one... return (Bitstream[])bitstreams.toArray(new Bitstream[bitstreams.size()]); } int newIndex = 0; predicate = precedesPredicate(context); while (predicate != null && triple != null) { anObject = triple.getObject(); if (anObject instanceof Bitstream) { Bitstream bitstream = (Bitstream)anObject; int index = bitstreams.indexOf(bitstream); if (index != -1) { bitstreams.remove(index); if (false) { // false means none rdf bitstreams last bitstreams.add(newIndex++,bitstream); } else { bitstreams.add(bitstream); } triple = RDFtriple.find(context,bitstream,predicate,Bitstream.class); } else { // bitstream is no "child" of item, so this is strange... log.warn(LogManager.getHeader(context, "rdf_integrity_error", "bitstream "+bitstream.getID()+" is no child of item "+item.getID())); triple = null; } } else { // some other type was found... log.warn(LogManager.getHeader(context, "rdf_integrity_error", anObject.getClass().toString() )); triple = null; } } return (Bitstream[])bitstreams.toArray(new Bitstream[bitstreams.size()]); } catch (SQLException e) { // some sql exception occured, but we do have a list of bistreams... so.... return (Bitstream[])bitstreams.toArray(new Bitstream[bitstreams.size()]); } } public void orderListOfOriginalBitstreams(Context context, Item item, Bitstream[] bitstreams) throws SQLException { if (item == null) { return; } List oldList = bitstreamsList(context, item, "ORIGINAL"); RDFtriple triple = null; RDFpredicate predicate = initialPredicate(context); triple = RDFtriple.find(context,item,predicate,Bitstream.class); if (bitstreams.length > 0) { if (triple != null) { if ( ! bitstreams[0].equals(triple.getObject())) { triple.setObject(bitstreams[0]); triple.update(); } } else { triple = new RDFtriple(context,item,predicate,bitstreams[0]); } predicate = precedesPredicate(context); for (int i = 1; i < bitstreams.length; i++) { triple = RDFtriple.find(context,bitstreams[i-1],predicate,Bitstream.class); if (triple != null) { if ( ! bitstreams[i].equals(triple.getObject())) { triple.setObject(bitstreams[i]); triple.update(); } } else { triple = new RDFtriple(context,bitstreams[i-1],predicate,bitstreams[i]); } int index = oldList.indexOf(bitstreams[i-1]); if (index != -1) { oldList.remove(index); } } } else { if (triple != null) { triple.delete(); } } ListIterator iterator = oldList.listIterator(); predicate = precedesPredicate(context); while (predicate != null && iterator.hasNext()) { triple = RDFtriple.find(context,(Bitstream)iterator.next(),predicate,Bitstream.class); if (triple != null) { triple.delete(); } } } public RDFpredicate precedesPredicate(Context context) { RDFpredicate predicate = null; try { predicate = RDFpredicate.find(context,precedes); if (predicate == null) { predicate = new RDFpredicate(context,precedes); } } catch (SQLException e) { // do nothing... } return predicate; } public RDFpredicate initialPredicate(Context context) { RDFpredicate predicate = null; try { predicate = RDFpredicate.find(context,initial); if (predicate == null) { predicate = new RDFpredicate(context,initial); } } catch (SQLException e) { // do nothing... } return predicate; } private List bitstreamsList(Context context, Item item, String type) { List bitstreams = new ArrayList(); if (item != null) { Bundle[] bundles = item.getBundles(type); for (int i = 0; i < bundles.length; i++) { Bitstream[] bs = bundles[i].getBitstreams(); for (int k = 0; k < bs.length; k++) { // Skip internal types if (!bs[k].getFormat().isInternal()) { bitstreams.add(bs[k]); } } } } return bitstreams; } public static void main(String[] argv) { try { Context context = new Context(); Item item = Item.find(context,new Integer(argv[0]).intValue()); BitstreamArranger arranger = BitstreamArranger.getBitstreamArranger(); Bitstream[] bitstreams = arranger.getOrderedListOfOriginalBistreams(context,item); System.out.println("ORDERED BITSTREAMS"); for (int i = 0;i