source: other-projects/trunk/gs3-webservices-democlient/src/GS3DemoClient/org/greenstone/gs3client/BrowseDisplay.java@ 15661

Last change on this file since 15661 was 15661, checked in by ak19, 16 years ago

displayBrowseResults() does mode.setRoot(newRoot) at the end of the for loop instead of throughout

File size: 24.8 KB
Line 
1/**
2 *#########################################################################
3 * BrowseDisplay.java - part of the demo-client for Greenstone 3, of the
4 * Greenstone digital library suite from the New Zealand Digital Library
5 * Project at the * University of Waikato, New Zealand.
6 * <BR><BR>
7 * Copyright (C) 2008 New Zealand Digital Library Project
8 * <BR><BR>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 * <BR><BR>
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *########################################################################
19 */
20package org.greenstone.gs3client;
21
22import javax.swing.JPopupMenu;
23import javax.swing.JList;
24import javax.swing.JPanel;
25import javax.swing.JScrollPane;
26import javax.swing.JEditorPane;
27import javax.swing.BorderFactory;
28import javax.swing.JButton;
29import javax.swing.JSplitPane;
30import javax.swing.JLabel;
31
32import java.awt.event.ActionListener;
33import java.awt.event.ActionEvent;
34
35import java.awt.Component;
36import java.awt.Container;
37import java.awt.Cursor;
38import java.awt.Dimension;
39import java.awt.BorderLayout;
40
41import org.w3c.dom.Element;
42import org.w3c.dom.NodeList;
43
44import java.net.MalformedURLException;
45import java.net.URL;
46import java.util.Vector;
47import java.util.HashMap;
48
49import javax.swing.JTree;
50import javax.swing.text.html.HTMLDocument;
51import javax.swing.tree.DefaultMutableTreeNode;
52import javax.swing.tree.TreeSelectionModel;
53import javax.swing.tree.DefaultTreeModel;
54import javax.swing.event.TreeWillExpandListener;
55import javax.swing.event.TreeExpansionEvent;
56import javax.swing.event.TreeSelectionEvent;
57import javax.swing.event.TreeSelectionListener;
58
59import org.apache.log4j.Logger;
60import org.greenstone.gs3client.data.BrowseResponseData;
61import org.greenstone.gs3client.data.DocumentNodeData;
62import org.greenstone.gs3client.data.ClassifierNodeData;
63import org.greenstone.gs3client.data.NodeData;
64import org.greenstone.gs3client.data.ParseUtil;
65import org.greenstone.gsdl3.util.GSXML;
66
67/**
68 * The Browse panel inside the Java-client's tab pane that's labelled "Browse".
69 * This panel contains a tree view for expanding classifiers and their documents.
70 * It also contains an area where the metadata is displayed, and a text area where
71 * the textual or image content of a selected documentNode is displayed.
72 * @author ak19
73*/
74public class BrowseDisplay extends JPanel
75 implements TreeSelectionListener, TreeWillExpandListener,
76 ColourCombo.ColourChangeable
77{
78 /** The Logger for this class */
79 static Logger LOG = Logger.getLogger(SearchResultsDisplay.class);
80
81 /** Access to the running instance of GS3JavaClient */
82 protected GS3JavaClient client;
83 /** A HashMap to store the displayData for the Browse operation. Usually
84 * just 2 elements long at most: displayName and displayDescription. */
85 protected HashMap displayData;
86
87 /* GUI items of this Browse Panel */
88 protected JLabel browseLabel;
89 protected JPanel browsePanel;
90 protected JSplitPane splitViewPane, structureMetaView;
91 protected JPanel browseBar;
92 protected ClassifierButton[] classifierList;
93 protected JTree browsingTree;
94 protected JEditorPane htmlPane;
95 protected JList metanames, metavalues;
96 /** Context menu that pops up when users right click in the browse tree area */
97 protected JPopupMenu popup;
98
99 /** Constructor that creates the Browse Panel and its internal GUI items.
100 * @param client is the running instance of the client application through
101 * which its methods can be accessed. */
102 public BrowseDisplay(GS3JavaClient client) {
103 super(new BorderLayout());
104 this.client = client;
105 displayData = new HashMap(2); //usual maxsize
106
107 browseBar = new JPanel(); // default FlowLayout L to R, centre aligned
108 classifierList = null;
109 this.add(browseBar, BorderLayout.NORTH);
110
111 browsingTree = new JTree(new DefaultMutableTreeNode(null));
112 browsingTree.getSelectionModel().setSelectionMode(
113 TreeSelectionModel.SINGLE_TREE_SELECTION);
114 browsingTree.addTreeSelectionListener(this);
115 browsingTree.addTreeWillExpandListener(this);
116
117 browsePanel = new JPanel(new BorderLayout());
118 // new FlowLayout(FlowLayout.LEFT)); // don't use this,
119 // else view of tree is limited to the very minimum
120 browsePanel.add(new JScrollPane(browsingTree), BorderLayout.CENTER);
121 browseLabel = new JLabel("Browsing by...");
122 browsePanel.add(browseLabel, BorderLayout.NORTH);
123
124 JPanel metadataPanel = new JPanel(new BorderLayout());
125 this.metanames = new JList();
126 this.metavalues = new JList();
127 metadataPanel.add(metanames, BorderLayout.WEST);
128 metadataPanel.add(metavalues, BorderLayout.CENTER);
129
130 JPanel metaSuperPanel = new JPanel(new BorderLayout());
131 metaSuperPanel.add(new JLabel("Metadata"), BorderLayout.NORTH);
132 //metaSuperPanel.add(metadataPanel, BorderLayout.CENTER);
133 metaSuperPanel.add(
134 new JScrollPane(metadataPanel), BorderLayout.CENTER);
135
136 structureMetaView = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
137 structureMetaView.setTopComponent(browsePanel);
138 structureMetaView.setBottomComponent(new JScrollPane(metaSuperPanel));
139 structureMetaView.setOneTouchExpandable(true);
140
141 htmlPane = new JEditorPane();
142 htmlPane.setEditable(false);
143 htmlPane.setContentType("text/html");
144
145 // Add the docStructure and metadata panels next to each
146 // other within a split pane
147 splitViewPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
148 splitViewPane.setLeftComponent(structureMetaView);
149 splitViewPane.setRightComponent(new JScrollPane(htmlPane));
150 splitViewPane.setOneTouchExpandable(true);
151
152 this.add(splitViewPane, BorderLayout.CENTER);
153
154
155 // add a (rightclick) popup menu to the browsing tree
156 // (can only do this after tree and htmlPane have been instantiated):
157 popup = new JPopupMenu();
158 browsingTree.setComponentPopupMenu(popup);
159 browsingTree.addMouseListener(new Displays.PopupListener(
160 popup, browsingTree, client, this.htmlPane));
161 }
162
163 /** Clears the service-specific buttons in the browseBar and the
164 * service-specific display-data. The rest of the GUI (split panes, panels)
165 * remain as they are. */
166 public void clear() {
167 // empty the docStructureTree's popup menu too
168 popup.removeAll();
169
170 browseBar.removeAll();
171 displayData.clear();
172
173 htmlPane.setText("");
174 // empty any classification/document metadata
175 final String[] empty = {};
176 BrowseDisplay.this.metanames.setListData(empty);
177 BrowseDisplay.this.metavalues.setListData(empty);
178 //metanames.removeAll(); // doesn't work
179 //metavalues.removeAll(); // doesn't work
180
181 // empty the tree:
182 ((DefaultTreeModel)browsingTree.getModel()).setRoot(null);
183
184 classifierList = null;
185 System.gc();
186
187 this.validate();
188 }
189
190 /** Changes the colour of the query form and its controls to the
191 * current colours set in class ColourCombo. Specified by
192 * the ColourCombo.ColourChangeable interface. */
193 public void changeUIColour() {
194 Component[] comps = { this, this.browseBar, this.browsePanel,
195 browsingTree, metanames, metavalues, popup };
196 ColourCombo.changeColor(comps);
197 // ensures that the "metadata" JLabel (not an instance variable)
198 // is coloured appropriately as well
199 ColourCombo.changeAncestorColor(metanames);
200
201 }
202
203 /** For some reason, the overriden getPreferredSize() is not
204 * called upon resize of this panel, so I am calling it manually
205 * whenever there's a call to paint this Panel. Painting will
206 * be done when the parent container is resized (and this panel
207 * made visible) anyway, so it might as well work out what size
208 * the interior panels will have on every resize.
209 * @param g is the Graphics object
210 * @see "JPanel's paint(Graphics g)"
211 */
212 public void paint(java.awt.Graphics g) {
213 super.paint(g); // let the usual JPanel paint event happen
214 this.getPreferredSize();
215 }
216
217 // FIX ME: The following problem was 'fixed' by overriding paint:
218 // Strangely, this method is called only once! Even though it should
219 // always be called on resize as indeed happens correctly in
220 // SearchResultsDisplay.java.
221 // Reason might be because components are arranged differently in the
222 // JSplitPanes nested in this JPanel (they're arranged different from
223 // SearchResultsDisplay.java)
224 /** Overrode this method to resize the splitpanes within, upon resize.
225 * It calculates the size of this panel, as well as setting those of
226 * the splitpanes it contains based on the size of the parent container.
227 * @return the preferred dimensions of this JPanel. */
228 public Dimension getPreferredSize() {
229 Dimension size = this.getParent().getSize();
230 int x = (int)size.getWidth() / 3; // WHY DOES THIS NOT WORK?????
231 int y = (int)(size.getHeight() / 5 * 3); // WHY DOES THIS NOT WORK?????
232 structureMetaView.setDividerLocation(y); // 400
233 // structureMetaView.setDividerLocation(1.0); // as far down as
234 // possible to give more space to browse structure and less to meta
235 splitViewPane.setDividerLocation(x); // 300
236 splitViewPane.setPreferredSize(size);
237 //System.err.println("SIZE: " + this.getSize() + "y: " + y);
238 return size;
239 }
240
241 /** Will clear previous browse service's classification options and widgets,
242 * and redisplay browse options as specified by the describe Response Message
243 * XML returned from the browse Service.
244 * @param describeRespMsgTag - the (Classifier)Browse Service's describe
245 * response message element, used to reset the classifier buttons in the
246 * browseBar of this panel. */
247 public void displayBrowseOptions(Element describeRespMsgTag){
248 this.clear();
249 // First set the displayItems
250 Element service = ParseUtil.getFirstDescElementCalled(
251 describeRespMsgTag, GSXML.SERVICE_ELEM);
252
253 Vector displayItems = ParseUtil.getAllChildElementsCalled(
254 service, GSXML.DISPLAY_TEXT_ELEM);
255 if(displayItems != null) {
256 for(int i = 0; i < displayItems.size(); i++) {
257 Element e = (Element)displayItems.get(i);
258 if(!e.hasAttribute(GSXML.NAME_ATT))
259 continue;
260 // we are looking for <displayItem name="">value</displayItem>
261 String name = e.getAttribute(GSXML.NAME_ATT);
262 String value = ParseUtil.getBodyTextValue(e);
263 this.displayData.put(name, value);
264 }
265
266 // get <displayItem name="description">descr</displayItem>
267 String descr = (String)displayData.get(
268 GSXML.DISPLAY_TEXT_DESCRIPTION);
269 if(descr != null)
270 this.setBorder(BorderFactory.createTitledBorder(descr));
271 }
272
273 // Now, process all <classifier> items inside <classifierList>
274 NodeList nl = describeRespMsgTag.getElementsByTagName(
275 GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
276 // There will be only one, as far as I can tell from the describe
277 // response returned from gs2mgppdemo's ClassifierBrowse service
278 if(nl.getLength() <= 0)
279 return; // nothing to do; but this should not happen
280 Element classifierListTag = (Element)nl.item(0);
281
282 // now get the <classifier>s children from <classifierList>
283 nl = classifierListTag.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
284 int size = nl.getLength();
285 if(size > 0)
286 classifierList = new ClassifierButton[size];
287
288 for(int i = 0; i < size; i++) {
289 Element classifier = (Element)nl.item(i);
290 classifierList[i] = new ClassifierButton(
291 new ClassifierData(classifier));
292 this.browseBar.add(classifierList[i]);
293 }
294 }
295
296 /** Called to populate the browsing tree with browse data. Only the
297 * data for the top-level classifier and its direct descendants are
298 * retrieved.
299 * @param browseResponseObj - stores the data of the response XML
300 * message returned by the (Classifier)Browse service.
301 * @param rootName - the title/name of the root classifier */
302 public void displayBrowseResults(
303 BrowseResponseData browseResponseObj, String rootName)
304 {
305 browsingTree.removeAll();
306 DefaultTreeModel model = (DefaultTreeModel)browsingTree.getModel();
307
308 ClassifierNodeData rootClassNode
309 = browseResponseObj.getRootClassifier();
310 rootClassNode.setTitle(rootName);
311 DefaultMutableTreeNode newRoot
312 = new DefaultMutableTreeNode(rootClassNode);
313
314 NodeData[] childNodes = rootClassNode.getChildren();
315 // First set their titles:
316 client.retrieveTitledStructureFor(rootClassNode);
317
318 if(childNodes != null) {
319 for(int i = 0; i < childNodes.length; i++) {
320 DefaultMutableTreeNode child
321 = new DefaultMutableTreeNode(childNodes[i]);
322 newRoot.add(child);
323 if(childNodes[i].hasChildren)
324 child.add(new DefaultMutableTreeNode(null));
325 //browsingTree.setRootVisible(false); //No, because it
326 // has a root: the root classifierNode
327 }
328 model.setRoot(newRoot);
329 }
330 }
331
332 /** This method of the TreeWillExpandListener interface is called when
333 * the user clicked on an expandable node in the browsingTree.
334 * Since we are loading substructures in the tree lazily (i.e. loading
335 * childnodes lazily) we have dummy/null childTreeNodes that make
336 * expandable parentNodes look like folders (make the parents look
337 * expandable).
338 * Therefore, when the user clicks on an expandable node, we first check
339 * whether we already have loaded the datastructure/subtree or whether
340 * its child is a dummy (null). If a dummy (null child), then we work
341 * out whether it's a classifierNodeData or a documentNodeData that the
342 * expanding treeNode represents. Based on that, we retrieve the sub-
343 * structure for the treeNode that's expanding.
344 */
345 public void treeWillExpand(TreeExpansionEvent e)
346 {
347 DefaultMutableTreeNode node = null;
348
349 // Don't use browsingTree.getLastSelectedPathComponent(). That
350 // method doesn't deal with the case when someone clicked on the
351 // expand/collapse knob next to folders.
352 // Use e.getPath().getLastPathComponent() instead:
353 node = (DefaultMutableTreeNode)e.getPath().getLastPathComponent();
354 if(node == null || node.isLeaf())
355 return; // leafnode, shouldn't happen: we're in Expansion method!
356
357 Object nodeInfo = node.getUserObject();
358
359 // First check whether this expanding/folder node's child contains
360 // a dummy object (null) or is already set:
361 DefaultMutableTreeNode child
362 = (DefaultMutableTreeNode)node.getFirstChild();
363 Object childNodeInfo = child.getUserObject();
364 // if the child is null (therefore not a NodeData object), it was a
365 // dummy we added for delayed lazy-loading - so remove child
366 if(childNodeInfo != null) {
367 return; // we've already retrieved the structure for
368 // this node, don't need to process it any further
369 }
370
371 // Child is null: not a NodeData object, so we change the dummy child.
372 // This is done by populating the node's children with the actual
373 // document node/classifier node structure:
374 node.removeAllChildren(); // first remove the dummy child
375
376 // now, construct the structure of the treenode that's expanding
377 // based on whether it represents a classifierNodeData or
378 // documentNodeData object:
379 NodeData nodeData = (NodeData)nodeInfo;
380 if(nodeData instanceof ClassifierNodeData) {
381 ClassifierNodeData classNode = (ClassifierNodeData)nodeData;
382 this.client.retrieveTitledStructureFor((classNode));
383
384 // The above will have set the expanding classNode's children.
385 // Now, we add a treeNode for each child of classNode -
386 // and for each childclassNode that's expandable, add a dummy
387 // child for them to make them expandable:
388 NodeData[] children = classNode.getChildren();
389 for(int i = 0; i < children.length; i++) {
390 DefaultMutableTreeNode childTreeNode
391 = new DefaultMutableTreeNode(children[i]);
392 node.add(childTreeNode);
393 // If the classifier node has children (expands further), make
394 // it a folder by adding in a null child to allow lazy tree-
395 // expansion as when required
396 if(children[i].hasChildren)
397 childTreeNode.add(new DefaultMutableTreeNode(null));
398 }
399 } else { // if instanceof DocumentNodeData
400 DocumentNodeData docNode = (DocumentNodeData)nodeData;
401 if(docNode.nodeType.equals(GSXML.NODE_TYPE_ROOT)) {
402 this.client.retrieveTitledStructureFor(docNode);
403
404 Displays.createNodesForChildren(docNode, node);
405 } //else { document can't be a leaf node *and* expand at the
406 // same time. So shouldn't ever be here!
407 // After all, this is the method that's called when a node
408 // is expanding, and leaf nodes should not expand.
409 //}
410 }
411 }
412
413 /** Part of the TreeWillExpandListener interface. Nothing to do here. */
414 public void treeWillCollapse(TreeExpansionEvent e) {}
415
416 /* THE FOLLOWING DOES NOT APPLY ANYMORE:
417 * In this method, we are not dealing with expandable nodes
418 * (we check for whether the clicked node is a leaf), but with document-
419 * NodeData objects that are leaves: for these, we display the document. */
420 /**
421 * Whenever an item is clicked in the browsingTree, this method is called.
422 * We display the document associated with a documentNode that is clicked,
423 * or "" for classifierNodes.
424 */
425 public void valueChanged(TreeSelectionEvent e) {
426 // remove any menuItems in the popup from the previously
427 // selected docNode
428 popup.removeAll();
429
430 DefaultMutableTreeNode node = null;
431 node = (DefaultMutableTreeNode)
432 browsingTree.getLastSelectedPathComponent();
433
434 if(node == null) return;
435 Object nodeInfo = node.getUserObject();
436 // after construction there's nothing in the trees, so check for that:
437 if(nodeInfo == null) return;
438
439 // We need to change to a Wait cursor while we load the documentNode
440 Container c = client.getContentPane();
441 c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
442
443
444 if(nodeInfo instanceof DocumentNodeData) {
445 //whether leaf or folder, the document element may contain text
446 DocumentNodeData docNode = (DocumentNodeData)nodeInfo;
447 client.retrieveContentFor(docNode);
448 // for docNodes, there's more than title metadata, so ensure
449 // all metadata has been retrieved
450 client.retrieveAllMetadataFor(docNode);
451
452 if(docNode.hasNoText()) { //NoText field is 1, meaning it's an img
453 // now display the image
454 this.htmlPane.setText(
455 Displays.getImgUrlEnclosedInHtml(docNode.getImgURL()));
456 } else { // it has text
457 // Java's htmlpane does not recognise justified alignment.
458 // It displays them all centred.
459 // So here we replace all ALIGN="JUSTIFY" with ALIGN="LEFT"
460 // (we don't do this in the DocumentNodeData class itself,
461 // because our nodeContent should not be transformed: it will
462 // display properly in browsers and other html displays).
463 //System.err.println("docNode can not be an image");
464 String docContent = docNode.getContent().replaceAll(
465 "ALIGN=\"JUSTIFY\"", "ALIGN=\"LEFT\"");
466 String baseURL = client.getBaseURL();
467 // TODO: make the docNode itself work out its URL by passing
468 // baseURL to the docNode?
469 if(!baseURL.equals("") && docNode.getRoot() != null) {
470 // "" is the case where dlAPIA = gs3
471 // where the _httpdocimg_ macro will deal with
472 // resolving the relative urls into their full ones
473 // We don't want to set the base and meddle with macro
474 // for those cases.
475 // For Fedora's case:
476 HTMLDocument doc
477 = (HTMLDocument)this.htmlPane.getDocument();
478 try{
479 URL url = new URL(baseURL+docNode.getRoot().nodeID+"/");
480 //System.err.println("url: " + url.toString());
481 doc.setBase(url);
482 //docContent = docContent.replaceAll("_httpdocimg_/", "");
483 LOG.debug(docContent);
484 }catch(MalformedURLException mex) {
485 ; //nothing to be done, leave the base as it is
486 }
487 }
488 this.htmlPane.setText(docContent);
489 }
490 this.htmlPane.setCaretPosition(0);
491 } else // treenode is a ClassifierNodeData, clear the html Pane
492 this.htmlPane.setText("");
493
494 // In any case -- whatever kind of nodedata it may be -- we display
495 // the metadata for this NodeData:
496 Displays.showMeta((NodeData)nodeInfo, metanames, metavalues);
497
498 c.setCursor(Cursor.getDefaultCursor()); // set the cursor back to normal
499 }
500
501 /** Inner class (not static, as it needs access to outerclass' this object.
502 * This class represents a button that encapsulates a ClassifierData
503 * object and sets its own name and tooltip text based on the displayName
504 * and displayDescription of that ClassifierData object. */
505 public class ClassifierButton
506 extends JButton implements ActionListener
507 {
508 /** Encapsulated classifierData obj */
509 public ClassifierData classifier;
510
511 /** Constructor that creates a button to visually represent
512 * the classifier.
513 * @param classifier - the ClassifierData object for which to
514 * create a button, using its display data. */
515 public ClassifierButton(ClassifierData classifier) {
516 super(classifier.displayName);
517 this.classifier = classifier;
518 this.setToolTipText(classifier.displayDescription);
519 this.addActionListener(this);
520 }
521
522 /** Called when someone presses the ClassifierButton: when pressed,
523 * perform the browse request associated with the classifier. */
524 public void actionPerformed(ActionEvent e) {
525 Container c = client.getContentPane();
526 c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
527 // empty the previous classification's/document's metadata
528 // and any text in the html pane
529 final String[] empty = {};
530 BrowseDisplay.this.metanames.setListData(empty);
531 BrowseDisplay.this.metavalues.setListData(empty);
532 BrowseDisplay.this.htmlPane.setText("");
533
534 // Now use the outerclass' MessagerClient object to perform the
535 // browse request:
536 BrowseDisplay.this.client.doBrowse(this.classifier);
537 BrowseDisplay.this.browseLabel.setText("Browsing by "
538 + classifier.displayName);
539 c.setCursor(Cursor.getDefaultCursor());
540 }
541 }
542
543 /** Static inner class that represents the data in a &lt;classifier&gt;
544 * element - itself nested inside a list (&lt;classifierList&gt;) of them.
545 * These elements are to be found in the response returned for a describe
546 * request sent to a collection's BrowseService. */
547 public static class ClassifierData {
548 /** The content attribute of the &lt;classifier&gt; */
549 public final String content;
550 /** The name attribute of the &lt;classifier&gt; */
551 public final String name;
552 /** The display name attribute of the &lt;classifier&gt; */
553 public final String displayName;
554 /** The description attribute of the &lt;classifier&gt; */
555 public final String displayDescription;
556
557 /** Constructor.
558 * @param classifierTag - creates a ClassifierData object from the
559 * data stored in a &lt;classifier&gt; element */
560 public ClassifierData(Element classifierTag) {
561 content = classifierTag.hasAttribute(GSXML.CLASSIFIER_CONTENT_ATT) ?
562 classifierTag.getAttribute(GSXML.CLASSIFIER_CONTENT_ATT) : "";
563 name = classifierTag.hasAttribute(GSXML.NAME_ATT) ?
564 classifierTag.getAttribute(GSXML.NAME_ATT) : "";
565
566 // now get <displayItem name="name">value</displayItem>
567 // and <displayItem name="description">descr</displayItem>
568 HashMap displayData = new HashMap(2); //size = 2, because
569 // generally expecting only display Name and Description
570 NodeList nl = classifierTag.getElementsByTagName(
571 GSXML.DISPLAY_TEXT_ELEM);
572 for(int i = 0; i < nl.getLength(); i++) {
573 Element displayItem = (Element)nl.item(0);
574 if(displayItem.hasAttribute(GSXML.NAME_ATT)) {
575 String nameAtt = displayItem.getAttribute(GSXML.NAME_ATT);
576 String value = ParseUtil.getBodyTextValue(displayItem);
577 displayData.put(nameAtt, value);
578 }
579 }
580 String dName = (String)displayData.get(GSXML.DISPLAY_TEXT_NAME);
581 String dDescr = (String)displayData.get(
582 GSXML.DISPLAY_TEXT_DESCRIPTION);
583 this.displayName = (dName == null) ? "" : dName;
584 this.displayDescription = (dDescr == null) ? "" : dDescr;
585
586 // Can get rid of HashMap now:
587 displayData.clear();
588 displayData = null;
589 }
590
591 /** The displayName can be used as a label in any widget.
592 * @return the displayName of this ClassifierData object */
593 public String toString() { return this.displayName; }
594
595 /** @return a display String with the data stored in this ClassifierData
596 * object. Useful for debugging purposes. */
597 public String show() {
598 StringBuffer buf = new StringBuffer(this.name);
599 buf.append(" ");
600 buf.append(this.content);
601 buf.append(" ");
602 buf.append(this.displayName);
603 buf.append(" ");
604 buf.append(this.displayDescription);
605
606 return buf.toString();
607 }
608 }
609}
Note: See TracBrowser for help on using the repository browser.