001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.util;
042:
043: import java.io.*;
044: import java.net.MalformedURLException;
045: import java.net.URL;
046: import java.util.ArrayList;
047: import java.util.Enumeration;
048: import java.util.Locale;
049: import java.util.Vector;
050:
051: import javax.help.HelpSet;
052: import javax.help.HelpSetException;
053: import javax.help.IndexItem;
054: import javax.help.IndexView;
055: import javax.help.InvalidHelpSetContextException;
056: import javax.help.Map;
057: import javax.help.Map.ID;
058: import javax.help.Merge;
059: import javax.help.NavigatorView;
060: import javax.help.SearchHit;
061: import javax.help.SearchTOCItem;
062: import javax.help.SearchView;
063: import javax.help.ServletHelpBroker;
064: import javax.help.SortMerge;
065: import javax.help.TOCItem;
066: import javax.help.TOCView;
067: import javax.help.TreeItem;
068: import javax.help.search.MergingSearchEngine;
069: import javax.help.search.SearchEvent;
070: import javax.help.search.SearchItem;
071: import javax.help.search.SearchListener;
072: import javax.help.search.SearchQuery;
073:
074: import javax.servlet.*;
075: import javax.servlet.http.*;
076: import javax.servlet.jsp.*;
077: import javax.swing.tree.DefaultMutableTreeNode;
078: import javax.swing.tree.TreeNode;
079:
080: import javax.faces.context.FacesContext;
081:
082: /**
083: * This is a set of utilities used for accessing JavaHelp content.
084: *
085: * @author Sun Microsystems, Inc.
086: */
087: public class HelpUtils implements SearchListener {
088: public static final String URL_SEPARATOR = "/";
089: public static final String TOC_VIEW_NAME = "TOC";
090: public static final String INDEX_VIEW_NAME = "Index";
091: public static final String SEARCH_VIEW_NAME = "Search";
092:
093: private ServletHelpBroker helpBroker;
094:
095: // TOC variables.
096: private TOCView tocView;
097: private Enumeration tocTreeEnum;
098: private ArrayList tocTreeList;
099: private DefaultMutableTreeNode tocTopNode;
100:
101: // Index (tab) variables.
102: private IndexView indexView;
103: private Enumeration indexTreeEnum;
104: private ArrayList indexTreeList;
105: private DefaultMutableTreeNode indexTopNode;
106:
107: // Search variables.
108: private SearchView searchView;
109: private MergingSearchEngine helpSearch;
110: private SearchQuery searchQuery;
111: private Vector searchNodes;
112: private Enumeration searchEnum;
113: private boolean searchFinished;
114:
115: // The application name (context name).
116: private String appName;
117:
118: // Help path prefix
119: private static String pathPrefix;
120:
121: // unsecure http port to use for help requests
122: int httpPort = -1;
123:
124: // Locale object for the tags.
125: private Locale currentLocale;
126:
127: /** Node ID of the root treenode. */
128: public static final String BASE_ID = "root";
129:
130: /** Tips on searching path. */
131: protected static final String REQUEST_SCHEME = "http";
132: protected static final String HTML_DIR = "html";
133: protected static final String HELP_DIR = "help";
134: protected static final String DEFAULT_HELPSET_NAME = "app.hs";
135: protected static final String TIPS_ON_SEARCHING_FILE = "tips_on_searching.html";
136:
137: /** Constructor. */
138: public HelpUtils(HttpServletRequest request, String appName,
139: int httpPort) {
140: // Debug.initTrace();
141: this .appName = appName;
142:
143: this .httpPort = httpPort;
144:
145: // Set up the currentLocale object.
146: currentLocale = getLocale();
147:
148: // Initialize the helpBroker and create/validate the helpset.
149: initHelp(request);
150: }
151:
152: /** Constructor. */
153: public HelpUtils(HttpServletRequest request, String appName,
154: String pathPrefix) {
155: // Debug.initTrace();
156: this .appName = appName;
157:
158: if ((pathPrefix != null) && (pathPrefix.length() != 0)) {
159: if (pathPrefix.trim().length() != 0) {
160: this .pathPrefix = pathPrefix.trim();
161: }
162: }
163:
164: // Set up the currentLocale object.
165: currentLocale = getLocale();
166:
167: // Initialize the helpBroker and create/validate the helpset.
168: initHelp(request);
169: }
170:
171: private Locale getLocale() {
172: FacesContext context = FacesContext.getCurrentInstance();
173: return context.getViewRoot().getLocale();
174: }
175:
176: /**
177: * Get the path to the localized tips_on_searching help file.
178: */
179: public String getTipsOnSearchingPath(ServletContext context) {
180:
181: // first check if the file is in the app help directory, if
182: // not look for it in the resource context path.
183:
184: StringBuffer buf = new StringBuffer(128);
185:
186: buf.append(getHelpPath(appName)).append(URL_SEPARATOR).append(
187: HTML_DIR).append(URL_SEPARATOR).append(
188: currentLocale.toString()).append(URL_SEPARATOR).append(
189: HELP_DIR).append(URL_SEPARATOR).append(
190: TIPS_ON_SEARCHING_FILE);
191:
192: return buf.toString();
193:
194: /*
195: // file is in the resource context path
196: buf = new StringBuffer(CCSystem.getResourceContextPath() +
197: URL_SEPARATOR + HTML_DIR
198: + URL_SEPARATOR + currentLocale.toString()
199: + URL_SEPARATOR + HELP_DIR
200: + URL_SEPARATOR + TIPS_ON_SEARCHING_FILE);
201: return buf.toString();
202: */
203: }
204:
205: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206: // Initialization methods
207: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
208:
209: /**
210: * Initialize the Help helpset.
211: */
212: private void initHelp(HttpServletRequest request) {
213:
214: instantiateHelpBroker(request);
215:
216: // Grab the default HelpSet path: /<appName>/html/<locale>/help/app.hs
217: String hsPath = getDefaultHelpSetPath();
218: // Debug.trace3("hsPath: " + hsPath);
219:
220: // Validate the HelpSets and the help IDs (use null to get current ID).
221: validateHelpSet(request, hsPath, false);
222: validateID(null);
223:
224: initNavigatorViews();
225: }
226:
227: /**
228: * Instantiate the ServletHelpBroker bean.
229: */
230: private void instantiateHelpBroker(HttpServletRequest request) {
231: try {
232: helpBroker = (ServletHelpBroker) java.beans.Beans
233: .instantiate(this .getClass().getClassLoader(),
234: "javax.help.ServletHelpBroker");
235: } catch (ClassNotFoundException exc) {
236: // XXX: Is this serious??
237: System.out.println("Cannot instantiate ServletHelpBroker."
238: + exc.getMessage());
239: } catch (Exception exc) {
240: // XXX: Is this serious??
241: System.out
242: .println("Cannot create bean of class ServletHelpBroker."
243: + exc.getMessage());
244: }
245: }
246:
247: /**
248: * Return a handle to the ServletHelpBroker.
249: */
250: public ServletHelpBroker getHelpBroker() {
251: return helpBroker;
252: }
253:
254: public String getLocalizedHelpPath() {
255: StringBuffer buffer = new StringBuffer(1024);
256:
257: buffer.append(appName);
258:
259: if (!appName.endsWith("/")) {
260: // add the slash if it's not there already
261: buffer.append(URL_SEPARATOR);
262: }
263:
264: buffer.append(HTML_DIR).append(URL_SEPARATOR).append(
265: currentLocale.toString()).append(URL_SEPARATOR).append(
266: HELP_DIR).append(URL_SEPARATOR);
267:
268: return buffer.toString();
269: }
270:
271: /**
272: * Return the path to the default helpset file. The path will be formatted
273: * as follows:
274: * <p>
275: * <code>/<appName>/html/<locale>/help/app.hs</code>
276: * </p>
277: */
278: public String getDefaultHelpSetPath() {
279: /*
280: if (appName == null) {
281: appName = request.getContextPath();
282: if (appName == null) {
283: // Debug("Unable to obtain app name from request.");
284: appName = "";
285: } else {
286: if (appName.startsWith(URL_SEPARATOR)) {
287: appName = appName.substring(1);
288: }
289: }
290: }
291: */
292:
293: StringBuffer buffer = new StringBuffer(1024);
294:
295: buffer.append(getLocalizedHelpPath()).append(
296: DEFAULT_HELPSET_NAME);
297:
298: // System.out.println("default hs path = " + buffer.toString());
299:
300: return buffer.toString();
301: }
302:
303: /**
304: * Get help installation directory with reference to the app
305: * base. If the application's pathPrefix is set to a given value
306: * then this method will return a string of the form pathPrefix/html.
307: * If the appName is null or empty or no path prefix has been set then
308: * "html" will be returned.
309: */
310: private static String getHelpPath(String appName) {
311:
312: if ((appName == null) || (appName.length() == 0)) {
313: return HTML_DIR;
314: } else {
315: if (pathPrefix == null) {
316: return appName;
317: } else {
318: return (appName + URL_SEPARATOR + pathPrefix);
319: }
320: }
321: }
322:
323: /**
324: * Initialize navigator views.
325: */
326: private void initNavigatorViews() {
327: // Initialize TOC.
328: //
329: HelpSet hs = helpBroker.getHelpSet();
330: Locale locale = hs.getLocale();
331:
332: tocView = (TOCView) hs.getNavigatorView(TOC_VIEW_NAME);
333: if (tocView != null) {
334: // Grab the tree data from the navigator view.
335: tocTopNode = tocView.getDataAsTree();
336:
337: // Sort the helpsets
338: String mergeType = tocView.getMergeType();
339: if (mergeType != null) {
340: SortMerge.sortNode(tocTopNode, locale);
341: }
342:
343: // Add all the sub-helpsets to the master merged helpset.
344: addSubHelpSets(hs);
345:
346: // Set the tocTreeEnum and tocTreeList objects for future use.
347: tocTreeEnum = tocTopNode.preorderEnumeration();
348: setTOCTreeList();
349: }
350:
351: // Initialize Index.
352: //
353:
354: // Get the Index navigator view and index tree data.
355: indexView = (IndexView) hs.getNavigatorView(INDEX_VIEW_NAME);
356: if (indexView != null) {
357: indexTopNode = indexView.getDataAsTree();
358:
359: // Set the indexTreeEnum and indexTreeList objects for future use.
360: indexTreeEnum = indexTopNode.preorderEnumeration();
361: setIndexTreeList();
362: }
363:
364: // Initialize Search.
365: //
366:
367: // Get the Search navigator view and index tree data.
368: searchView = (SearchView) hs.getNavigatorView(SEARCH_VIEW_NAME);
369: }
370:
371: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
372: // Validation methods
373: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374:
375: /**
376: * This method validates the helpset.
377: *
378: * @param request The request for this page.
379: * @param hsName The helpset name.
380: * @param merge Indicates whether the helpset hsName should be merged.
381: */
382: public void validateHelpSet(HttpServletRequest request,
383: String hsName, boolean merge) {
384: HelpSet hs = helpBroker.getHelpSet();
385:
386: // The HelpSet exists.
387: if (hs != null) {
388: // If the hsName is null, return since there is nothing to do.
389: // Otherwise, if merging is turned on, add the HelpSet.
390: if (hsName == null) {
391: return;
392: }
393:
394: HelpSet newHS = createHelpSet(request, hsName);
395: if (merge && !hs.contains(newHS)) {
396: hs.add(newHS);
397: } else {
398: helpBroker.setHelpSet(newHS);
399: }
400:
401: // The HelpSet does not exist.
402: } else {
403: // If the hsName is null, forward to the invalid page. Otherwise,
404: // create a HelpSet from hsName and set HelpBroker's HelpSet value.
405: if (hsName == null) {
406: // Debug.trace1("Invalid URL path: " + hsName);
407: // XXX: Forward to invalid url page.
408: return;
409: }
410: helpBroker.setHelpSet(createHelpSet(request, hsName));
411: }
412: }
413:
414: /**
415: * Validate the given help id. If none is specified, set the current id to
416: * the home id.
417: *
418: * @param helpID the current ID.
419: */
420: public void validateID(String helpID) {
421: if (helpID != null) {
422: helpBroker.setCurrentID(helpID);
423: } else if (helpBroker.getCurrentID() == null
424: && helpBroker.getCurrentURL() == null) {
425: try {
426: helpBroker.setCurrentID(helpBroker.getHelpSet()
427: .getHomeID());
428: } catch (InvalidHelpSetContextException e) {
429: // Ignore
430: }
431: }
432: }
433:
434: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
435: // HelpSet methods
436: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
437:
438: /**
439: * Set the path to the "current" page.
440: */
441: public void setCurrentHelpPage(URL url) {
442: helpBroker.setCurrentURL(url);
443: }
444:
445: /**
446: * Creates a helpset.
447: *
448: * @param request The request for this page
449: * @param hsName the HelpSet name
450: * @return the HelpSet created
451: */
452: private HelpSet createHelpSet(HttpServletRequest request,
453: String hsName) {
454: if (!hsName.startsWith(REQUEST_SCHEME)
455: && !hsName.startsWith(URL_SEPARATOR)) {
456: hsName = URL_SEPARATOR + hsName;
457: }
458:
459: HelpSet hs = null;
460:
461: int port = httpPort;
462:
463: if (port == -1) {
464: port = request.getServerPort();
465: }
466:
467: try {
468: URL url = (hsName.startsWith(REQUEST_SCHEME)) ? new URL(
469: hsName) : new URL(REQUEST_SCHEME, "127.0.0.1",
470: port, hsName);
471:
472: hs = new HelpSet(null, url);
473: } catch (MalformedURLException e) {
474: // ignore
475: } catch (HelpSetException hse) {
476: // If the currentLocale is not "en", try to create the HelpSet using
477: // the "en" (default) locale.
478: if (!currentLocale.toString().equals(Locale.ENGLISH)) {
479: currentLocale = Locale.ENGLISH;
480: hs = createHelpSet(request, getDefaultHelpSetPath());
481: // XXX: This is a serious error. The currentLocale is not "en", and a
482: // helpset still cannot be found. Throw a runtime exception for now.
483: } else {
484: throw new RuntimeException(hse.getMessage());
485: }
486: }
487: return hs;
488: }
489:
490: /**
491: * Adds sub-helpsets to the master merged helpset.
492: *
493: * @param hs The HelpSet to which subhelpsets will be added
494: */
495: private void addSubHelpSets(HelpSet hs) {
496: for (Enumeration e = hs.getHelpSets(); e.hasMoreElements();) {
497: HelpSet ehs = (HelpSet) e.nextElement();
498: if (ehs == null) {
499: continue;
500: }
501:
502: // Merge views
503: NavigatorView[] views = ehs.getNavigatorViews();
504: for (int i = 0; i < views.length; i++) {
505: if (views[i] instanceof TOCView) {
506: Merge mergeObject = Merge.DefaultMergeFactory
507: .getMerge(tocView, views[i]);
508: if (mergeObject != null) {
509: mergeObject.processMerge(tocTopNode);
510: }
511: }
512: }
513: addSubHelpSets(ehs);
514: }
515: }
516:
517: /**
518: * Return the ID of the given node.
519: */
520: public String getID(TreeNode node) {
521: if (node == tocTopNode) {
522: return BASE_ID;
523: }
524:
525: TreeNode parent = node.getParent();
526: if (parent == null) {
527: return "";
528: }
529:
530: String id = getID(parent);
531: return id.concat("_" + Integer.toString(parent.getIndex(node)));
532: }
533:
534: /**
535: * Return the content URL in String form for a given TreeItem, or an empty
536: * String if no content exists.
537: */
538: public String getContentURL(TreeItem item) {
539: URL url = null;
540: ID id = item.getID();
541: if (id != null) {
542: HelpSet hs = id.hs;
543: Map map = hs.getLocalMap();
544: try {
545: url = map.getURLFromID(id);
546: } catch (MalformedURLException e) {
547: // Ignore
548: }
549: }
550: return (url != null) ? url.toExternalForm() : "";
551: }
552:
553: /**
554: * Set the TOC tree list object using the tocTreeEnum object.
555: */
556: private void setTOCTreeList() {
557: tocTreeList = new ArrayList();
558: while (tocTreeEnum.hasMoreElements()) {
559: tocTreeList.add(tocTreeEnum.nextElement());
560: }
561: }
562:
563: /**
564: * Return the TOC tree enumeration as an ArrayList object.
565: */
566: public ArrayList getTOCTreeList() {
567: if (tocTreeList == null) {
568: setTOCTreeList();
569: }
570: return tocTreeList;
571: }
572:
573: /**
574: * Set the Index tree list object using the indexTreeEnum object.
575: */
576: private void setIndexTreeList() {
577: indexTreeList = new ArrayList();
578: while (indexTreeEnum.hasMoreElements()) {
579: indexTreeList.add(indexTreeEnum.nextElement());
580: }
581: }
582:
583: /**
584: * Return the Index tree enumeration as an ArrayList object.
585: */
586: public ArrayList getIndexTreeList() {
587: if (indexTreeList == null) {
588: setIndexTreeList();
589: }
590: return indexTreeList;
591: }
592:
593: /**
594: * Do a search on the query passed in.
595: */
596: public synchronized Enumeration doSearch(String query) {
597: if (query == null) {
598: return null;
599: }
600:
601: if (helpSearch == null) {
602: if (searchView == null) {
603: searchView = (SearchView) helpBroker.getHelpSet()
604: .getNavigatorView(SEARCH_VIEW_NAME);
605: }
606:
607: if (searchView == null) {
608: return null;
609: }
610:
611: helpSearch = new MergingSearchEngine(searchView);
612: searchQuery = helpSearch.createQuery();
613: searchQuery.addSearchListener(this );
614: }
615:
616: if (searchQuery.isActive()) {
617: searchQuery.stop();
618: }
619:
620: searchFinished = false;
621: searchQuery.start(query, currentLocale);
622:
623: // Wait for search to finish.
624: if (!searchFinished) {
625: try {
626: wait();
627: } catch (InterruptedException e) {
628: // ignore
629: }
630: }
631:
632: // searchEnum is set in searchFinished method.
633: return searchEnum;
634: }
635:
636: /**
637: * Tells the listener that the search has started.
638: */
639: public synchronized void searchStarted(SearchEvent e) {
640: searchNodes = new Vector();
641: searchFinished = false;
642: }
643:
644: /**
645: * Tells the listener that the search has finished.
646: */
647: public synchronized void searchFinished(SearchEvent e) {
648: searchFinished = true;
649: searchEnum = searchNodes.elements();
650: notifyAll();
651: }
652:
653: /**
654: * Tells the listener that matching SearchItems have been found.
655: */
656: public synchronized void itemsFound(SearchEvent e) {
657: SearchTOCItem tocitem;
658: Enumeration itemEnum = e.getSearchItems();
659:
660: // Iterate through each search item in the searchEvent
661: while (itemEnum.hasMoreElements()) {
662: SearchItem item = (SearchItem) itemEnum.nextElement();
663: URL url;
664: try {
665: url = new URL(item.getBase(), item.getFilename());
666: } catch (MalformedURLException me) {
667: /* Debug.trace3("Could not create URL from: "
668: + item.getBase() + "|" + item.getFilename()); */
669: continue;
670: }
671: boolean foundNode = false;
672:
673: // See if this search item matches that of one we currently have
674: // if so just do an update
675: Enumeration nodesEnum = searchNodes.elements();
676: while (nodesEnum.hasMoreElements()) {
677: tocitem = (SearchTOCItem) nodesEnum.nextElement();
678: URL testURL = tocitem.getURL();
679: if (testURL != null && url != null
680: && url.sameFile(testURL)) {
681: tocitem.addSearchHit(new SearchHit(item
682: .getConfidence(), item.getBegin(), item
683: .getEnd()));
684: foundNode = true;
685: break;
686: }
687: }
688:
689: // No match.
690: // OK then add a new one.
691: if (!foundNode) {
692: tocitem = new SearchTOCItem(item);
693: searchNodes.addElement(tocitem);
694: }
695: }
696: }
697:
698: /**
699: * For debug - print the attributes of each node in the toc and index trees.
700: */
701: public void printDebug() {
702: // Print TOC tree.
703: ArrayList tocTreeList = getTOCTreeList();
704: if (tocTreeList == null) {
705: // Debug.trace1("tocTreeList null.");
706: return;
707: }
708:
709: StringBuffer buf = new StringBuffer("tocTreeList dump:\n");
710: DefaultMutableTreeNode node = null;
711: int nTreeNodes = tocTreeList.size();
712: for (int i = 0; i < nTreeNodes; i++) {
713: node = (DefaultMutableTreeNode) tocTreeList.get(i);
714: buf.append(tocTreeToString(node)).append("\n");
715: }
716:
717: // Print Index tree.
718: ArrayList indexTreeList = getIndexTreeList();
719: if (indexTreeList == null) {
720: // Debug.trace1("indexTreeList null.");
721: return;
722: }
723:
724: buf = new StringBuffer("indexTreeList dump:\n");
725: nTreeNodes = indexTreeList.size();
726: for (int i = 0; i < nTreeNodes; i++) {
727: node = (DefaultMutableTreeNode) indexTreeList.get(i);
728: buf.append(indexTreeToString(node)).append("\n");
729: }
730: }
731:
732: /**
733: * Return a string containing the contents of the given TOC tree node.
734: */
735: public String tocTreeToString(DefaultMutableTreeNode node) {
736: // Add TOC tree to buffer.
737: if (node == null) {
738: return ("\n\tTOC tree node is null.");
739: }
740:
741: TOCItem item = (TOCItem) node.getUserObject();
742: if (item == null) {
743: return ("\n\tTOCItem is null.");
744: }
745:
746: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node
747: .getParent();
748: StringBuffer buf = new StringBuffer();
749: buf.append("\n\tname: " + item.getName());
750: buf.append("\n\thelpID: "
751: + ((item.getID() != null) ? item.getID().id : ""));
752: buf.append("\n\tparentID: "
753: + ((parent != null) ? Integer.toHexString(parent
754: .hashCode()) : ""));
755: buf.append("\n\tparentID 2: " + getID(parent));
756: buf.append("\n\tnode: "
757: + Integer.toHexString(node.hashCode()));
758: buf.append("\n\tnodeID: " + getID(node));
759: buf.append("\n\tcontentURL: " + getContentURL(item));
760: buf.append("\n\texpansionType: "
761: + Integer.toString(item.getExpansionType()));
762:
763: return buf.toString();
764: }
765:
766: /**
767: * Return a string containing the contents of the given Index tree node.
768: */
769: public String indexTreeToString(DefaultMutableTreeNode node) {
770: // Add Index tree to buffer.
771: if (node == null) {
772: return ("\n\tTree node is null.");
773: }
774:
775: IndexItem item = (IndexItem) node.getUserObject();
776: if (item == null) {
777: return ("\n\tIndexItem is null.");
778: }
779:
780: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node
781: .getParent();
782: StringBuffer buf = new StringBuffer();
783: buf.append("\n\tname: " + item.getName());
784: buf.append("\n\thelpID: "
785: + ((item.getID() != null) ? item.getID().id : ""));
786: buf.append("\n\tparentID: "
787: + ((parent != null) ? Integer.toHexString(parent
788: .hashCode()) : ""));
789: buf.append("\n\tparentID 2: " + getID(parent));
790: buf.append("\n\tnode: "
791: + Integer.toHexString(node.hashCode()));
792: buf.append("\n\tnodeID: " + getID(node));
793: buf.append("\n\texpansionType: "
794: + Integer.toString(item.getExpansionType()));
795:
796: return buf.toString();
797: }
798: }
|