Merge pull request #707 from EKT/DS-2162

DS-2162: Per item configurable visual indicators for browse and search results (JSPUI only)
This commit is contained in:
helix84
2014-10-29 00:13:37 +01:00
10 changed files with 535 additions and 5 deletions

View File

@@ -0,0 +1,91 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.itemmarking;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import org.dspace.app.util.Util;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
/**
* This is an item marking Strategy class that tries to mark an item availability
* based on the existence of bitstreams within the ORIGINAL bundle.
*
* @author Kostas Stamatis
*
*/
public class ItemMarkingAvailabilityBitstreamStrategy implements ItemMarkingExtractor {
private String availableImageName;
private String nonAvailableImageName;
public ItemMarkingAvailabilityBitstreamStrategy() {
}
@Override
public ItemMarkingInfo getItemMarkingInfo(Context context, Item item)
throws SQLException {
Bundle[] bundles = item.getBundles("ORIGINAL");
if (bundles.length == 0){
ItemMarkingInfo markInfo = new ItemMarkingInfo();
markInfo.setImageName(nonAvailableImageName);
return markInfo;
}
else {
Bundle originalBundle = bundles[0];
if (originalBundle.getBitstreams().length == 0){
ItemMarkingInfo markInfo = new ItemMarkingInfo();
markInfo.setImageName(nonAvailableImageName);
return markInfo;
}
else {
Bitstream bitstream = originalBundle.getBitstreams()[0];
ItemMarkingInfo signInfo = new ItemMarkingInfo();
signInfo.setImageName(availableImageName);
signInfo.setTooltip(bitstream.getName());
String bsLink = "";
bsLink = bsLink + "bitstream/"
+ item.getHandle() + "/"
+ bitstream.getSequenceID() + "/";
try {
bsLink = bsLink + Util.encodeBitstreamName(bitstream.getName(), Constants.DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
signInfo.setLink(bsLink);
return signInfo;
}
}
}
public void setAvailableImageName(String availableImageName) {
this.availableImageName = availableImageName;
}
public void setNonAvailableImageName(String nonAvailableImageName) {
this.nonAvailableImageName = nonAvailableImageName;
}
}

View File

@@ -0,0 +1,50 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.itemmarking;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.core.Context;
/**
* This is an item marking Strategy class that tries to mark an item
* based on the collection the items belong to
*
* @author Kostas Stamatis
*
*/
public class ItemMarkingCollectionStrategy implements ItemMarkingExtractor {
Map<String, ItemMarkingInfo> mapping = new HashMap<String, ItemMarkingInfo>();
public ItemMarkingCollectionStrategy() {
}
@Override
public ItemMarkingInfo getItemMarkingInfo(Context context, Item item)
throws SQLException {
if (mapping!=null){
for (Collection collection : item.getCollections()){
if (mapping.containsKey(collection.getHandle())){
return mapping.get(collection.getHandle());
}
}
}
return null;
}
public void setMapping(Map<String, ItemMarkingInfo> mapping) {
this.mapping = mapping;
}
}

View File

@@ -0,0 +1,24 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.itemmarking;
import java.sql.SQLException;
import org.dspace.content.Item;
import org.dspace.core.Context;
/**
* Interface to abstract the strategy for item signing
*
* @author Kostas Stamatis
*
*/
public interface ItemMarkingExtractor {
public ItemMarkingInfo getItemMarkingInfo(Context context, Item item)
throws SQLException;
}

View File

@@ -0,0 +1,57 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.itemmarking;
/**
* Simple DTO to transfer data about the marking info for an item
*
* @author Kostas Stamatis
*
*/
public class ItemMarkingInfo {
private String imageName;
private String classInfo;
private String tooltip;
private String link;
public ItemMarkingInfo() {
super();
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public String getTooltip() {
return tooltip;
}
public void setTooltip(String tooltip) {
this.tooltip = tooltip;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getClassInfo() {
return classInfo;
}
public void setClassInfo(String classInfo) {
this.classInfo = classInfo;
}
}

View File

@@ -0,0 +1,61 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.itemmarking;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.dspace.content.DCValue;
import org.dspace.content.Item;
import org.dspace.core.Context;
/**
* This is an item marking Strategy class that tries to mark an item
* based on the existence of a specific value within the values of a specific
* metadata field
*
* @author Kostas Stamatis
*
*/
public class ItemMarkingMetadataStrategy implements ItemMarkingExtractor {
private String metadataField;
Map<String, ItemMarkingInfo> mapping = new HashMap<String, ItemMarkingInfo>();
public ItemMarkingMetadataStrategy() {
}
@Override
public ItemMarkingInfo getItemMarkingInfo(Context context, Item item)
throws SQLException {
if (metadataField != null && mapping!=null)
{
DCValue[] vals = item.getMetadataByMetadataString(metadataField);
if (vals.length > 0)
{
for (DCValue value : vals){
String type = value.value;
if (mapping.containsKey(type)){
return mapping.get(type);
}
}
}
}
return null;
}
public void setMetadataField(String metadataField) {
this.metadataField = metadataField;
}
public void setMapping(Map<String, ItemMarkingInfo> mapping) {
this.mapping = mapping;
}
}

View File

@@ -10,6 +10,8 @@ package org.dspace.app.webui.jsptag;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.app.itemmarking.ItemMarkingExtractor;
import org.dspace.app.itemmarking.ItemMarkingInfo;
import org.dspace.app.webui.util.UIUtil;
import org.dspace.browse.*;
import org.dspace.content.Bitstream;
@@ -24,6 +26,7 @@ import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.storage.bitstore.BitstreamStorageManager;
import org.dspace.sort.SortOption;
import org.dspace.utils.DSpace;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
@@ -388,8 +391,14 @@ public class BrowseListTag extends TagSupport
String css = "oddRow" + cOddOrEven[colIdx] + "Col";
String message = "itemlist." + field;
String markClass = "";
if (field.startsWith("mark_"))
{
markClass = " "+field+"_th";
}
// output the header
out.print("<th id=\"" + id + "\" class=\"" + css + "\">"
out.print("<th id=\"" + id + "\" class=\"" + css + markClass +"\">"
+ (emph[colIdx] ? "<strong>" : "")
+ LocaleSupport.getLocalizedMessage(pageContext, message)
+ (emph[colIdx] ? "</strong>" : "") + "</th>");
@@ -474,6 +483,10 @@ public class BrowseListTag extends TagSupport
{
metadata = getThumbMarkup(hrq, items[i]);
}
else if (field.startsWith("mark_"))
{
metadata = UIUtil.getMarkingMarkup(hrq, items[i], field);
}
else if (metadataArray.length > 0)
{
// format the date field correctly
@@ -594,10 +607,16 @@ public class BrowseListTag extends TagSupport
{
extras = "nowrap=\"nowrap\" align=\"right\"";
}
String markClass = "";
if (field.startsWith("mark_"))
{
markClass = " "+field+"_tr";
}
String id = "t" + Integer.toString(colIdx + 1);
out.print("<td headers=\"" + id + "\" class=\""
+ rOddOrEven + "Row" + cOddOrEven[colIdx] + "Col\" " + extras + ">"
+ rOddOrEven + "Row" + cOddOrEven[colIdx] + "Col" + markClass + "\" " + extras + ">"
+ (emph[colIdx] ? "<strong>" : "") + metadata + (emph[colIdx] ? "</strong>" : "")
+ "</td>");
}

View File

@@ -10,6 +10,8 @@ package org.dspace.app.webui.jsptag;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.app.itemmarking.ItemMarkingExtractor;
import org.dspace.app.itemmarking.ItemMarkingInfo;
import org.dspace.app.webui.util.UIUtil;
import org.dspace.browse.BrowseException;
@@ -30,6 +32,7 @@ import org.dspace.core.Utils;
import org.dspace.sort.SortOption;
import org.dspace.storage.bitstore.BitstreamStorageManager;
import org.dspace.utils.DSpace;
import java.awt.image.BufferedImage;
@@ -353,8 +356,14 @@ public class ItemListTag extends TagSupport
String css = "oddRow" + cOddOrEven[colIdx] + "Col";
String message = "itemlist." + field;
String markClass = "";
if (field.startsWith("mark_"))
{
markClass = " "+field+"_th";
}
// output the header
out.print("<th id=\"" + id + "\" class=\"" + css + "\">"
out.print("<th id=\"" + id + "\" class=\"" + css + markClass +"\">"
+ (emph[colIdx] ? "<strong>" : "")
+ LocaleSupport.getLocalizedMessage(pageContext, message)
+ (emph[colIdx] ? "</strong>" : "") + "</th>");
@@ -439,6 +448,10 @@ public class ItemListTag extends TagSupport
{
metadata = getThumbMarkup(hrq, items[i]);
}
else if (field.startsWith("mark_"))
{
metadata = UIUtil.getMarkingMarkup(hrq, items[i], field);
}
if (metadataArray.length > 0)
{
// format the date field correctly
@@ -560,9 +573,16 @@ public class ItemListTag extends TagSupport
extras = "nowrap=\"nowrap\" align=\"right\"";
}
String markClass = "";
if (field.startsWith("mark_"))
{
markClass = " "+field+"_tr";
}
String id = "t" + Integer.toString(colIdx + 1);
out.print("<td headers=\"" + id + "\" class=\""
+ rOddOrEven + "Row" + cOddOrEven[colIdx] + "Col\" " + extras + ">"
+ rOddOrEven + "Row" + cOddOrEven[colIdx] + "Col" + markClass + "\" " + extras + ">"
+ (emph[colIdx] ? "<strong>" : "") + metadata + (emph[colIdx] ? "</strong>" : "")
+ "</td>");
}
@@ -873,4 +893,4 @@ public class ItemListTag extends TagSupport
throw new JspException("Server does not support DSpace's default encoding. ", e);
}
}
}
}

View File

@@ -22,21 +22,28 @@ import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.jstl.core.Config;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.app.itemmarking.ItemMarkingExtractor;
import org.dspace.app.itemmarking.ItemMarkingInfo;
import org.dspace.app.util.Util;
import org.dspace.authenticate.AuthenticationManager;
import org.dspace.browse.BrowseItem;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DCDate;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.Email;
import org.dspace.core.I18nUtil;
import org.dspace.eperson.EPerson;
import org.dspace.utils.DSpace;
/**
* Miscellaneous UI utility methods
@@ -470,4 +477,114 @@ public class UIUtil extends Util
response.setHeader("Content-Disposition", "attachment;filename=" + name);
}
}
/**
* Generate the (X)HTML required to show the item marking. Based on the markType it tries to find
* the corresponding item marking Strategy on the iem_marking.xml Spring configuration file in order
* to apply it to the item.
* This method is used in BrowseListTag and ItemListTag to du the actual item marking in browse
* and search results
*
* @param hrq The servlet request
* @param dso The DSpaceObject to mark (it can be a BrowseItem or an Item)
* @param markType the type of the mark.
* @return
* @throws JspException
*/
public static String getMarkingMarkup(HttpServletRequest hrq, DSpaceObject dso, String markType)
throws JspException
{
try
{
String contextPath = hrq.getContextPath();
Context c = UIUtil.obtainContext(hrq);
Item item = null;
if (dso instanceof BrowseItem){
item = Item.find(c, dso.getID());
}
else if (dso instanceof Item){
item = (Item)dso;
}
String mark = markType.replace("mark_", "");
ItemMarkingExtractor markingExtractor = new DSpace()
.getServiceManager()
.getServiceByName(
ItemMarkingExtractor.class.getName()+"."+mark,
ItemMarkingExtractor.class);
if (markingExtractor == null){ // In case we cannot find the corresponding extractor (strategy) in xml beans
return "";
}
ItemMarkingInfo markInfo = markingExtractor.getItemMarkingInfo(c, item);
if (markInfo == null){
return "";
}
StringBuffer markFrag = new StringBuffer();
String localizedTooltip = null;
if (markInfo.getTooltip()!=null){
localizedTooltip = org.dspace.core.I18nUtil.getMessage(markInfo.getTooltip(), hrq.getLocale());
}
String markLink = markInfo.getLink();
if (markInfo.getImageName()!=null){
//Link
if (StringUtils.isNotEmpty(markLink)){
markFrag.append("<a href=\"")
.append(contextPath+"/" + markLink)
.append("\">");
}
markFrag.append("<img class=\""+markType+"_img\" src=\""+ contextPath+"/")
.append(markInfo.getImageName()).append("\"");
if (StringUtils.isNotEmpty(localizedTooltip)){
markFrag.append(" title=\"")
.append(localizedTooltip)
.append("\"");
}
markFrag.append("/>");
//Link
if (StringUtils.isNotEmpty(markLink)){
markFrag.append("</a>");
}
}
else if (markInfo.getClassInfo()!=null){
//Link
if (StringUtils.isNotEmpty(markLink)){
markFrag.append("<a href=\"")
.append(contextPath+"/" + markLink)
.append("\">");
}
markFrag.append("<div class=\""+markType+"_class" + " " + markInfo.getClassInfo() + "\" ");
if (StringUtils.isNotEmpty(localizedTooltip)){
markFrag.append(" title=\"")
.append(localizedTooltip)
.append("\"");
}
markFrag.append("/>");
//Link
if (StringUtils.isNotEmpty(markLink)){
markFrag.append("</a>");
}
}
return markFrag.toString();
}
catch (SQLException sqle)
{
throw new JspException(sqle.getMessage(), sqle);
}
}
}

View File

@@ -1793,6 +1793,13 @@ plugin.single.org.dspace.app.webui.util.StyleSelection = \
# If you have enabled thumbnails (webui.browse.thumbnail.show), you must also
# include a 'thumbnail' entry in your columns - this is where the thumbnail will be displayed
#
# If you want to mark each item include a 'mark_[value]' (without the brackets - replace the word 'value' with anything that
# has a meaning for your mark) entry in your columns - this is where the icon will be displayed.
# Do not forget to add a Spring bean with id = "org.dspace.app.itemmarking.ItemMarkingExtractor.[value]"
# in file 'config/spring/api/item-marking.xml'. This bean is responsible for drawing the appropriate mark for each item.
# You can add more than one 'mark_[value]' options (with different value) in case you need to mark items more than one time for
# different purposes. Remember to add the respective beans in file 'config/spring/api/item-marking.xml'.
#
# webui.itemlist.columns = thumbnail, dc.date.issued(date), dc.title, dc.contributor.*
#
# You can customise the width of each column with the following line - you can have numbers (pixels)

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The contents of this file are subject to the license and copyright
detailed in the LICENSE and NOTICE files at the root of the source
tree and available online at
http://www.dspace.org/license/
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire-candidates="*Service,*DAO,javax.sql.DataSource">
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
<!-- Enable this strategy in order to mark item based on the value of a metadata field -->
<bean class="org.dspace.app.itemmarking.ItemMarkingMetadataStrategy"
id="org.dspace.app.itemmarking.ItemMarkingExtractor.type">
<property name="metadataField" value="dc.type" />
<property name="mapping" ref="typeMap"/>
</bean>
<!-- Enable this strategy in order to mark items based on the collection the item belongs to -->
<!-- <bean class="org.dspace.app.itemmarking.ItemMarkingCollectionStrategy"
id="org.dspace.app.itemmarking.ItemMarkingExtractor.type">
<property name="mapping" ref="collectionMap"/>
</bean> -->
<!-- Enable this strategy in order to mark items based on the availability of their bitstreams -->
<bean class="org.dspace.app.itemmarking.ItemMarkingAvailabilityBitstreamStrategy"
id="org.dspace.app.itemmarking.ItemMarkingExtractor.availability">
<property name="availableImageName" value="image/available.png" />
<property name="nonAvailableImageName" value="image/nonavailable.png" />
</bean>
<bean class="java.util.HashMap" id="typeMap">
<constructor-arg>
<map>
<!-- <entry>
<key>
<value>image</value>
</key>
<ref bean="type1MarkingInfo"/>
</entry>
<entry>
<key>
<value>video</value>
</key>
<ref bean="type2MarkingInfo"/>
</entry> -->
</map>
</constructor-arg>
</bean>
<bean class="java.util.HashMap" id="collectionMap">
<constructor-arg>
<map>
<!-- <entry>
<key>
<value>123456789/2</value>
</key>
<ref bean="type1MarkingInfo"/>
</entry> -->
</map>
</constructor-arg>
</bean>
<!-- <bean class="org.dspace.app.itemmarking.ItemMarkingInfo" id="type1MarkingInfo">
<property name="classInfo" value="glyphicon glyphicon-picture"/>
<property name="tooltip" value="itemlist.mark.type1MarkingInfo"/>
</bean>
<bean class="org.dspace.app.itemmarking.ItemMarkingInfo" id="type2MarkingInfo">
<property name="imageName" value="image/type2.png"/>
<property name="tooltip" value="itemlist.mark.type2MarkingInfo"/>
</bean> -->
</beans>