All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.util.HelpUtils Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at
 * https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.webui.jsf.util;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Vector;

import javax.help.HelpSet;
import javax.help.HelpSetException;
import javax.help.IndexItem;
import javax.help.IndexView;
import javax.help.InvalidHelpSetContextException;
import javax.help.Map;
import javax.help.Map.ID;
import javax.help.Merge;
import javax.help.NavigatorView;
import javax.help.SearchHit;
import javax.help.SearchTOCItem;
import javax.help.SearchView;
import javax.help.ServletHelpBroker;
import javax.help.SortMerge;
import javax.help.TOCItem;
import javax.help.TOCView;
import javax.help.TreeItem;
import javax.help.search.MergingSearchEngine;
import javax.help.search.SearchEvent;
import javax.help.search.SearchItem;
import javax.help.search.SearchListener;
import javax.help.search.SearchQuery;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

import javax.faces.context.FacesContext;

/**
 * This is a set of utilities used for accessing JavaHelp content.
 *
 * @author  Sun Microsystems, Inc.
 */
public class HelpUtils implements SearchListener {
    public static final String URL_SEPARATOR = "/";
    public static final String TOC_VIEW_NAME = "TOC";
    public static final String INDEX_VIEW_NAME = "Index";
    public static final String SEARCH_VIEW_NAME = "Search";

    private ServletHelpBroker helpBroker;

    // TOC variables.
    private TOCView tocView;
    private Enumeration tocTreeEnum;
    private ArrayList tocTreeList;
    private DefaultMutableTreeNode tocTopNode;    

    // Index (tab) variables.
    private IndexView indexView;
    private Enumeration indexTreeEnum;
    private ArrayList indexTreeList;
    private DefaultMutableTreeNode indexTopNode;    

    // Search variables.
    private SearchView searchView;
    private MergingSearchEngine helpSearch;
    private SearchQuery searchQuery;
    private Vector searchNodes;
    private Enumeration searchEnum;
    private boolean searchFinished;
    
    private String currentRequestScheme = null;

    // The application name (context name).
    private String appName;

    // Help path prefix
    private static String pathPrefix;
    
    // unsecure http port to use for help requests
    int httpPort = -1;

    // Locale object for the tags.
    private Locale currentLocale;

    /** Node ID of the root treenode. */
    public static final String BASE_ID = "root";

    /** Tips on searching path. */
    protected static final String REQUEST_SCHEME = "http";
    protected static final String HTML_DIR = "html";
    protected static final String HELP_DIR = "help";
    protected static final String DEFAULT_HELPSET_NAME = "app.hs";
    protected static final String TIPS_ON_SEARCHING_FILE =
	"tips_on_searching.html";

    /** Constructor. */
    public HelpUtils(HttpServletRequest request, String appName, int httpPort) {
	// Debug.initTrace();
	this.appName = appName;
        
        this.httpPort = httpPort;

	// Set up the currentLocale object.
	currentLocale = getLocale();

	// Initialize the helpBroker and create/validate the helpset.
	initHelp(request);
    }
    
    public HelpUtils(HttpServletRequest request, String appName, int httpPort,
            String requestScheme) {
        this.appName = appName;
        this.httpPort = httpPort;

        // Set up the currentLocale object.
        currentLocale = getLocale();
        
        currentRequestScheme = requestScheme;
        
        // Initialize the helpBroker and create/validate the helpset.
        initHelp(request);        
    }

    /** Constructor. */
    public HelpUtils(HttpServletRequest request, String appName,
	    String pathPrefix) {
	// Debug.initTrace();
	this.appName = appName;

	if ((pathPrefix != null)  && (pathPrefix.length() != 0)) {
	    if (pathPrefix.trim().length() != 0) {
	        this.pathPrefix = pathPrefix.trim();
	    }
	}

	// Set up the currentLocale object.
	currentLocale = getLocale();

	// Initialize the helpBroker and create/validate the helpset.
	initHelp(request);
    }
    
    public String getCurrentRequestScheme() {
        if (currentRequestScheme != null) {
            return currentRequestScheme;
        }
        
        // default to http
        return REQUEST_SCHEME;
    }
    
    public void setCurrentRequestScheme(String scheme) {
        currentRequestScheme = scheme;
    }

    private Locale getLocale() {
	FacesContext context = FacesContext.getCurrentInstance();
        return context.getViewRoot().getLocale();
    }

    /**
     * Get the path to the localized tips_on_searching help file.
     */
    public String getTipsOnSearchingPath(ServletContext context) {

	// first check if the file is in the app help directory, if 
	// not look for it in the resource context path.

	StringBuffer buf = new StringBuffer(128);
        
        buf.append(getHelpPath(appName))
            .append(URL_SEPARATOR)
            .append(HTML_DIR)
            .append(URL_SEPARATOR)
            .append(currentLocale.toString())
            .append(URL_SEPARATOR) 
            .append(HELP_DIR)
            .append(URL_SEPARATOR)
            .append(TIPS_ON_SEARCHING_FILE);
        
        return buf.toString();
        
        /*            
        // file is in the resource context path
        buf = new StringBuffer(CCSystem.getResourceContextPath() + 
            URL_SEPARATOR + HTML_DIR
            + URL_SEPARATOR + currentLocale.toString()
            + URL_SEPARATOR + HELP_DIR
            + URL_SEPARATOR + TIPS_ON_SEARCHING_FILE);
        return buf.toString();
        */
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Initialization methods
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    /**
     * Initialize the Help helpset.
     */
    private void initHelp(HttpServletRequest request) {        
        
	instantiateHelpBroker(request);
        
	// Grab the default HelpSet path: //html//help/app.hs
	String hsPath = getDefaultHelpSetPath();
	// Debug.trace3("hsPath: " + hsPath);

	// Validate the HelpSets and the help IDs (use null to get current ID).
	validateHelpSet(request, hsPath, false);
	validateID(null);

	initNavigatorViews();
    }

    /** 
     * Instantiate the ServletHelpBroker bean.
     */
    private void instantiateHelpBroker(HttpServletRequest request) {
	try {
	    helpBroker = (ServletHelpBroker) java.beans.Beans.instantiate(
		this.getClass().getClassLoader(), 
		"javax.help.ServletHelpBroker");
	} catch (ClassNotFoundException exc) {
	    // XXX: Is this serious??
	    System.out.println("Cannot instantiate ServletHelpBroker."
		+ exc.getMessage());
	} catch (Exception exc) {
	    // XXX: Is this serious??
	    System.out.println("Cannot create bean of class ServletHelpBroker."
		+ exc.getMessage());
	}
    }
    
    /**
     * Return a handle to the ServletHelpBroker.
     */
    public ServletHelpBroker getHelpBroker() {
	return helpBroker;
    }
    
    public String getLocalizedHelpPath() {
        StringBuffer buffer = new StringBuffer(1024);
        
        buffer.append(appName);
        
        if (!appName.endsWith("/"))  {
            // add the slash if it's not there already
            buffer.append(URL_SEPARATOR);
        }
        
        buffer.append(HTML_DIR)
	    .append(URL_SEPARATOR)
	    .append(currentLocale.toString())
	    .append(URL_SEPARATOR)
	    .append(HELP_DIR)
	    .append(URL_SEPARATOR);
        
        return buffer.toString();
    }

    /**
     * Return the path to the default helpset file. The path will be formatted
     * as follows:
     * 

* //html//help/app.hs *

*/ public String getDefaultHelpSetPath() { /* if (appName == null) { appName = request.getContextPath(); if (appName == null) { // Debug("Unable to obtain app name from request."); appName = ""; } else { if (appName.startsWith(URL_SEPARATOR)) { appName = appName.substring(1); } } } */ StringBuffer buffer = new StringBuffer(1024); buffer.append(getLocalizedHelpPath()) .append(DEFAULT_HELPSET_NAME); // System.out.println("default hs path = " + buffer.toString()); return buffer.toString(); } /** * Get help installation directory with reference to the app * base. If the application's pathPrefix is set to a given value * then this method will return a string of the form pathPrefix/html. * If the appName is null or empty or no path prefix has been set then * "html" will be returned. */ private static String getHelpPath(String appName) { if ((appName == null) || (appName.length() == 0)) { return HTML_DIR; } else { if (pathPrefix == null) { return appName; } else { return (appName + URL_SEPARATOR + pathPrefix); } } } /** * Initialize navigator views. */ private void initNavigatorViews() { // Initialize TOC. // HelpSet hs = helpBroker.getHelpSet(); Locale locale = hs.getLocale(); tocView = (TOCView) hs.getNavigatorView(TOC_VIEW_NAME); if (tocView != null) { // Grab the tree data from the navigator view. tocTopNode = tocView.getDataAsTree(); // Add all the sub-helpsets to the master merged helpset. addSubHelpSets(hs); // Set the tocTreeEnum and tocTreeList objects for future use. tocTreeEnum = tocTopNode.preorderEnumeration(); setTOCTreeList(); } // Initialize Index. // // Get the Index navigator view and index tree data. indexView = (IndexView) hs.getNavigatorView(INDEX_VIEW_NAME); if (indexView != null) { indexTopNode = indexView.getDataAsTree(); // Set the indexTreeEnum and indexTreeList objects for future use. indexTreeEnum = indexTopNode.preorderEnumeration(); setIndexTreeList(); } // Initialize Search. // // Get the Search navigator view and index tree data. searchView = (SearchView) hs.getNavigatorView(SEARCH_VIEW_NAME); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Validation methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * This method validates the helpset. * * @param request The request for this page. * @param hsName The helpset name. * @param merge Indicates whether the helpset hsName should be merged. */ public void validateHelpSet(HttpServletRequest request, String hsName, boolean merge) { HelpSet hs = helpBroker.getHelpSet(); // The HelpSet exists. if (hs != null) { // If the hsName is null, return since there is nothing to do. // Otherwise, if merging is turned on, add the HelpSet. if (hsName == null) { return; } HelpSet newHS = createHelpSet(request, hsName); if (merge && !hs.contains(newHS)) { hs.add(newHS); } else { helpBroker.setHelpSet(newHS); } // The HelpSet does not exist. } else { // If the hsName is null, forward to the invalid page. Otherwise, // create a HelpSet from hsName and set HelpBroker's HelpSet value. if (hsName == null) { // Debug.trace1("Invalid URL path: " + hsName); // XXX: Forward to invalid url page. return; } helpBroker.setHelpSet(createHelpSet(request, hsName)); } } /** * Validate the given help id. If none is specified, set the current id to * the home id. * * @param helpID the current ID. */ public void validateID(String helpID) { if (helpID != null) { helpBroker.setCurrentID(helpID); } else if (helpBroker.getCurrentID() == null && helpBroker.getCurrentURL() == null) { try { helpBroker.setCurrentID(helpBroker.getHelpSet().getHomeID()); } catch (InvalidHelpSetContextException e) { // Ignore } } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HelpSet methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Set the path to the "current" page. */ public void setCurrentHelpPage(URL url) { helpBroker.setCurrentURL(url); } /** * Creates a helpset. * * @param request The request for this page * @param hsName the HelpSet name * @return the HelpSet created */ private HelpSet createHelpSet(HttpServletRequest request, String hsName) { if (!hsName.startsWith(REQUEST_SCHEME) && !hsName.startsWith(URL_SEPARATOR)) { hsName = URL_SEPARATOR + hsName; } HelpSet hs = null; int port = httpPort; if (port == -1) { port = request.getServerPort(); } try { URL url = (hsName.startsWith(REQUEST_SCHEME)) ? new URL(hsName) : new URL(getCurrentRequestScheme(), request.getServerName(), port, hsName); hs = new HelpSet(null, url); } catch (MalformedURLException e) { // ignore } catch (HelpSetException hse) { // If the currentLocale is not "en", try to create the HelpSet using // the "en" (default) locale. if (! currentLocale.equals(Locale.ENGLISH)) { currentLocale = Locale.ENGLISH; try { hs = createHelpSet(request, getDefaultHelpSetPath()); } catch (Exception ex) { LogUtil.warning("Can not create helpset for en locale: " + ex.getMessage()); throw new RuntimeException(ex); } } else { // XXX: This is a serious error. The currentLocale is "en", // and a helpset still cannot be found. Throw a runtime // exception for now. LogUtil.warning("Can not create helpset for en locale: " + hse.getMessage()); throw new RuntimeException(hse); } } return hs; } /** * Adds sub-helpsets to the master merged helpset. * * @param hs The HelpSet to which subhelpsets will be added */ private void addSubHelpSets(HelpSet hs) { for (Enumeration e = hs.getHelpSets(); e.hasMoreElements(); ) { HelpSet ehs = (HelpSet) e.nextElement(); if (ehs == null) { continue; } // Merge views NavigatorView[] views = ehs.getNavigatorViews(); for (int i = 0; i < views.length; i++) { if (views[i] instanceof TOCView) { Merge mergeObject = Merge.DefaultMergeFactory.getMerge( tocView, views[i]); if (mergeObject != null) { mergeObject.processMerge(tocTopNode); } } } addSubHelpSets(ehs); } } /** * Return the ID of the given node. */ public String getID(TreeNode node) { if (node == tocTopNode) { return BASE_ID; } TreeNode parent = node.getParent(); if (parent == null) { return ""; } String id = getID(parent); return id.concat("_" + Integer.toString(parent.getIndex(node))); } /** * Return the content URL in String form for a given TreeItem, or an empty * String if no content exists. */ public String getContentURL(TreeItem item) { URL url = null; ID id = item.getID(); if (id != null) { HelpSet hs = id.hs; Map map = hs.getLocalMap(); try { url = map.getURLFromID(id); } catch (MalformedURLException e) { // Ignore } } return (url != null) ? url.toExternalForm() : ""; } /** * Set the TOC tree list object using the tocTreeEnum object. */ private void setTOCTreeList() { tocTreeList = new ArrayList(); while (tocTreeEnum.hasMoreElements()) { tocTreeList.add(tocTreeEnum.nextElement()); } } /** * Return the TOC tree enumeration as an ArrayList object. */ public ArrayList getTOCTreeList() { if (tocTreeList == null) { setTOCTreeList(); } return tocTreeList; } /** * Set the Index tree list object using the indexTreeEnum object. */ private void setIndexTreeList() { indexTreeList = new ArrayList(); while (indexTreeEnum.hasMoreElements()) { indexTreeList.add(indexTreeEnum.nextElement()); } } /** * Return the Index tree enumeration as an ArrayList object. */ public ArrayList getIndexTreeList() { if (indexTreeList == null) { setIndexTreeList(); } return indexTreeList; } /** * Do a search on the query passed in. */ public synchronized Enumeration doSearch(String query) { if (query == null) { return null; } if (helpSearch == null) { if (searchView == null) { searchView = (SearchView) helpBroker.getHelpSet() .getNavigatorView(SEARCH_VIEW_NAME); } if (searchView == null) { return null; } helpSearch = new MergingSearchEngine(searchView); searchQuery = helpSearch.createQuery(); searchQuery.addSearchListener(this); } if (searchQuery.isActive()) { searchQuery.stop(); } searchFinished = false; searchQuery.start(query, currentLocale); // Wait for search to finish. if (!searchFinished) { try { wait(); } catch (InterruptedException e) { // ignore } } // searchEnum is set in searchFinished method. return searchEnum; } /** * Tells the listener that the search has started. */ public synchronized void searchStarted(SearchEvent e) { searchNodes = new Vector(); searchFinished = false; } /** * Tells the listener that the search has finished. */ public synchronized void searchFinished(SearchEvent e) { searchFinished = true; searchEnum = searchNodes.elements(); notifyAll(); } /** * Tells the listener that matching SearchItems have been found. */ public synchronized void itemsFound(SearchEvent e) { SearchTOCItem tocitem; Enumeration itemEnum = e.getSearchItems(); // Iterate through each search item in the searchEvent while (itemEnum.hasMoreElements()) { SearchItem item = (SearchItem) itemEnum.nextElement(); URL url; try { url = new URL(item.getBase(), item.getFilename()); } catch (MalformedURLException me) { /* Debug.trace3("Could not create URL from: " + item.getBase() + "|" + item.getFilename()); */ continue; } boolean foundNode = false; // See if this search item matches that of one we currently have // if so just do an update Enumeration nodesEnum = searchNodes.elements(); while (nodesEnum.hasMoreElements()) { tocitem = (SearchTOCItem) nodesEnum.nextElement(); URL testURL = tocitem.getURL(); if (testURL != null && url != null && url.sameFile(testURL)) { tocitem.addSearchHit(new SearchHit(item.getConfidence(), item.getBegin(), item.getEnd())); foundNode = true; break; } } // No match. // OK then add a new one. if (!foundNode) { tocitem = new SearchTOCItem(item); searchNodes.addElement(tocitem); } } } /** * For debug - print the attributes of each node in the toc and index trees. */ public void printDebug() { // Print TOC tree. ArrayList tocTreeList = getTOCTreeList(); if (tocTreeList == null) { // Debug.trace1("tocTreeList null."); return; } StringBuffer buf = new StringBuffer("tocTreeList dump:\n"); DefaultMutableTreeNode node = null; int nTreeNodes = tocTreeList.size(); for (int i = 0; i < nTreeNodes; i++) { node = (DefaultMutableTreeNode) tocTreeList.get(i); buf.append(tocTreeToString(node)).append("\n"); } // Print Index tree. ArrayList indexTreeList = getIndexTreeList(); if (indexTreeList == null) { // Debug.trace1("indexTreeList null."); return; } buf = new StringBuffer("indexTreeList dump:\n"); nTreeNodes = indexTreeList.size(); for (int i = 0; i < nTreeNodes; i++) { node = (DefaultMutableTreeNode) indexTreeList.get(i); buf.append(indexTreeToString(node)).append("\n"); } } /** * Return a string containing the contents of the given TOC tree node. */ public String tocTreeToString(DefaultMutableTreeNode node) { // Add TOC tree to buffer. if (node == null) { return ("\n\tTOC tree node is null."); } TOCItem item = (TOCItem) node.getUserObject(); if (item == null) { return ("\n\tTOCItem is null."); } DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); StringBuffer buf = new StringBuffer(); buf.append("\n\tname: " + item.getName()); buf.append("\n\thelpID: " + ((item.getID() != null) ? item.getID().id : "")); buf.append("\n\tparentID: " + ((parent != null) ? Integer.toHexString(parent.hashCode()) : "")); buf.append("\n\tparentID 2: " + getID(parent)); buf.append("\n\tnode: " + Integer.toHexString(node.hashCode())); buf.append("\n\tnodeID: " + getID(node)); buf.append("\n\tcontentURL: " + getContentURL(item)); buf.append("\n\texpansionType: " + Integer.toString(item.getExpansionType())); return buf.toString(); } /** * Return a string containing the contents of the given Index tree node. */ public String indexTreeToString(DefaultMutableTreeNode node) { // Add Index tree to buffer. if (node == null) { return ("\n\tTree node is null."); } IndexItem item = (IndexItem) node.getUserObject(); if (item == null) { return ("\n\tIndexItem is null."); } DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); StringBuffer buf = new StringBuffer(); buf.append("\n\tname: " + item.getName()); buf.append("\n\thelpID: " + ((item.getID() != null) ? item.getID().id : "")); buf.append("\n\tparentID: " + ((parent != null) ? Integer.toHexString(parent.hashCode()) : "")); buf.append("\n\tparentID 2: " + getID(parent)); buf.append("\n\tnode: " + Integer.toHexString(node.hashCode())); buf.append("\n\tnodeID: " + getID(node)); buf.append("\n\texpansionType: " + Integer.toString(item.getExpansionType())); return buf.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy