Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: JIRA Issue macro params updated with additional server info
Info

As of version 1.8, this feature is now part of DSpace XMLUI and doesn't require you to make any modifications to the code. This feature was added in

Jira
serverDuraSpace JIRA
serverIdc815ca92-fd23-34c2-8fe3-956808caf8c5
keyDS-749
.

 <?xml version="1.0" encoding="utf-8"?>
<html>

Background

At Leiden University, The Netherlands, we needed a way to change the order of the bitstreams as they are displayed in an easy way.

...

The order of bitstreams is defined by using the Basic + RDF + implementation. The bitstreams are semantically linked to eachother by using in "precedes" predicate. The special class BitstreamArranger manages the ordering of bitstreams.

...

Step 1: Install the Basic+RDF+implementation

See Basic + RDF + implementation for details on how to do this.

...

  • add some new import statements:
Code Block

  import java.util.ArrayList;
  import nl.leidenuniv.dspace.rdf.BitstreamArranger;
  import nl.leidenuniv.dspace.rdf.RDFpredicate;
  import nl.leidenuniv.dspace.rdf.RDFtriple;
  • add line of code just before "// Sort the list" near line 372
Code Block

  BitstreamArranger arranger = BitstreamArranger.getBitstreamArranger();
  • add lines of code inside "if (button.equals("submit_delete_bitstream_"..." block near 463 as the first statements:
Code Block

   RDFpredicate predicate = arranger.precedesPredicate(context);
   RDFtriple triple = RDFtriple.find(context,bitstream,predicate,Bitstream.class);
   if (triple != null) \{
     triple.delete();
   \}
  • add a new "else if" block just before the "item.update()" near 524:
Code Block

   else if (p.equals("position"))
   //        && AuthorizeManager.isAdmin(context))
   \{
     String[] values = request.getParameterValues(p);
     Bitstream[] newOrder = new Bitstream[values.length];
     for (int i = 0;i<values.length;i++) \{
       String v = values[i];
       StringTokenizer st = new StringTokenizer(v, "_"); // should use: v.split("_")
       // Ignore "position"
       st.nextToken();
       // Bundle ID and bitstream ID next
       int bundleID = Integer.parseInt(st.nextToken());
       int bitstreamID = Integer.parseInt(st.nextToken());
       String newPos = st.nextToken();
       //Bundle bundle = Bundle.find(context, bundleID);
       Bitstream bitstream = Bitstream.find(context, bitstreamID);
       String key = String.valueOf(bundleID) + "_" + bitstreamID;
       if ( ! newPos.equals("N")) \{
         int pos = Integer.parseInt(newPos);
         if (bitstream != null && newOrder[pos] == null
             && ! button.equals("submit_delete_bitstream_"+key)) \{
           newOrder[pos] = bitstream;
         \}
       \}
     \}
     int count = 0;
     for (int i=0; i<newOrder.length; i++) \{
       if (newOrder[i] != null) count++;
     \}
     Bitstream[] bitOrder = new Bitstream[count];
     for (int i=0, j=0;i<newOrder.length;i++) \{
       if (newOrder[i] != null) \{
         bitOrder[j++] = newOrder[i];
       \}
     \}
     arranger.orderListOfOriginalBitstreams(context,item,bitOrder);
   \}

org/dspace/app/webui/jsptag/ItemTag.java

  • add some new import statements:
Code Block

  import org.dspace.core.Context;
  import nl.leidenuniv.dspace.rdf.BitstreamArranger;
  • replace the following code near line 632:
Code Block

  for (int i = 0; i < bundles.length; i++)
  \{
      Bitstream[] bitstreams = bundles[i].getBitstreams();
      for (int k = 0; k < bitstreams.length; k++)
      \{
          // Skip internal types
          if (!bitstreams[k].getFormat().isInternal())
          \{

with this:

Code Block

    BitstreamArranger arranger = BitstreamArranger.getBitstreamArranger();
    Context context = null;
    Bitstream[] bitstreams = null;
    try \{
      context = UIUtil.obtainContext(request);
      bitstreams = arranger.getOrderedListOfOriginalBistreams(context,item);
    \}
    catch (SQLException e) \{
      // something wrong...
      throw new IOException(e.toString());
    \}
    for (int k = 0; k < bitstreams.length; k++) \{

and do not forget to balance the number of brackets (remove 2 brackets) near line 718

...

  • add some page imports:
Code Block

 <%@ page import="nl.leidenuniv.dspace.rdf.BitstreamArranger" %>
 <%@ page import="nl.leidenuniv.dspace.rdf.RDFtriple" %>
 <%@ page import="nl.leidenuniv.dspace.rdf.RDFpredicate" %>
 <%@ page import="java.sql.SQLException" %>
 <%@ page import="org.dspace.app.webui.util.UIUtil" %>
 <%@ page import="org.dspace.core.Context" %>
 <%@ page import="org.dspace.content.DSpaceObject" %>
  • near 320 add 2 columns
Code Block

  <th id="t10" class="oddRowOddCol">&nbsp;</th>
  <th id="t11" class="oddRowOddCol"><strong><fmt:message key="jsp.tools.edit-item-form.elem6"/></strong></th>
  • replace "Bitstream) [] bitstreams = bundles(i).getBitstreams();" near line 335 with the following code:
Code Block

    Bitstream[] bitstreams = new Bitstream[0];
    boolean isOriginal = bundles[i].getName().equals("ORIGINAL");
    int posKnownFrom = 0;
    int posKnownTill = -1;
    if (isOriginal) \{
      BitstreamArranger arranger = BitstreamArranger.getBitstreamArranger();
      try \{
        Context context = UIUtil.obtainContext(request);
        bitstreams = arranger.getOrderedListOfOriginalBistreams(context,item);
        RDFpredicate predicate = arranger.initialPredicate(context);
        if (bitstreams.length > 0) \{
          RDFtriple triple = RDFtriple.find(context,item,predicate,Bitstream.class);
          if (triple != null) \{
            DSpaceObject first = triple.getObject();
            for (int p=0; p<bitstreams.length; p++) \{
              if (bitstreams[p].equals(first)) \{
                posKnownFrom = p;
                posKnownTill = p;
              \}
            \}
            if (posKnownFrom >= 0) \{
              predicate = arranger.precedesPredicate(context);
              for (int p=posKnownFrom; p<bitstreams.length-1; p++) \{
                triple = RDFtriple.find(context,bitstreams[p],predicate,bitstreams[p+1]);
                if (triple == null) \{
                  break;
                \}
                posKnownTill++;
              \}
            \}
          \}
        \}
      \}
      catch (SQLException e) \{
        // do nothing, maybe originals will be retrieved by getBitstreams below
      \}
    \}
    if (bitstreams.length == 0) \{
      bitstreams = bundles[i].getBitstreams();
    \}
  • replace "<% if (bundles[i].getName().equals("ORIGINAL")) {" near line 344 with the following code:
Code Block

  <td headers="t10" class="<%= row %>RowEvenCol">
    <a target="_blank" href="<%= request.getContextPath() %>/retrieve/<%= bitstreams[j].getID() %>"><fmt:message key="jsp.tools.general.view"/></a>
  </td>
  <% if (isOriginal)
     \{ %>
   <td headers="t11" class="<%= row %>RowOddCol" align="center">
      <SELECT name="position" onchange="reposition(this)">
         <OPTION value="position_<%= key %>_N">-</OPTION>
         <% for (int k = 0; k < bitstreams.length; k++) \{ %>
         <OPTION value="position_<%= key %>_<%= k %>" <% if (j>=posKnownFrom && j<=posKnownTill && (j - posKnownFrom) == k) \{ %> selected <% \} %> ><%= k+1 %></OPTION>
         <% \} %>
      </SELECT>
   </TD>
  • near line 353 replace "<td headers="t11"> </td>" with:
Code Block

  <td headers="t11" class="<%= row %>RowOddCol"> </td>
  <td headers="t11" class="<%= row %>RowEvenCol"> </td>
  • near line 372 replace:
Code Block

  <a target="_blank" href="<%= request.getContextPath() %>/retrieve/<%= bitstreams[j].getID() %>"><fmt:message key="jsp.tools.general.view"/></a>&nbsp;<input type="submit" name="submit_delete_bitstream_<%= key %>" value="<fmt:message key="jsp.tools.general.remove"/>" />

with this:

Code Block

  <input type="submit" name="submit_delete_bitstream_<%= key %>" value="<fmt:message key="jsp.tools.general.remove"/>" />
  • add some javascript just after the "</table>" near line 381 (you can also include this in a seperate file):
Code Block

 <SCRIPT language="JavaScript">
 var storedPos = new Array();
 function reposition(anElement) \{
   var allPosEl = document.getElementsByName('position');
   var oldPos, newPos;
   var indexOfEl = 0;
   var hiPos = 0;
   for (var i=0;i<allPosEl.length;i++) \{
     if (allPosEl[i] == anElement) \{
       indexOfEl = i;
     \}
     else \{
       if (allPosEl[i].selectedIndex > hiPos) \{
         hiPos = allPosEl[i].selectedIndex;
       \}
     \}
   \}
   oldPos = storedPos[indexOfEl];
   newPos = anElement.selectedIndex;
   if (oldPos == newPos) return;
   if (newPos > hiPos + 1) \{
     anElement.selectedIndex = hiPos + 1;
     newPos = hiPos + 1;
   \}
   if (newPos == 0) \{
     for (var i=0;i<allPosEl.length;i++) \{
       if (allPosEl[i] != anElement) \{
         var pos = allPosEl[i].selectedIndex;
         if (pos > oldPos) \{
           allPosEl[i].selectedIndex -= 1;
         \}
       \}
     \}
   \}
   else if (oldPos == 0) \{
     for (var i=0;i<allPosEl.length;i++) \{
       if (allPosEl[i] != anElement) \{
         var pos = allPosEl[i].selectedIndex;
         if (pos >= newPos) \{
           allPosEl[i].selectedIndex += 1;
         \}
       \}
     \}
   \}
   else \{
     for (var i=0;i<allPosEl.length;i++) \{
       if (allPosEl[i] != anElement) \{
         var pos = allPosEl[i].selectedIndex;
         if (oldPos > newPos) \{
           if (pos >= newPos && pos < oldPos) \{
             allPosEl[i].selectedIndex += 1;
           \}
         \}
         else \{
           if (pos > oldPos && pos <= newPos) \{
             allPosEl[i].selectedIndex -= 1;
           \}
         \}
       \}
     \}
   \}
   storePositions();
 \}
 function storePositions() \{
   var allPosEl = document.getElementsByName('position');
   for (var i=0;i<allPosEl.length;i++) \{
     storedPos[i] = allPosEl[i].selectedIndex;
   \}
 \}
 storePositions();
 </SCRIPT>

...

If you need help, or have any comments, or you just want to inform me that you (are going to) use this, please contact me at schaik (at) library.leidenuniv.nl</html>