001: /*
002: * ControlledVocabularyTag.java
003: *
004: * Version: $Revision: 1414 $
005: *
006: * Date: $Date: 2006-02-08 08:41:08 -0600 (Wed, 08 Feb 2006) $
007: *
008: * Copyright (c) 2002, Hewlett-Packard Company and Massachusetts Institute of
009: * Technology. All rights reserved.
010: *
011: * Redistribution and use in source and binary forms, with or without
012: * modification, are permitted provided that the following conditions are met: -
013: * Redistributions of source code must retain the above copyright notice, this
014: * list of conditions and the following disclaimer. - Redistributions in binary
015: * form must reproduce the above copyright notice, this list of conditions and
016: * the following disclaimer in the documentation and/or other materials provided
017: * with the distribution. - Neither the name of the Hewlett-Packard Company nor
018: * the name of the Massachusetts Institute of Technology nor the names of their
019: * contributors may be used to endorse or promote products derived from this
020: * software without specific prior written permission.
021: *
022: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
023: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
024: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
025: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
026: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
027: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
028: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
029: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
030: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
031: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
032: * POSSIBILITY OF SUCH DAMAGE.
033: */
034: package org.dspace.app.webui.jsptag;
035:
036: import java.io.File;
037: import java.io.FilenameFilter;
038: import java.util.Enumeration;
039: import java.util.Hashtable;
040: import java.util.Iterator;
041:
042: import javax.servlet.http.HttpServletRequest;
043: import javax.servlet.jsp.JspException;
044: import javax.servlet.jsp.tagext.TagSupport;
045:
046: import org.apache.log4j.Logger;
047: import org.dspace.app.webui.util.XMLUtil;
048: import org.dspace.core.ConfigurationManager;
049: import org.w3c.dom.Document;
050:
051: /**
052: * A Tag to load and display controlled vocabularies
053: *
054: * @author Miguel Ferreira
055: * @version $Revision: 1414 $
056: *
057: */
058: public class ControlledVocabularyTag extends TagSupport {
059: // path to the jsp that outputs the results of this tag
060: private static final String CONTROLLEDVOCABULARY_JSPTAG = "/controlledvocabulary/controlledvocabularyTag.jsp";
061:
062: // the log
063: private static Logger log = Logger
064: .getLogger(ControlledVocabularyTag.class);
065:
066: // a tag attribute that contains the words used to trim the vocabulary tree
067: private String filter;
068:
069: // a tag attribute that activates multiple selection of vocabulary terms
070: private boolean allowMultipleSelection;
071:
072: // a tag attribute that specifies the vocabulary to be displayed
073: private String vocabulary;
074:
075: // an hashtable containing all the loaded vocabularies
076: public Hashtable controlledVocabularies;
077:
078: /**
079: * Process tag
080: */
081: public int doStartTag() throws JspException {
082: HttpServletRequest request = (HttpServletRequest) pageContext
083: .getRequest();
084:
085: String vocabulariesPath = ConfigurationManager
086: .getProperty("dspace.dir")
087: + "/config/controlled-vocabularies/";
088: String addonBaseDirectory = pageContext.getServletContext()
089: .getRealPath("")
090: + "/controlledvocabulary/";
091: String vocabularyPrunningXSLT = addonBaseDirectory
092: + "vocabularyprune.xsl";
093: String controlledVocabulary2HtmlXSLT = addonBaseDirectory
094: + "vocabulary2html.xsl";
095:
096: // Load vocabularies on startup
097: controlledVocabularies = (Hashtable) pageContext
098: .getServletContext().getAttribute(
099: "controlledvocabulary.controlledVocabularies");
100: if (controlledVocabularies == null) {
101: controlledVocabularies = loadControlledVocabularies(vocabulariesPath);
102: pageContext.getServletContext().setAttribute(
103: "controlledvocabulary.controlledVocabularies",
104: controlledVocabularies);
105: }
106:
107: try {
108: Hashtable prunnedVocabularies = needsFiltering() ? filterVocabularies(
109: controlledVocabularies, vocabularyPrunningXSLT)
110: : controlledVocabularies;
111:
112: String html = "";
113: if (vocabulary != null && !vocabulary.equals("")) {
114: html = renderVocabularyAsHTML(
115: (Document) prunnedVocabularies.get(vocabulary
116: + ".xml"),
117: controlledVocabulary2HtmlXSLT,
118: isAllowMultipleSelection(), request
119: .getContextPath());
120: } else {
121: html = renderVocabulariesAsHTML(prunnedVocabularies,
122: controlledVocabulary2HtmlXSLT,
123: isAllowMultipleSelection(), request
124: .getContextPath());
125: }
126: request.getSession().setAttribute(
127: "controlledvocabulary.vocabularyHTML", html);
128:
129: pageContext.include(CONTROLLEDVOCABULARY_JSPTAG);
130:
131: } catch (Exception e) {
132: log.warn("Exception", e);
133: }
134:
135: return SKIP_BODY;
136: }
137:
138: /**
139: * End processing tag
140: */
141: public int doEndTag() {
142: return EVAL_PAGE;
143: }
144:
145: /**
146: * Do we gave a filter to apply to the controlled vocabularies?
147: *
148: * @return true if a filter was provided.
149: */
150: private boolean needsFiltering() {
151: return getFilter() != null && getFilter().length() > 0;
152: }
153:
154: /**
155: * Converts a XML Vocabulary to a HTML tree
156: *
157: * @param vocabularies
158: * A hashtable with all the XML taxonomies/vocabularies loaded as
159: * values
160: * @param xslt
161: * the filename of the stylesheet to apply the XML taxonomies
162: * @param allowMultipleSelection
163: * include checkboxes next to the taxonomy terms
164: * @param contextPath
165: * The context path
166: * @return the HTML that represents the vocabularies
167: */
168: private String renderVocabulariesAsHTML(Hashtable vocabularies,
169: String xslt, boolean allowMultipleSelection,
170: String contextPath) {
171: String result = "";
172: Iterator iter = vocabularies.values().iterator();
173: while (iter.hasNext()) {
174: Document controlledVocabularyXML = (Document) iter.next();
175: result += renderVocabularyAsHTML(controlledVocabularyXML,
176: xslt, allowMultipleSelection, contextPath);
177: }
178: return result;
179: }
180:
181: /**
182: * Applies a filter to the vocabularies, i.e. it prunes the trees by
183: * removing all the branches that do not contain the words in the filter.
184: *
185: * @param vocabularies
186: * A hashtable with all the XML taxonomies/vocabularies loaded as
187: * values
188: * @param vocabularyPrunningXSLT
189: * the filename of the stylesheet that trimms the taxonomies
190: * @return An hashtable with all the filtered vocabularies
191: */
192: private Hashtable filterVocabularies(Hashtable vocabularies,
193: String vocabularyPrunningXSLT) {
194: Hashtable prunnedVocabularies = new Hashtable();
195: Enumeration enumeration = vocabularies.keys();
196: while (enumeration.hasMoreElements()) {
197: String controlledVocabularyKey = (String) enumeration
198: .nextElement();
199: Document controlledVocabulary = (Document) vocabularies
200: .get(controlledVocabularyKey);
201: prunnedVocabularies.put(controlledVocabularyKey,
202: filterVocabulary(controlledVocabulary,
203: vocabularyPrunningXSLT, getFilter()));
204: }
205: return prunnedVocabularies;
206: }
207:
208: /**
209: * Renders a taxonomy as HTML by applying a stylesheet.
210: *
211: * @param vocabulary
212: * The XML document representing a taxonomy
213: * @param controlledVocabulary2HtmlXSLT
214: * The filename of the stylesheet that converts the taxonomy to
215: * HTML
216: * @param allowMultipleSelection
217: * include checkboxes next to the taxonomy terms
218: * @param contextPath
219: * The context path
220: * @return the provided taxonomy as HTML.
221: */
222: public String renderVocabularyAsHTML(Document vocabulary,
223: String controlledVocabulary2HtmlXSLT,
224: boolean allowMultipleSelection, String contextPath) {
225: if (vocabulary == null)
226: return "";
227:
228: String result = "";
229: try {
230:
231: Hashtable parameters = new Hashtable();
232: parameters.put("allowMultipleSelection",
233: allowMultipleSelection ? "yes" : "no");
234: parameters.put("contextPath", contextPath);
235: result = XMLUtil.transformDocumentAsString(vocabulary,
236: parameters, controlledVocabulary2HtmlXSLT);
237: } catch (Exception e) {
238: e.printStackTrace();
239: }
240: return result;
241: }
242:
243: /**
244: * Applies a filter to the provided vocabulary, i.e. it prunes the tree by
245: * removing all the branches that do not contain the words in the filter.
246: *
247: * @param vocabulary
248: * The vocabulary to be trimmed
249: * @param vocabularyPrunningXSLT
250: * The filename of the stylesheet that trims the vocabulary
251: * @param filter
252: * The filter to be applied
253: * @return The trimmed vocabulary.
254: */
255: public Document filterVocabulary(Document vocabulary,
256: String vocabularyPrunningXSLT, String filter) {
257: if (vocabulary == null)
258: return null;
259:
260: try {
261: Hashtable parameters = new Hashtable();
262: parameters.put("filter", filter);
263: Document prunnedVocabulary = XMLUtil.transformDocument(
264: vocabulary, parameters, vocabularyPrunningXSLT);
265: return prunnedVocabulary;
266: } catch (Exception e) {
267: e.printStackTrace();
268: return null;
269: }
270:
271: }
272:
273: /**
274: * Loads into memory all the vocabularies found in the given directory. All
275: * files with .xml extension are considered to be controlled vocabularies.
276: *
277: * @param directory
278: * where the files are positioned
279: * @return an hashtable with the filenames of the vocabularies as keys and
280: * the XML documents representing the vocabularies as values.
281: */
282: private static Hashtable loadControlledVocabularies(String directory) {
283: Hashtable controlledVocabularies = new Hashtable();
284: File dir = new File(directory);
285:
286: FilenameFilter filter = new FilenameFilter() {
287: public boolean accept(File dir, String name) {
288: return name.endsWith(".xml");
289: }
290: };
291: String[] children = dir.list(filter);
292:
293: if (children != null && children.length > 0) {
294: for (int i = 0; i < children.length; i++) {
295: String filename = children[i];
296:
297: try {
298: Document controlledVocabulary = XMLUtil
299: .loadXML(directory + filename);
300: controlledVocabularies.put(filename,
301: controlledVocabulary);
302: log.warn("Loaded vocabulary: " + filename);
303: } catch (Exception e) {
304: log.warn("Failed to load vocabulary from "
305: + filename, e);
306: }
307: }
308: } else {
309: log.warn("Could not find any vocabularies...");
310: }
311: return controlledVocabularies;
312:
313: }
314:
315: /**
316: * Gets the filter provided as parameter to the tag
317: *
318: * @return the filter
319: */
320: public String getFilter() {
321: return filter;
322: }
323:
324: /**
325: * Sets the filter
326: *
327: * @param filter
328: * the filter
329: */
330: public void setFilter(String filter) {
331: this .filter = filter;
332: }
333:
334: /**
335: * Returns the value of the multiple selection parameter
336: *
337: * @return true if the multiple selection was selected
338: */
339: public boolean isAllowMultipleSelection() {
340: return allowMultipleSelection;
341: }
342:
343: /**
344: * Defines if we want to be able to select multiple terms of the taxonomy
345: *
346: * @param allowMultipleSelection
347: * true if we want to be able to select more than on term
348: */
349: public void setAllowMultipleSelection(boolean allowMultipleSelection) {
350: this .allowMultipleSelection = allowMultipleSelection;
351: }
352:
353: /**
354: * Gets the name of the vocabulary to be displayed
355: *
356: * @return the name of the vocabulary
357: */
358: public String getVocabulary() {
359: return vocabulary;
360: }
361:
362: /**
363: * Sets the name of the vocabulary to be displayed. If no name is provided,
364: * all vocabularies loaded will be rendered to the output
365: *
366: * @param vocabulary
367: * the name of the vocabulary to be selected
368: */
369: public void setVocabulary(String vocabulary) {
370: this.vocabulary = vocabulary;
371: }
372:
373: }
|