Contents |
At Leiden University, The Netherlands, we use DSpace among other things for "Dissertations Online" https://openaccess.leidenuniv.nl/handle/1887/492
Sometimes the dissertation is in the repository, but the publisher disallows the distribution of the full text of the dissertation or part of the dissertation. It must be under embargo. Because DSpace 1.3.2 did not support this kind of behaviour, we implemented it.
Bitstreams all have a resource policy. Most of the time this is a anonymous read policy. If a bitstream has no anonymous read policy then it cannot be read, so effectively it is under embargo.
Now if you could set an end date for that embargo, it would be so much nicer. But this is already possible:
DSpace allows resource policies to have a start date and an end date: so if you set an anonymous read policy with a start date of januari 1 2009, it is effectively under embargo until januari 1 2009.
Now all this change does, is:
Here you can see the functionality at work:
https://openaccess.leidenuniv.nl/handle/1887/12291
https://openaccess.leidenuniv.nl/handle/1887/12151
Note: our DSpace implementation has lots of other modifications, including a very different look and feel. This is not included in this patch.
Below are some screenshots from the submission process and from the administrators pages
The modifications I made were made to Dspace 1.3.2. This is also the version of DSpace were this functionality was tested extensively.
This does not mean that this will not work on DSpace 1.4 or higher, it just is not tested yet.
The installation steps below are for DSpace 1.3.2, but will give some pointers for DSpace 1.4, so it should be possible to implement this on DSpace 1.4. If you do this and have any suggestions, please share them!
Many files need some changes, so keep a backup copy of the changed files in case it goes sour...
Change the following Java files (make a backup copy!)
import org.dspace.authorize.AuthorizeManager; import org.dspace.core.Context; import java.util.Date; import java.util.Calendar |
out .print(bsLink + LocaleSupport .getLocalizedMessage( pageContext, "org.dspace.app.webui.jsptag.ItemTag.view") + "</a></td></tr>"); |
to this:
Date date = bitstreams[k].getEmbargoEndDate(); if (bitstreams[k].isEmbargoed() && (handle != null || date != null)) \{ out.println(LocaleSupport.getLocalizedMessage(pageContext, "org.dspace.app.webui.jsptag.ItemTag.underEmbargo")); if (date != null) \{ out.print(LocaleSupport.getLocalizedMessage(pageContext, "org.dspace.app.webui.jsptag.ItemTag.embargoUntil")); Calendar cal = Calendar.getInstance(); cal.setTime(date); out.print(cal.get(Calendar.DAY_OF_MONTH)); out.print("/"); out.print(cal.get(Calendar.MONTH) + 1); out.print("/"); out.println(cal.get(Calendar.YEAR)); \} \} Context context = null; boolean allowed = false; try \{ context = UIUtil.obtainContext(request); allowed = AuthorizeManager.authorizeActionBoolean(context,bitstreams[k],Constants.READ); \} catch (SQLException e) \{ allowed = false; \} if (!bitstreams[k].isEmbargoed() || allowed) \{ out.println(bsLink + LocaleSupport .getLocalizedMessage( pageContext, "org.dspace.app.webui.jsptag.ItemTag.view") + "</a>"); \} out.println("</td></tr>"); |
import java.util.Date; import java.util.Calendar |
private void applyPolicyEndAndStartDate(HttpServletRequest request, ResourcePolicy policy) \{ int start_year = UIUtil.getIntParameter(request, "start_year"); int start_month = UIUtil.getIntParameter(request, "start_month"); int start_day = UIUtil.getIntParameter(request, "start_day"); int end_year = UIUtil.getIntParameter(request, "end_year"); int end_month = UIUtil.getIntParameter(request, "end_month"); int end_day = UIUtil.getIntParameter(request, "end_day"); Date startDate = null; Date endDate = null; if (start_year > 0 && start_month > 0 && start_day > 0) \{ Calendar cal = Calendar.getInstance(); start_month--; cal.set(start_year,start_month,start_day,0,0,0); startDate = cal.getTime(); \} if (end_year > 0 && end_month > 0 && end_day > 0) \{ Calendar cal = Calendar.getInstance(); end_month--; cal.set(end_year,end_month,end_day,0,0,0); endDate = cal.getTime(); \} // modify the policy policy.setStartDate(startDate); policy.setEndDate(endDate); \} |
else if (item_id != -1) \{ item = Item.find(c, item_id); // modify the policy policy.setAction(action_id); policy.setGroup(group); policy.update(); // show edit form! prepItemEditForm(c, request, item); display_page = "/dspace-admin/authorize-item-edit.jsp"; \} |
to this:
else if (item_id != -1) \{ item = Item.find(c, item_id); // modify the policy policy.setAction(action_id); policy.setGroup(group); applyPolicyEndAndStartDate(request,policy); policy.update(); // show edit form! prepItemEditForm(c, request, item); display_page = "/dspace-admin/authorize-item-edit.jsp"; \} |
So, only "applyPolicyEndAndStartDate(request,policy);" was added below "policy.setGroup(group);"
import org.dspace.authorize.ResourcePolicy; import org.dspace.eperson.Group; import java.util.Date; import java.util.Calendar |
// Update to DB b.update(); item.update(); |
the following lines:
// set the embargo, if any int embargo_year = UIUtil.getIntParameter(wrapper, "embargo_year"); int embargo_month = UIUtil.getIntParameter(wrapper, "embargo_month"); int embargo_day = UIUtil.getIntParameter(wrapper, "embargo_day"); if (embargo_year > 0 && embargo_month > 0 && embargo_day > 0) \{ Date embargoDate = null; Calendar cal = Calendar.getInstance(); embargo_month--; cal.set(embargo_year,embargo_month,embargo_day,0,0,0); embargoDate = cal.getTime(); ResourcePolicy rp = ResourcePolicy.create(context); Group group = Group.find(context,0); rp.setResource(b); rp.setAction(Constants.READ); rp.setGroup(group); rp.setStartDate(embargoDate); rp.update(); \} |
Note: sometimes the underscores are not displayed correctly in wiki, but if you copy and paste it, they reappear.
In this file a bug exists, in version 1.3.2 and also in version 1.4.2. It is clear that this code is not being used, but now it is, so patch the bug:
if (now.after(sd)) |
if (now.after(ed)) |
public boolean isEmbargoed() \{ // may be a better name is: isUnderEmbargo() ? ResourcePolicy policy; try \{ policy = getAnonymousReadPolicy(); \} catch (SQLException e) \{ return true; \} if (policy == null) \{ return true; \} else \{ return !policy.isDateValid(); \} \} public Date getEmbargoEndDate() \{ ResourcePolicy policy; try \{ policy = getAnonymousReadPolicy(); \} catch (SQLException e) \{ return null; \} if (policy == null) \{ return null; \} else \{ return policy.getStartDate(); \} \} public ResourcePolicy getAnonymousReadPolicy() throws SQLException \{ ResourcePolicy thePolicy = null; List policies = AuthorizeManager.getPoliciesActionFilter(bContext, this, Constants.READ); for (Iterator i = policies.iterator(); i.hasNext(); ) \{ ResourcePolicy policy = (ResourcePolicy)i.next(); if (policy.getGroupID() == 0) \{ // anonymous group thePolicy = policy; \} \} return thePolicy; \} |
Bitstream mybitstream = bs[j]; // change bitstream policies AuthorizeManager.removeAllPolicies(ourContext, bs[j]); AuthorizeManager.addPolicies(ourContext, newpolicies, bs[j]); |
with this:
Bitstream mybitstream = bs[j]; // keep anonymous read policies with a start date, // because that is a policy that enables an embargo ResourcePolicy embargo = bs[j].getAnonymousReadPolicy(); // change bitstream policies AuthorizeManager.removeAllPolicies(ourContext, bs[j]); AuthorizeManager.addPolicies(ourContext, newpolicies, bs[j]); // re-apply the embargo if (embargo != null) \{ ResourcePolicy arp = bs[j].getAnonymousReadPolicy(); if (arp == null) \{ Group anonymousGroup = Group.find(ourContext, 0); AuthorizeManager.addPolicy(ourContext, bs[j], Constants.READ, anonymousGroup); arp = bs[j].getAnonymousReadPolicy(); \} arp.setStartDate(embargo.getStartDate()); arp.setEndDate(embargo.getEndDate()); arp.update(); \} |
Change the following JSP files:
The best way to do this is by modifying a local copy: so copy a file from jsp/ to jsp/local (include the path), and then modify the local version.
<%@ page import="java.util.Date" %> <%@ page import="java.util.Calendar" %> |
<th class="oddRowOddCol"><strong><fmt:message key="jsp.dspace-admin.general.period"/></strong></th> <th class="oddRowEvenCol"><strong><fmt:message key="jsp.dspace-admin.authorize-item-edit.eperson" /></strong></th> <th class="oddRowOddCol"><strong><fmt:message key="jsp.dspace-admin.general.group"/></strong></th> <th class="oddRowEvenCol"> </th> |
<td class="<%= row %>RowOddCol"> <% Date date; if ((date = rp.getStartDate()) != null) \{ Calendar start_cal = Calendar.getInstance(); start_cal.setTime(date); out.print(start_cal.get(Calendar.DAY_OF_MONTH)); out.print("/"); out.print(start_cal.get(Calendar.MONTH) + 1); out.print("/"); out.println(start_cal.get(Calendar.YEAR)); \} out.println("-"); if ((date = rp.getEndDate()) != null) \{ Calendar end_cal = Calendar.getInstance(); end_cal.setTime(date); out.print(end_cal.get(Calendar.DAY_OF_MONTH)); out.print("/"); out.print(end_cal.get(Calendar.MONTH) + 1); out.print("/"); out.println(end_cal.get(Calendar.YEAR)); \} %> </td> |
<%@ page import="java.util.Date" %> <%@ page import="java.util.Calendar" %> |
Calendar start_cal = null; Calendar end_cal = null; Date date = null; if ((date = policy.getStartDate()) != null) \{ start_cal = Calendar.getInstance(); start_cal.setTime(date); \} if ((date = policy.getEndDate()) != null) \{ end_cal = Calendar.getInstance(); end_cal.setTime(date); \} |
<form action="<%= request.getContextPath() %>/dspace-admin/authorize" method="post"> |
<form action="<%= request.getContextPath() %>/dspace-admin/authorize" method="post" <%=(resourceType == 0)?"onSubmit=\"return validate(this)\"":"" %> > |
<% if (resourceType == Constants.BITSTREAM) \{ %> <tr> <th id="t3"><label for="tstartdate"><fmt:message key="jsp.dspace-admin.general.startdate-colon"/></label></th> <td headers="t3"> <% if (start_cal == null) \{ %> <input type="text" name="start_day" value="" maxlength="2" size="2"/> / <input type="text" name="start_month" value="" maxlength="2" size="2"/> / <input type="text" name="start_year" value="" maxlength="4" size="4"/> <fmt:message key="jsp.dspace-admin.general.startdate-help"/> <% \} else \{ %> <input type="text" name="start_day" value="<%=start_cal.get(Calendar.DAY_OF_MONTH)%>" maxlength="2" size="2"/> / <input type="text" name="start_month" value="<%=start_cal.get(Calendar.MONTH) + 1%>" maxlength="2" size="2"/> / <input type="text" name="start_year" value="<%=start_cal.get(Calendar.YEAR)%>" maxlength="4" size="4"/> <fmt:message key="jsp.dspace-admin.general.startdate-help"/> <% \} %> </td> </tr> <tr> <th id="t4"><label for="tstartdate"><fmt:message key="jsp.dspace-admin.general.enddate-colon"/></label></th> <td headers="t4"> <% if (end_cal == null) \{ %> <input type="text" name="end_day" value="" maxlength="2" size="2"/> / <input type="text" name="end_month" value="" maxlength="2" size="2"/> / <input type="text" name="end_year" value="" maxlength="4" size="4"/> <fmt:message key="jsp.dspace-admin.general.enddate-help"/> <% \} else \{ %> <input type="text" name="end_day" value="<%=end_cal.get(Calendar.DAY_OF_MONTH)%>" maxlength="2" size="2"/> / <input type="text" name="end_month" value="<%=end_cal.get(Calendar.MONTH) + 1%>" maxlength="2" size="2"/> / <input type="text" name="end_year" value="<%=end_cal.get(Calendar.YEAR)%>" maxlength="4" size="4"/> <fmt:message key="jsp.dspace-admin.general.enddate-help"/> <% \} %> </td> </tr> <script language="Javascript"> function validate(aForm) \{ var ssy = aForm.start_year.value; var ssm = aForm.start_month.value; var ssd = aForm.start_day.value; var sey = aForm.end_year.value; var sem = aForm.end_month.value; var sed = aForm.end_day.value; if ( ! onlyDigits(ssy+ssm+ssd)) \{ if (!confirm("Start date contains not only digits.\nUse this date anyway?")) \{ aForm.start_day.focus(); return false; \} \} if ( ! onlyDigits(sey+sem+sed)) \{ if (!confirm("End date contains not only digits.\nUse this date anyway?")) \{ aForm.end_day.focus(); return false; \} \} var sy = parseInt(ssy,10); var sm = parseInt(ssm,10); var sd = parseInt(ssd,10); var ey = parseInt(sey,10); var em = parseInt(sem,10); var ed = parseInt(sed,10); if ( ! isValidDate(sy,sm,sd)) \{ if (!confirm("Start date is not a valid date, it should be like dd/mm/yyy.\nUse this date anyway?")) \{ aForm.start_day.focus(); return false; \} \} if ( ! isValidDate(ey,em,ed) ) \{ if (!confirm("End date is not a valid date, it should be like dd/mm/yyy.\nUse this date anyway?")) \{ aForm.end_day.focus(); return false; \} \} if (!(isNaN(sy) || isNaN(sm) || isNaN(sd) || isNaN(ey) || isNaN(em) || isNaN(ed))) \{ if (!(sy <= ey && sm <= em && sd <= ed)) \{ if (!confirm("Start date is greater than end date. Use these dates anyway?")) \{ aForm.end_day.focus(); return false; \} \} \} return true; \} function isValidDate(y,m,d) \{ if (isNaN(y) && isNaN(m) && isNaN(d)) return true; if (isNaN(y) || isNaN(m) || isNaN(d)) return false; if (y < 1900 || y > 2100) return false; if (m < 1 || m > 12) return false; var dof = (y%4==0&&(y%100!=0||y%400==0))?29:28; var max = (m==4||m==6||m==9||m==11?30:(m==2?dof:31)); if (d < 1 || d > max) return false; return true; \} function onlyDigits(s) \{ for(var i = 0;i<s.length;i++) \{ if (isNaN(s.charAt(i))) \{ return false; \} \} return true; \} </script> <% \} %> |
Add the following lines to config/language-packs/Messages.properties:
jsp.dspace-admin.general.startdate-colon = Start date: jsp.dspace-admin.general.enddate-colon = End date: jsp.dspace-admin.general.startdate-help = (dd/mm/yyyy or blank) jsp.dspace-admin.general.enddate-help = (dd/mm/yyyy or blank) jsp.dspace-admin.general.period = Period jsp.submit.choose-file.embargohead =If the file is under embargo, please enter the end date of the embargo below jsp.submit.choose-file.embargo =Embargo Ends on: jsp.submit.choose-file.embargohelp = (dd/mm/yyyy, is optional) jsp.submit.upload-file-list.tableheading7 = Embargo jsp.submit.upload-file-list.no-embargo = None org.dspace.app.webui.jsptag.ItemTag.underEmbargo = Under Embargo org.dspace.app.webui.jsptag.ItemTag.embargoUntil = until |
This step is optional; if you do this the submitter can choose an embargo date when he/she uploads a file.
<tr> <td colspan="2"> </td> </tr> <tr> <td class="submitFormHelp" colspan="2"> <fmt:message key="jsp.submit.choose-file.embargohead"/> </td> </tr> <tr> <td class="submitFormLabel"><label for="tdescription"><fmt:message key="jsp.submit.choose-file.embargo"/></label></td> <td> <input type="text" name="embargo_day" value="" maxlength="2" size="2"/> / <input type="text" name="embargo_month" value="" maxlength="2" size="2"/> / <input type="text" name="embargo_year" value="" maxlength="4" size="4"/> <fmt:message key="jsp.submit.choose-file.embargohelp"/> </td> </tr> |
<%@ page import="org.dspace.authorize.ResourcePolicy" %> <%@ page import="java.util.Date" %> <%@ page import="java.util.Calendar" %> |
<th id="t8" class="oddRowEvenCol"><fmt:message key="jsp.submit.upload-file-list.tableheading7"/></th> |
<td headers="t8" class="evenRowEvenCol"> <% ResourcePolicy rp = bitstream.getAnonymousReadPolicy(); Date date; if ((rp != null) && (date = rp.getStartDate()) != null) \{ Calendar start_cal = Calendar.getInstance(); start_cal.setTime(date); out.print(start_cal.get(Calendar.DAY_OF_MONTH)); out.print("/"); out.print(start_cal.get(Calendar.MONTH) + 1); out.print("/"); out.println(start_cal.get(Calendar.YEAR)); \} else \{ %> <fmt:message key="jsp.submit.upload-file-list.no-embargo"/> <% \} %> </td> |
<%@ page import="org.dspace.authorize.ResourcePolicy" %> <%@ page import="java.util.Date" %> <%@ page import="java.util.Calendar" %> |
<th id="t8" class="oddRowOddCol"><fmt:message key="jsp.submit.upload-file-list.tableheading7"/></th> |
<td headers="t8" class="<%= row %>RowOddCol"> <% ResourcePolicy rp = bitstreams[i].getAnonymousReadPolicy(); Date date; if ((rp != null) && (date = rp.getStartDate()) != null) \{ Calendar start_cal = Calendar.getInstance(); start_cal.setTime(date); out.print(start_cal.get(Calendar.DAY_OF_MONTH)); out.print("/"); out.print(start_cal.get(Calendar.MONTH) + 1); out.print("/"); out.println(start_cal.get(Calendar.YEAR)); \} else \{ %> <fmt:message key="jsp.submit.upload-file-list.no-embargo"/> <% \} %> </td> |
Do the stuff you normally do when deploying a new version of DSpace.
With the following perl script you can set or remove the embargo of a list of items in one go:
Missing File: Setembargo.pl
The script is executed from the command line and gets 2 arguments:
May be you must alter the script, because of database issues. Please change this:
my $PSQL = "/usr/bin/psql";
in something more appropriate, like:
my $PSQL = "/usr/bin/psql -d dspace -U NAME -h HOSTNAME -p PORT";
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 dot leidenuniv dot nl
</html>