diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 7c5742ceab..f9e9f84f6a 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -551,6 +551,32 @@ webui.feed.formats = rss_1.0,rss_2.0 # Set to true to use local server URLs (i.e. http://myserver.myorg/handle/123456789/1) webui.feed.localresolve = false +# Customize each single-value field displayed in the +# feed information for each item. Each of +# the below fields takes a *single* metadata field +# +# The form is .[.|.*] +webui.feed.item.title = dc.title +webui.feed.item.date = dc.date.issued + +# Customise the metadata fields to show in the feed for each item's description. +# Elements will be displayed in the order that they are specified here. +# +# The form is .[.|.*][(date)], ... +# +# Similar to the item display UI, the name of the field for display +# in the feed will be drawn from the current UI dictionary, +# using the key: +# "metadata." +# +# e.g. "metadata.dc.title" +# "metadata.dc.contributor.author" +# "metadata.dc.date.issued" +webui.feed.item.description = dc.title, dc.contributor.author, \ + dc.contributor.editor, dc.description.abstract, \ + dc.description + + #### Item Recommendation Settings ##### # show a link to the item recommendation page from item display page webui.suggest.enable = false diff --git a/dspace/config/language-packs/Messages.properties b/dspace/config/language-packs/Messages.properties index 7aa1e6a5cc..30ffdeffee 100644 --- a/dspace/config/language-packs/Messages.properties +++ b/dspace/config/language-packs/Messages.properties @@ -12,6 +12,8 @@ itemlist.dc.type = Type metadata.dc.title = Title metadata.dc.title.alternative = Other Titles metadata.dc.contributor.* = Authors +metadata.dc.contributor.author = Authors +metadata.dc.contributor.editor = Editors metadata.dc.subject = Keywords metadata.dc.date.issued = Issue Date metadata.dc.publisher = Publisher @@ -1304,6 +1306,17 @@ org.dspace.app.webui.jsptag.SelectEPersonTag.selectPeople = Select E-people... org.dspace.app.webui.jsptag.SelectEPersonTag.selectPerson = Select E-person... org.dspace.app.webui.jsptag.SelectEPersonTag.removeSelected = Remove Selected +org.dspace.app.webui.servlet.FeedServlet.feed-type.collection = Collection +org.dspace.app.webui.servlet.FeedServlet.feed-type.community = Community +# In the following takes in feed type and the title of the collection/community +org.dspace.app.webui.servlet.FeedServlet.feed.title = DSpace {0}: {1} +org.dspace.app.webui.servlet.FeedServlet.logo.title = The Channel Image +org.dspace.app.webui.servlet.FeedServlet.search.description = Search the Channel +org.dspace.app.webui.servlet.FeedServlet.search.name = search +# The following takes in the feed type (collection or community) +org.dspace.app.webui.servlet.FeedServlet.search.title = The {0}''s search engine +org.dspace.app.webui.servlet.FeedServlet.notitle = no title + org.dspace.app.webui.servlet.admin.MetadataSchemaRegistryServlet.emptynamespace = The namespace cannot be empty. org.dspace.app.webui.servlet.admin.MetadataSchemaRegistryServlet.emptyname = The short name cannot be empty. org.dspace.app.webui.servlet.admin.MetadataSchemaRegistryServlet.nametolong = The short name must be 32 characters or less. diff --git a/dspace/src/org/dspace/app/webui/servlet/FeedServlet.java b/dspace/src/org/dspace/app/webui/servlet/FeedServlet.java index 3965e7ae24..2e98080a6d 100644 --- a/dspace/src/org/dspace/app/webui/servlet/FeedServlet.java +++ b/dspace/src/org/dspace/app/webui/servlet/FeedServlet.java @@ -42,12 +42,16 @@ package org.dspace.app.webui.servlet; import java.io.IOException; import java.sql.SQLException; +import java.text.MessageFormat; import java.util.Date; import java.util.Iterator; +import java.util.Locale; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.ArrayList; +import java.util.ResourceBundle; +import java.util.StringTokenizer; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -94,6 +98,8 @@ public class FeedServlet extends DSpaceServlet private static final long HOUR_MSECS = 60 * 60 * 1000; /** log4j category */ private static Logger log = Logger.getLogger(FeedServlet.class); + private String clazz = "org.dspace.app.webui.servlet.FeedServlet"; + // are syndication feeds enabled? private static boolean enabled = false; @@ -108,6 +114,13 @@ public class FeedServlet extends DSpaceServlet // supported syndication formats private static List formats = null; + // localized resource bundle + private static ResourceBundle labels = null; + + //default fields to display in item description + private static String defaultDescriptionFields = "dc.title, dc.contributor.author, dc.contributor.editor, dc.description.abstract, dc.description"; + + static { enabled = ConfigurationManager.getBooleanProperty("webui.feed.enable"); @@ -146,6 +159,13 @@ public class FeedServlet extends DSpaceServlet String feedType = null; String handle = null; + if(labels==null) + { + // Get access to the localized resource bundle + Locale locale = request.getLocale(); + labels = ResourceBundle.getBundle("Messages", locale); + } + if (path != null) { // substring(1) is to remove initial '/' @@ -273,7 +293,7 @@ public class FeedServlet extends DSpaceServlet if (dso.getType() == Constants.COLLECTION) { - type = "collection"; + type = labels.getString(clazz + ".feed-type.collection"); Collection col = (Collection)dso; description = col.getMetadata("short_description"); title = col.getMetadata("name"); @@ -282,7 +302,7 @@ public class FeedServlet extends DSpaceServlet } else if (dso.getType() == Constants.COMMUNITY) { - type = "community"; + type = labels.getString(clazz + ".feed-type.community"); Community comm = (Community)dso; description = comm.getMetadata("short_description"); title = comm.getMetadata("name"); @@ -293,14 +313,17 @@ public class FeedServlet extends DSpaceServlet // put in container-level data channel.setDescription(description); channel.setLink(objectUrl); - channel.setTitle("DSpace " + type + ": " + title); + //build channel title by passing in type and title + String channelTitle = MessageFormat.format(labels.getString(clazz + ".feed.title"), + new Object[]{type, title}); + channel.setTitle(channelTitle); if (logo != null) { // we use the path to the logo for this, the logo itself cannot // be contained in the rdf. Not all RSS-viewers show this logo. Image image = new Image(); image.setLink(objectUrl); - image.setTitle("The Channel Image"); + image.setTitle(labels.getString(clazz + ".logo.title")); image.setUrl(dspaceUrl + "/retrieve/" + logo.getID()); channel.setImage(image); } @@ -310,9 +333,12 @@ public class FeedServlet extends DSpaceServlet // version until this bug is fixed. TextInput input = new TextInput(); input.setLink(dspaceUrl + "/simple-search"); - input.setDescription( "Search the Channel" ); - input.setTitle("The " + type + "'s search engine"); - input.setName("s"); + input.setDescription( labels.getString(clazz + ".search.description") ); + //build search title by passing in type + String searchTitle = MessageFormat.format(labels.getString(clazz + ".search.title"), + new Object[]{type}); + input.setTitle(searchTitle); + input.setName(labels.getString(clazz + ".search.name")); channel.setTextInput(input); // gather & add items to the feed. @@ -344,111 +370,125 @@ public class FeedServlet extends DSpaceServlet com.sun.syndication.feed.rss.Item rssItem = new com.sun.syndication.feed.rss.Item(); + //get the title and date fields + String titleField = ConfigurationManager.getProperty("webui.feed.item.title"); + if (titleField == null) + { + titleField = "dc.title"; + } + + String dateField = ConfigurationManager.getProperty("webui.feed.item.date"); + if (dateField == null) + { + dateField = "dc.date.issued"; + } + + //Set item handle String itHandle = ConfigurationManager.getBooleanProperty("webui.feed.localresolve") ? HandleManager.resolveToURL(context, dspaceItem.getHandle()) : HandleManager.getCanonicalForm(dspaceItem.getHandle()); rssItem.setLink(itHandle); - String title = getDC(dspaceItem, "title", null, Item.ANY); - if (title == null) - { - title = "no_title"; - } + //get first title + String title = null; + try + { + title = dspaceItem.getMetadata(titleField)[0].value; + + } + catch (ArrayIndexOutOfBoundsException e) + { + title = labels.getString(clazz + ".notitle"); + } rssItem.setTitle(title); + // We put some metadata in the description field. This field is // displayed by most RSS viewers - StringBuffer descBuf = new StringBuffer(); - if ( ! "no_title".equals(title) ) - { - descBuf.append("title: "); - descBuf.append(title); - descBuf.append(" "); - } - DCValue[] authors = dspaceItem.getDC("contributor", "author", Item.ANY); - if (authors.length > 0) - { - descBuf.append("authors: "); - for (int i = 0; i < authors.length; i++) - { - descBuf.append(authors[i].value); - if (i < authors.length - 1) - { - descBuf.append("; "); - } - } - descBuf.append("\n
"); - } - DCValue[] editors = dspaceItem.getDC("contributor", "editor", Item.ANY); - if (editors.length > 0) - { - descBuf.append("editors: "); - for (int i = 0; i < editors.length; i++) - { - descBuf.append(editors[i].value); - if (i < editors.length - 1) - { - descBuf.append("; "); - } - } - descBuf.append("\n
"); - } - String abstr = getDC(dspaceItem, "description", "abstract", Item.ANY); - if (abstr != null) - { - descBuf.append("abstract: "); - descBuf.append(abstr); - descBuf.append("\n
"); - } - String desc = getDC(dspaceItem, "description", null, Item.ANY); - if (desc != null) - { - descBuf.append("description: "); - descBuf.append(desc); - descBuf.append("\n
"); - } + String descriptionFields = ConfigurationManager + .getProperty("webui.feed.item.description"); + if (descriptionFields == null) + { + descriptionFields = defaultDescriptionFields; + } + + //loop through all the metadata fields to put in the description + StringBuffer descBuf = new StringBuffer(); + StringTokenizer st = new StringTokenizer(descriptionFields, ","); + + while (st.hasMoreTokens()) + { + String field = st.nextToken().trim(); + boolean isDate = false; + + // Find out if the field should rendered as a date + if (field.indexOf("(date)") > 0) + { + field = field.replaceAll("\\(date\\)", ""); + isDate = true; + } + + + //print out this field, along with its value(s) + DCValue[] values = dspaceItem.getMetadata(field); + + if(values != null && values.length>0) + { + //as long as there is already something in the description + //buffer, print out a few line breaks before the next field + if(descBuf.length() > 0) + { + descBuf.append("\n
"); + descBuf.append("\n
"); + } + + String fieldLabel = null; + try + { + fieldLabel = labels.getString("metadata." + field); + } + catch(java.util.MissingResourceException e) {} + + if(fieldLabel !=null && fieldLabel.length()>0) + descBuf.append(fieldLabel + ": "); + + for(int i=0; i.[.|.*] + * + * @param mdString + * The metadata string of the form + * .[.|.*] + */ + public DCValue[] getMetadata(String mdString) + { + StringTokenizer dcf = new StringTokenizer(mdString, "."); + + String[] tokens = { "", "", "" }; + int i = 0; + while(dcf.hasMoreTokens()) + { + tokens[i] = dcf.nextToken().toLowerCase().trim(); + i++; + } + String schema = tokens[0]; + String element = tokens[1]; + String qualifier = tokens[2]; + + DCValue[] values; + if ("*".equals(qualifier)) + { + values = getMetadata(schema, element, Item.ANY, Item.ANY); + } + else if ("".equals(qualifier)) + { + values = getMetadata(schema, element, null, Item.ANY); + } + else + { + values = getMetadata(schema, element, qualifier, Item.ANY); + } + + return values; + } /** * Add Dublin Core metadata fields. These are appended to existing values.