Commit f7ef86d64c6c2aebf0f365a7e4fd538ec7a11970

Authored by Fernando Ribeiro
1 parent d88830cb25

Changed the Behaviour of BrowseListTag to have a link in the title to Inform Ite…

…m Removed - This permits the manager of dspace to see the handle
dspace/modules/jspui/pom.xml
... ... @@ -93,12 +93,19 @@
93 93 </dependency>
94 94  
95 95 <dependency>
96   - <groupId>org.dspace</groupId>
  96 + <groupId>org.dspace</groupId><dependency>
  97 + <groupId>javax.servlet</groupId>
  98 + <artifactId>jsp-api</artifactId>
  99 + <version>2.0</version>
  100 + <scope>provided</scope>
  101 + </dependency>
  102 +
97 103 <artifactId>dspace-jspui</artifactId>
98 104 <type>jar</type>
99 105 <classifier>classes</classifier>
100 106 </dependency>
101 107  
  108 +<!-- Added to permit the BrowseListTag be in here, as we add a change in BrowseListTag -->
102 109 <dependency>
103 110 <groupId>javax.servlet</groupId>
104 111 <artifactId>servlet-api</artifactId>
... ... @@ -106,4 +113,6 @@
106 113 </dependency>
107 114 </dependencies>
108 115  
  116 +
  117 +
109 118 </project>
110 119 \ No newline at end of file
... ...
dspace/modules/jspui/src/main/java/org/dspace/webui/jsptag/BrowseListTag.java
... ... @@ -0,0 +1,937 @@
  1 +/**
  2 + * The contents of this file are subject to the license and copyright
  3 + * detailed in the LICENSE and NOTICE files at the root of the source
  4 + * tree and available online at
  5 + *
  6 + * http://www.dspace.org/license/
  7 + */
  8 +package org.dspace.app.webui.jsptag;
  9 +
  10 +import org.apache.commons.lang.ArrayUtils;
  11 +import org.apache.commons.lang.StringUtils;
  12 +import org.apache.log4j.Logger;
  13 +import org.dspace.app.itemmarking.ItemMarkingExtractor;
  14 +import org.dspace.app.itemmarking.ItemMarkingInfo;
  15 +import org.dspace.app.webui.util.UIUtil;
  16 +import org.dspace.browse.*;
  17 +import org.dspace.content.Bitstream;
  18 +import org.dspace.content.DCDate;
  19 +import org.dspace.content.Metadatum;
  20 +import org.dspace.content.Item;
  21 +import org.dspace.content.Thumbnail;
  22 +import org.dspace.content.service.ItemService;
  23 +import org.dspace.core.ConfigurationManager;
  24 +import org.dspace.core.Constants;
  25 +import org.dspace.core.Context;
  26 +import org.dspace.core.Utils;
  27 +import org.dspace.storage.bitstore.BitstreamStorageManager;
  28 +import org.dspace.sort.SortOption;
  29 +import org.dspace.utils.DSpace;
  30 +
  31 +import javax.imageio.ImageIO;
  32 +import javax.servlet.http.HttpServletRequest;
  33 +import javax.servlet.jsp.JspException;
  34 +import javax.servlet.jsp.JspWriter;
  35 +import javax.servlet.jsp.jstl.fmt.LocaleSupport;
  36 +import javax.servlet.jsp.tagext.TagSupport;
  37 +import java.awt.image.BufferedImage;
  38 +import java.io.IOException;
  39 +import java.io.InputStream;
  40 +import java.io.UnsupportedEncodingException;
  41 +import java.net.URLEncoder;
  42 +import java.sql.SQLException;
  43 +import java.util.StringTokenizer;
  44 +import org.dspace.content.authority.MetadataAuthorityManager;
  45 +//UM
  46 +import pt.keep.dspace.report.ReportLinkManager;
  47 +//END UM
  48 +
  49 +/**
  50 + * Tag for display a list of items
  51 + *
  52 + * @author Robert Tansley
  53 + * @version $Revision$
  54 + */
  55 +public class BrowseListTag extends TagSupport
  56 +{
  57 + /** log4j category */
  58 + private static Logger log = Logger.getLogger(BrowseListTag.class);
  59 +
  60 + /** Items to display */
  61 + private transient BrowseItem[] items;
  62 +
  63 + /** Row to highlight, -1 for no row */
  64 + private int highlightRow = -1;
  65 +
  66 + /** Column to emphasise, identified by metadata field */
  67 + private String emphColumn;
  68 +
  69 + /** Config value of thumbnail view toggle */
  70 + private static boolean showThumbs;
  71 +
  72 + /** Config browse/search width and height */
  73 + private static int thumbItemListMaxWidth;
  74 +
  75 + private static int thumbItemListMaxHeight;
  76 +
  77 + /** Config browse/search thumbnail link behaviour */
  78 + private static boolean linkToBitstream = false;
  79 +
  80 + /** Config to include an edit link */
  81 + private boolean linkToEdit = false;
  82 +
  83 + /** Config to disable cross links */
  84 + private boolean disableCrossLinks = false;
  85 +
  86 + /** The default fields to be displayed when listing items */
  87 + private static final String DEFAULT_LIST_FIELDS;
  88 +
  89 + /** The default widths for the columns */
  90 + private static final String DEFAULT_LIST_WIDTHS;
  91 +
  92 + /** The default field which is bound to the browse by date */
  93 + private static String dateField = "dc.date.issued";
  94 +
  95 + /** The default field which is bound to the browse by title */
  96 + private static String titleField = "dc.title";
  97 +
  98 + private static String authorField = "dc.contributor.*";
  99 +
  100 + private int authorLimit = -1;
  101 +
  102 + private transient BrowseInfo browseInfo;
  103 +
  104 + private static final long serialVersionUID = 8091584920304256107L;
  105 +
  106 + static
  107 + {
  108 + getThumbSettings();
  109 +
  110 + if (showThumbs)
  111 + {
  112 + DEFAULT_LIST_FIELDS = "thumbnail, dc.date.issued(date), dc.title, dc.contributor.*";
  113 + DEFAULT_LIST_WIDTHS = "*, 130, 60%, 40%";
  114 + }
  115 + else
  116 + {
  117 + DEFAULT_LIST_FIELDS = "dc.date.issued(date), dc.title, dc.contributor.*";
  118 + DEFAULT_LIST_WIDTHS = "130, 60%, 40%";
  119 + }
  120 +
  121 + // get the date and title fields
  122 + String dateLine = ConfigurationManager.getProperty("webui.browse.index.date");
  123 + if (dateLine != null)
  124 + {
  125 + dateField = dateLine;
  126 + }
  127 +
  128 + String titleLine = ConfigurationManager.getProperty("webui.browse.index.title");
  129 + if (titleLine != null)
  130 + {
  131 + titleField = titleLine;
  132 + }
  133 +
  134 + // get the author truncation config
  135 + String authorLine = ConfigurationManager.getProperty("webui.browse.author-field");
  136 + if (authorLine != null)
  137 + {
  138 + authorField = authorLine;
  139 + }
  140 + }
  141 +
  142 + public BrowseListTag()
  143 + {
  144 + super();
  145 + }
  146 +
  147 + public int doStartTag() throws JspException
  148 + {
  149 + JspWriter out = pageContext.getOut();
  150 + HttpServletRequest hrq = (HttpServletRequest) pageContext.getRequest();
  151 +
  152 + /* just leave this out now
  153 + boolean emphasiseDate = false;
  154 + boolean emphasiseTitle = false;
  155 +
  156 + if (emphColumn != null)
  157 + {
  158 + emphasiseDate = emphColumn.equalsIgnoreCase("date");
  159 + emphasiseTitle = emphColumn.equalsIgnoreCase("title");
  160 + }
  161 + */
  162 +
  163 + // get the elements to display
  164 + String browseListLine = null;
  165 + String browseWidthLine = null;
  166 +
  167 + // As different indexes / sort options may require different columns to be displayed
  168 + // try to obtain a custom configuration based for the browse that has been performed
  169 + if (browseInfo != null)
  170 + {
  171 + SortOption so = browseInfo.getSortOption();
  172 + BrowseIndex bix = browseInfo.getBrowseIndex();
  173 +
  174 + // We have obtained the index that was used for this browse
  175 + if (bix != null)
  176 + {
  177 + // First, try to get a configuration for this browse and sort option combined
  178 + if (so != null && browseListLine == null)
  179 + {
  180 + browseListLine = ConfigurationManager.getProperty("webui.itemlist.browse." + bix.getName() + ".sort." + so.getName() + ".columns");
  181 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist.browse." + bix.getName() + ".sort." + so.getName() + ".widths");
  182 + }
  183 +
  184 + // We haven't got a sort option defined, so get one for the index
  185 + // - it may be required later
  186 + if (so == null)
  187 + {
  188 + so = bix.getSortOption();
  189 + }
  190 + }
  191 +
  192 + // If no config found, attempt to get one for this sort option
  193 + if (so != null && browseListLine == null)
  194 + {
  195 + browseListLine = ConfigurationManager.getProperty("webui.itemlist.sort." + so.getName() + ".columns");
  196 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist.sort." + so.getName() + ".widths");
  197 + }
  198 +
  199 + // If no config found, attempt to get one for this browse index
  200 + if (bix != null && browseListLine == null)
  201 + {
  202 + browseListLine = ConfigurationManager.getProperty("webui.itemlist.browse." + bix.getName() + ".columns");
  203 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist.browse." + bix.getName() + ".widths");
  204 + }
  205 +
  206 + // If no config found, attempt to get a general one, using the sort name
  207 + if (so != null && browseListLine == null)
  208 + {
  209 + browseListLine = ConfigurationManager.getProperty("webui.itemlist." + so.getName() + ".columns");
  210 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist." + so.getName() + ".widths");
  211 + }
  212 +
  213 + // If no config found, attempt to get a general one, using the index name
  214 + if (bix != null && browseListLine == null)
  215 + {
  216 + browseListLine = ConfigurationManager.getProperty("webui.itemlist." + bix.getName() + ".columns");
  217 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist." + bix.getName() + ".widths");
  218 + }
  219 + }
  220 +
  221 + if (browseListLine == null)
  222 + {
  223 + browseListLine = ConfigurationManager.getProperty("webui.itemlist.columns");
  224 + browseWidthLine = ConfigurationManager.getProperty("webui.itemlist.widths");
  225 + }
  226 +
  227 + // Have we read a field configration from dspace.cfg?
  228 + if (browseListLine != null)
  229 + {
  230 + // If thumbnails are disabled, strip out any thumbnail column from the configuration
  231 + if (!showThumbs && browseListLine.contains("thumbnail"))
  232 + {
  233 + // Ensure we haven't got any nulls
  234 + browseListLine = browseListLine == null ? "" : browseListLine;
  235 + browseWidthLine = browseWidthLine == null ? "" : browseWidthLine;
  236 +
  237 + // Tokenize the field and width lines
  238 + StringTokenizer bllt = new StringTokenizer(browseListLine, ",");
  239 + StringTokenizer bwlt = new StringTokenizer(browseWidthLine, ",");
  240 +
  241 + StringBuilder newBLLine = new StringBuilder();
  242 + StringBuilder newBWLine = new StringBuilder();
  243 + while (bllt.hasMoreTokens() || bwlt.hasMoreTokens())
  244 + {
  245 + String browseListTok = bllt.hasMoreTokens() ? bllt.nextToken() : null;
  246 + String browseWidthTok = bwlt.hasMoreTokens() ? bwlt.nextToken() : null;
  247 +
  248 + // Only use the Field and Width tokens, if the field isn't 'thumbnail'
  249 + if (browseListTok == null || !browseListTok.trim().equals("thumbnail"))
  250 + {
  251 + if (browseListTok != null)
  252 + {
  253 + if (newBLLine.length() > 0)
  254 + {
  255 + newBLLine.append(",");
  256 + }
  257 +
  258 + newBLLine.append(browseListTok);
  259 + }
  260 +
  261 + if (browseWidthTok != null)
  262 + {
  263 + if (newBWLine.length() > 0)
  264 + {
  265 + newBWLine.append(",");
  266 + }
  267 +
  268 + newBWLine.append(browseWidthTok);
  269 + }
  270 + }
  271 + }
  272 +
  273 + // Use the newly built configuration file
  274 + browseListLine = newBLLine.toString();
  275 + browseWidthLine = newBWLine.toString();
  276 + }
  277 + }
  278 + else
  279 + {
  280 + browseListLine = DEFAULT_LIST_FIELDS;
  281 + browseWidthLine = DEFAULT_LIST_WIDTHS;
  282 + }
  283 +
  284 + // Arrays used to hold the information we will require when outputting each row
  285 + String[] fieldArr = browseListLine == null ? new String[0] : browseListLine.split("\\s*,\\s*");
  286 + String[] widthArr = browseWidthLine == null ? new String[0] : browseWidthLine.split("\\s*,\\s*");
  287 + boolean isDate[] = new boolean[fieldArr.length];
  288 + boolean emph[] = new boolean[fieldArr.length];
  289 + boolean isAuthor[] = new boolean[fieldArr.length];
  290 + boolean viewFull[] = new boolean[fieldArr.length];
  291 + String[] browseType = new String[fieldArr.length];
  292 + String[] cOddOrEven = new String[fieldArr.length];
  293 +
  294 + try
  295 + {
  296 + // Get the interlinking configuration too
  297 + CrossLinks cl = new CrossLinks();
  298 +
  299 + // Get a width for the table
  300 + String tablewidth = ConfigurationManager.getProperty("webui.itemlist.tablewidth");
  301 +
  302 + // If we have column widths, try to use a fixed layout table - faster for browsers to render
  303 + // but not if we have to add an 'edit item' button - we can't know how big it will be
  304 + if (widthArr.length > 0 && widthArr.length == fieldArr.length && !linkToEdit)
  305 + {
  306 + // If the table width has been specified, we can make this a fixed layout
  307 + if (!StringUtils.isEmpty(tablewidth))
  308 + {
  309 + out.println("<table style=\"width: " + tablewidth + "; table-layout: fixed;\" align=\"center\" class=\"table\" summary=\"This table browses all dspace content\">");
  310 + }
  311 + else
  312 + {
  313 + // Otherwise, don't constrain the width
  314 + out.println("<table align=\"center\" class=\"table\" summary=\"This table browses all dspace content\">");
  315 + }
  316 +
  317 + // Output the known column widths
  318 + out.print("<colgroup>");
  319 +
  320 + for (int w = 0; w < widthArr.length; w++)
  321 + {
  322 + out.print("<col width=\"");
  323 +
  324 + // For a thumbnail column of width '*', use the configured max width for thumbnails
  325 + if (fieldArr[w].equals("thumbnail") && widthArr[w].equals("*"))
  326 + {
  327 + out.print(thumbItemListMaxWidth);
  328 + }
  329 + else
  330 + {
  331 + out.print(StringUtils.isEmpty(widthArr[w]) ? "*" : widthArr[w]);
  332 + }
  333 +
  334 + out.print("\" />");
  335 + }
  336 +
  337 + out.println("</colgroup>");
  338 + }
  339 + else if (!StringUtils.isEmpty(tablewidth))
  340 + {
  341 + out.println("<table width=\"" + tablewidth + "\" align=\"center\" class=\"table\" summary=\"This table browses all dspace content\">");
  342 + }
  343 + else
  344 + {
  345 + out.println("<table align=\"center\" class=\"table\" summary=\"This table browses all dspace content\">");
  346 + }
  347 +
  348 + // Output the table headers
  349 + out.println("<tr>");
  350 +
  351 + for (int colIdx = 0; colIdx < fieldArr.length; colIdx++)
  352 + {
  353 + String field = fieldArr[colIdx].toLowerCase().trim();
  354 + cOddOrEven[colIdx] = (((colIdx + 1) % 2) == 0 ? "Odd" : "Even");
  355 +
  356 + // find out if the field is a date
  357 + if (field.indexOf("(date)") > 0)
  358 + {
  359 + field = field.replaceAll("\\(date\\)", "");
  360 + isDate[colIdx] = true;
  361 + }
  362 +
  363 + // Cache any modifications to field
  364 + fieldArr[colIdx] = field;
  365 +
  366 + // find out if this is the author column
  367 + if (field.equals(authorField))
  368 + {
  369 + isAuthor[colIdx] = true;
  370 + }
  371 +
  372 + // find out if this field needs to link out to other browse views
  373 + if (cl.hasLink(field))
  374 + {
  375 + browseType[colIdx] = cl.getLinkType(field);
  376 + viewFull[colIdx] = BrowseIndex.getBrowseIndex(browseType[colIdx]).isItemIndex();
  377 + }
  378 +
  379 + // find out if we are emphasising this field
  380 + /*
  381 + if ((field.equals(dateField) && emphasiseDate) ||
  382 + (field.equals(titleField) && emphasiseTitle))
  383 + {
  384 + emph[colIdx] = true;
  385 + }
  386 + */
  387 + if (field.equals(emphColumn))
  388 + {
  389 + emph[colIdx] = true;
  390 + }
  391 +
  392 + // prepare the strings for the header
  393 + String id = "t" + Integer.toString(colIdx + 1);
  394 + String css = "oddRow" + cOddOrEven[colIdx] + "Col";
  395 + String message = "itemlist." + field;
  396 +
  397 + String markClass = "";
  398 + if (field.startsWith("mark_"))
  399 + {
  400 + markClass = " "+field+"_th";
  401 + }
  402 +
  403 + // output the header
  404 + out.print("<th id=\"" + id + "\" class=\"" + css + markClass +"\">"
  405 + + (emph[colIdx] ? "<strong>" : "")
  406 + + LocaleSupport.getLocalizedMessage(pageContext, message)
  407 + + (emph[colIdx] ? "</strong>" : "") + "</th>");
  408 + }
  409 +
  410 + if (linkToEdit)
  411 + {
  412 + String id = "t" + Integer.toString(cOddOrEven.length + 1);
  413 + String css = "oddRow" + cOddOrEven[cOddOrEven.length - 2] + "Col";
  414 +
  415 + // output the header
  416 + out.print("<th id=\"" + id + "\" class=\"" + css + "\">"
  417 + + (emph[emph.length - 2] ? "<strong>" : "")
  418 + + "&nbsp;" //LocaleSupport.getLocalizedMessage(pageContext, message)
  419 + + (emph[emph.length - 2] ? "</strong>" : "") + "</th>");
  420 + }
  421 +
  422 + out.print("</tr>");
  423 +
  424 + // now output each item row
  425 + for (int i = 0; i < items.length; i++)
  426 + {
  427 + out.print("<tr>");
  428 + // now prepare the XHTML frag for this division
  429 + String rOddOrEven;
  430 + if (i == highlightRow)
  431 + {
  432 + rOddOrEven = "highlight";
  433 + }
  434 + else
  435 + {
  436 + rOddOrEven = ((i & 1) == 1 ? "odd" : "even");
  437 + }
  438 +
  439 + for (int colIdx = 0; colIdx < fieldArr.length; colIdx++)
  440 + {
  441 + String field = fieldArr[colIdx];
  442 +
  443 + // get the schema and the element qualifier pair
  444 + // (Note, the schema is not used for anything yet)
  445 + // (second note, I hate this bit of code. There must be
  446 + // a much more elegant way of doing this. Tomcat has
  447 + // some weird problems with variations on this code that
  448 + // I tried, which is why it has ended up the way it is)
  449 + StringTokenizer eq = new StringTokenizer(field, ".");
  450 +
  451 + String[] tokens = { "", "", "" };
  452 + int k = 0;
  453 + while(eq.hasMoreTokens())
  454 + {
  455 + tokens[k] = eq.nextToken().toLowerCase().trim();
  456 + k++;
  457 + }
  458 + String schema = tokens[0];
  459 + String element = tokens[1];
  460 + String qualifier = tokens[2];
  461 +
  462 + // first get hold of the relevant metadata for this column
  463 + Metadatum[] metadataArray;
  464 + if (qualifier.equals("*"))
  465 + {
  466 + metadataArray = items[i].getMetadata(schema, element, Item.ANY, Item.ANY);
  467 + }
  468 + else if (qualifier.equals(""))
  469 + {
  470 + metadataArray = items[i].getMetadata(schema, element, null, Item.ANY);
  471 + }
  472 + else
  473 + {
  474 + metadataArray = items[i].getMetadata(schema, element, qualifier, Item.ANY);
  475 + }
  476 +
  477 + // save on a null check which would make the code untidy
  478 + if (metadataArray == null)
  479 + {
  480 + metadataArray = new Metadatum[0];
  481 + }
  482 +
  483 + // now prepare the content of the table division
  484 + String metadata = "-";
  485 + if (field.equals("thumbnail"))
  486 + {
  487 + metadata = getThumbMarkup(hrq, items[i]);
  488 + }
  489 + else if (field.startsWith("mark_"))
  490 + {
  491 + metadata = UIUtil.getMarkingMarkup(hrq, items[i], field);
  492 + }
  493 + else if (metadataArray.length > 0)
  494 + {
  495 + // format the date field correctly
  496 + if (isDate[colIdx])
  497 + {
  498 + DCDate dd = new DCDate(metadataArray[0].value);
  499 + metadata = UIUtil.displayDate(dd, false, false, hrq);
  500 + }
  501 + // format the title field correctly for withdrawn and private items (ie. don't link)
  502 + else if (field.equals(titleField) && items[i].isWithdrawn())
  503 + {
  504 + //metadata = Utils.addEntities(metadataArray[0].value); //Before
  505 + //IT SAYS DON'T LINK - BUT DO WE LINK?
  506 + metadata = "<a href=\"" + hrq.getContextPath() + "/handle/"
  507 + + items[i].getHandle() + "\">"
  508 + + Utils.addEntities(metadataArray[0].value)
  509 + + "</a>";
  510 +
  511 + }
  512 + // format the title field correctly (as long as the item isn't withdrawn, link to it)
  513 + else if (field.equals(titleField))
  514 + {
  515 + metadata = "<a href=\"" + hrq.getContextPath() + "/handle/"
  516 + + items[i].getHandle() + "\">"
  517 + + Utils.addEntities(metadataArray[0].value)
  518 + + "</a>";
  519 + }
  520 + // format all other fields
  521 + else
  522 + {
  523 + // limit the number of records if this is the author field (if
  524 + // -1, then the limit is the full list)
  525 + boolean truncated = false;
  526 + int loopLimit = metadataArray.length;
  527 + if (isAuthor[colIdx])
  528 + {
  529 + int fieldMax = (authorLimit == -1 ? metadataArray.length : authorLimit);
  530 + loopLimit = (fieldMax > metadataArray.length ? metadataArray.length : fieldMax);
  531 + truncated = (fieldMax < metadataArray.length);
  532 + log.debug("Limiting output of field " + field + " to " + Integer.toString(loopLimit) + " from an original " + Integer.toString(metadataArray.length));
  533 + }
  534 +
  535 + StringBuffer sb = new StringBuffer();
  536 + for (int j = 0; j < loopLimit; j++)
  537 + {
  538 + String startLink = "";
  539 + String endLink = "";
  540 + if (!StringUtils.isEmpty(browseType[colIdx]) && !disableCrossLinks)
  541 + {
  542 + String argument;
  543 + String value;
  544 + if (metadataArray[j].authority != null &&
  545 + metadataArray[j].confidence >= MetadataAuthorityManager.getManager()
  546 + .getMinConfidence(metadataArray[j].schema, metadataArray[j].element, metadataArray[j].qualifier))
  547 + {
  548 + argument = "authority";
  549 + value = metadataArray[j].authority;
  550 + }
  551 + else
  552 + {
  553 + argument = "value";
  554 + value = metadataArray[j].value;
  555 + }
  556 + if (viewFull[colIdx])
  557 + {
  558 + argument = "vfocus";
  559 + }
  560 + startLink = "<a href=\"" + hrq.getContextPath() + "/browse?type=" + browseType[colIdx] + "&amp;" +
  561 + argument + "=" + URLEncoder.encode(value,"UTF-8");
  562 +
  563 + if (metadataArray[j].language != null)
  564 + {
  565 + startLink = startLink + "&amp;" +
  566 + argument + "_lang=" + URLEncoder.encode(metadataArray[j].language, "UTF-8");
  567 + }
  568 +
  569 + if ("authority".equals(argument))
  570 + {
  571 + startLink += "\" class=\"authority " +browseType[colIdx] + "\">";
  572 + }
  573 + else
  574 + {
  575 + startLink = startLink + "\">";
  576 + }
  577 + endLink = "</a>";
  578 + if (browseType[colIdx].equals("author")
  579 + && ConfigurationManager
  580 + .getBooleanProperty("stats.reports.author.fulllist")) {
  581 + endLink += ReportLinkManager.generateLink(
  582 + pageContext, hrq, value);
  583 + }
  584 + }
  585 + sb.append(startLink);
  586 + sb.append(Utils.addEntities(metadataArray[j].value));
  587 + sb.append(endLink);
  588 + if (j < (loopLimit - 1))
  589 + {
  590 + sb.append("; ");
  591 + }
  592 + }
  593 + if (truncated)
  594 + {
  595 + String etal = LocaleSupport.getLocalizedMessage(pageContext, "itemlist.et-al");
  596 + sb.append(", ").append(etal);
  597 + }
  598 + metadata = "<em>" + sb.toString() + "</em>";
  599 + }
  600 + }
  601 + //In case title has no value, replace it with "undefined" so as the user has something to
  602 + //click in order to access the item page
  603 + else if (field.equals(titleField)){
  604 + String undefined = LocaleSupport.getLocalizedMessage(pageContext, "itemlist.title.undefined");
  605 + if (items[i].isWithdrawn())
  606 + {
  607 + metadata = "<span style=\"font-style:italic\">("+undefined+")</span>";
  608 +
  609 + }
  610 + // format the title field correctly (as long as the item isn't withdrawn, link to it)
  611 + else
  612 + {
  613 + metadata = "<a href=\"" + hrq.getContextPath() + "/handle/"
  614 + + items[i].getHandle() + "\">"
  615 + + "<span style=\"font-style:italic\">("+undefined+")</span>"
  616 + + "</a>";
  617 + }
  618 + }
  619 +
  620 + // prepare extra special layout requirements for dates
  621 + String extras = "";
  622 + if (isDate[colIdx])
  623 + {
  624 + extras = "nowrap=\"nowrap\" align=\"right\"";
  625 + }
  626 +
  627 + String markClass = "";
  628 + if (field.startsWith("mark_"))
  629 + {
  630 + markClass = " "+field+"_tr";
  631 + }
  632 +
  633 + String id = "t" + Integer.toString(colIdx + 1);
  634 + out.print("<td headers=\"" + id + "\" class=\""
  635 + + rOddOrEven + "Row" + cOddOrEven[colIdx] + "Col" + markClass + "\" " + extras + ">"
  636 + + (emph[colIdx] ? "<strong>" : "") + metadata + (emph[colIdx] ? "</strong>" : "")
  637 + + "</td>");
  638 + }
  639 +
  640 + // Add column for 'edit item' links
  641 + if (linkToEdit)
  642 + {
  643 + String id = "t" + Integer.toString(cOddOrEven.length + 1);
  644 +
  645 + out.print("<td headers=\"" + id + "\" class=\""
  646 + + rOddOrEven + "Row" + cOddOrEven[cOddOrEven.length - 2] + "Col\" nowrap>"
  647 + + "<form method=\"get\" action=\"" + hrq.getContextPath() + "/tools/edit-item\">"
  648 + + "<input type=\"hidden\" name=\"handle\" value=\"" + items[i].getHandle() + "\" />"
  649 + + "<input type=\"submit\" value=\"Edit Item\" /></form>"
  650 + + "</td>");
  651 + }
  652 +
  653 + out.println("</tr>");
  654 + }
  655 +
  656 + // close the table
  657 + out.println("</table>");
  658 + }
  659 + catch (IOException ie)
  660 + {
  661 + throw new JspException(ie);
  662 + } catch (BrowseException e)
  663 + {
  664 + throw new JspException(e);
  665 + }
  666 +
  667 + return SKIP_BODY;
  668 + }
  669 +
  670 + public BrowseInfo getBrowseInfo()
  671 + {
  672 + return browseInfo;
  673 + }
  674 +
  675 + public void setBrowseInfo(BrowseInfo browseInfo)
  676 + {
  677 + this.browseInfo = browseInfo;
  678 + setItems(browseInfo.getBrowseItemResults());
  679 + authorLimit = browseInfo.getEtAl();
  680 + }
  681 +
  682 + public boolean getLinkToEdit()
  683 + {
  684 + return linkToEdit;
  685 + }
  686 +
  687 + public void setLinkToEdit(boolean edit)
  688 + {
  689 + this.linkToEdit = edit;
  690 + }
  691 +
  692 + public boolean getDisableCrossLinks()
  693 + {
  694 + return disableCrossLinks;
  695 + }
  696 +
  697 + public void setDisableCrossLinks(boolean links)
  698 + {
  699 + this.disableCrossLinks = links;
  700 + }
  701 +
  702 + /**
  703 + * Get the items to list
  704 + *
  705 + * @return the items
  706 + */
  707 + public BrowseItem[] getItems()
  708 + {
  709 + return (BrowseItem[]) ArrayUtils.clone(items);
  710 + }
  711 +
  712 + /**
  713 + * Set the items to list
  714 + *
  715 + * @param itemsIn
  716 + * the items
  717 + */
  718 + public void setItems(BrowseItem[] itemsIn)
  719 + {
  720 + items = (BrowseItem[]) ArrayUtils.clone(itemsIn);
  721 + }
  722 +
  723 + /**
  724 + * Get the row to highlight - null or -1 for no row
  725 + *
  726 + * @return the row to highlight
  727 + */
  728 + public String getHighlightrow()
  729 + {
  730 + return String.valueOf(highlightRow);
  731 + }
  732 +
  733 + /**
  734 + * Set the row to highlight
  735 + *
  736 + * @param highlightRowIn
  737 + * the row to highlight or -1 for no highlight
  738 + */
  739 + public void setHighlightrow(String highlightRowIn)
  740 + {
  741 + if ((highlightRowIn == null) || highlightRowIn.equals(""))
  742 + {
  743 + highlightRow = -1;
  744 + }
  745 + else
  746 + {
  747 + try
  748 + {
  749 + highlightRow = Integer.parseInt(highlightRowIn);
  750 + }
  751 + catch (NumberFormatException nfe)
  752 + {
  753 + highlightRow = -1;
  754 + }
  755 + }
  756 + }
  757 +
  758 + /**
  759 + * Get the column to emphasise - "title", "date" or null
  760 + *
  761 + * @return the column to emphasise
  762 + */
  763 + public String getEmphcolumn()
  764 + {
  765 + return emphColumn;
  766 + }
  767 +
  768 + /**
  769 + * Set the column to emphasise - "title", "date" or null
  770 + *
  771 + * @param emphColumnIn
  772 + * column to emphasise
  773 + */
  774 + public void setEmphcolumn(String emphColumnIn)
  775 + {
  776 + emphColumn = emphColumnIn;
  777 + }
  778 +
  779 + public void release()
  780 + {
  781 + highlightRow = -1;
  782 + emphColumn = null;
  783 + items = null;
  784 + }
  785 +
  786 + /* get the required thumbnail config items */
  787 + private static void getThumbSettings()
  788 + {
  789 + showThumbs = ConfigurationManager
  790 + .getBooleanProperty("webui.browse.thumbnail.show");
  791 +
  792 + if (showThumbs)
  793 + {
  794 + thumbItemListMaxHeight = ConfigurationManager
  795 + .getIntProperty("webui.browse.thumbnail.maxheight");
  796 +
  797 + if (thumbItemListMaxHeight == 0)
  798 + {
  799 + thumbItemListMaxHeight = ConfigurationManager
  800 + .getIntProperty("thumbnail.maxheight");
  801 + }
  802 +
  803 + thumbItemListMaxWidth = ConfigurationManager
  804 + .getIntProperty("webui.browse.thumbnail.maxwidth");
  805 +
  806 + if (thumbItemListMaxWidth == 0)
  807 + {
  808 + thumbItemListMaxWidth = ConfigurationManager
  809 + .getIntProperty("thumbnail.maxwidth");
  810 + }
  811 + }
  812 +
  813 + String linkBehaviour = ConfigurationManager
  814 + .getProperty("webui.browse.thumbnail.linkbehaviour");
  815 +
  816 + if (linkBehaviour != null && linkBehaviour.equals("bitstream"))
  817 + {
  818 + linkToBitstream = true;
  819 + }
  820 + }
  821 +
  822 + /*
  823 + * Get the (X)HTML width and height attributes. As the browser is being used
  824 + * for scaling, we only scale down otherwise we'll get hideously chunky
  825 + * images. This means the media filter should be run with the maxheight and
  826 + * maxwidth set greater than or equal to the size of the images required in
  827 + * the search/browse
  828 + */
  829 + private String getScalingAttr(HttpServletRequest hrq, Bitstream bitstream)
  830 + throws JspException
  831 + {
  832 + BufferedImage buf;
  833 +
  834 + try
  835 + {
  836 + Context c = UIUtil.obtainContext(hrq);
  837 +
  838 + InputStream is = BitstreamStorageManager.retrieve(c, bitstream
  839 + .getID());
  840 +
  841 + //AuthorizeManager.authorizeAction(bContext, this, Constants.READ);
  842 + // read in bitstream's image
  843 + buf = ImageIO.read(is);
  844 + is.close();
  845 + }
  846 + catch (SQLException sqle)
  847 + {
  848 + throw new JspException(sqle.getMessage(), sqle);
  849 + }
  850 + catch (IOException ioe)
  851 + {
  852 + throw new JspException(ioe.getMessage(), ioe);
  853 + }
  854 +
  855 + // now get the image dimensions
  856 + float xsize = (float) buf.getWidth(null);
  857 + float ysize = (float) buf.getHeight(null);
  858 +
  859 + // scale by x first if needed
  860 + if (xsize > (float) thumbItemListMaxWidth)
  861 + {
  862 + // calculate scaling factor so that xsize * scale = new size (max)
  863 + float scaleFactor = (float) thumbItemListMaxWidth / xsize;
  864 +
  865 + // now reduce x size and y size
  866 + xsize = xsize * scaleFactor;
  867 + ysize = ysize * scaleFactor;
  868 + }
  869 +
  870 + // scale by y if needed
  871 + if (ysize > (float) thumbItemListMaxHeight)
  872 + {
  873 + float scaleFactor = (float) thumbItemListMaxHeight / ysize;
  874 +
  875 + // now reduce x size
  876 + // and y size
  877 + xsize = xsize * scaleFactor;
  878 + ysize = ysize * scaleFactor;
  879 + }
  880 +
  881 + StringBuffer sb = new StringBuffer("width=\"").append(xsize).append(
  882 + "\" height=\"").append(ysize).append("\"");
  883 +
  884 + return sb.toString();
  885 + }
  886 +
  887 + /* generate the (X)HTML required to show the thumbnail */
  888 + private String getThumbMarkup(HttpServletRequest hrq, BrowseItem item)
  889 + throws JspException
  890 + {
  891 + try
  892 + {
  893 + Context c = UIUtil.obtainContext(hrq);
  894 + Thumbnail thumbnail = ItemService.getThumbnail(c, item.getID(), linkToBitstream);
  895 +
  896 + if (thumbnail == null)
  897 + {
  898 + return "";
  899 + }
  900 + StringBuffer thumbFrag = new StringBuffer();
  901 +
  902 + if (linkToBitstream)
  903 + {
  904 + Bitstream original = thumbnail.getOriginal();
  905 + String link = hrq.getContextPath() + "/bitstream/" + item.getHandle() + "/" + original.getSequenceID() + "/" +
  906 + UIUtil.encodeBitstreamName(original.getName(), Constants.DEFAULT_ENCODING);
  907 + thumbFrag.append("<a target=\"_blank\" href=\"" + link + "\" />");
  908 + }
  909 + else
  910 + {
  911 + String link = hrq.getContextPath() + "/handle/" + item.getHandle();
  912 + thumbFrag.append("<a href=\"" + link + "\" />");
  913 + }
  914 +
  915 + Bitstream thumb = thumbnail.getThumb();
  916 + String img = hrq.getContextPath() + "/retrieve/" + thumb.getID() + "/" +
  917 + UIUtil.encodeBitstreamName(thumb.getName(), Constants.DEFAULT_ENCODING);
  918 + String alt = thumb.getName();
  919 + String scAttr = getScalingAttr(hrq, thumb);
  920 + thumbFrag.append("<img src=\"")
  921 + .append(img)
  922 + .append("\" alt=\"").append(alt).append("\" ")
  923 + .append(scAttr)
  924 + .append("/ border=\"0\"></a>");
  925 +
  926 + return thumbFrag.toString();
  927 + }
  928 + catch (SQLException sqle)
  929 + {
  930 + throw new JspException(sqle.getMessage(), sqle);
  931 + }
  932 + catch (UnsupportedEncodingException e)
  933 + {
  934 + throw new JspException("Server does not support DSpace's default encoding. ", e);
  935 + }
  936 + }
  937 +}
... ...