www.pudn.com > jsptree-1.0-b6-src.zip > JSPTreeComponent.java


/* 
 * ==================================================================== 
 * The JSP Tree Software License, Version 1.1 
 * 
 * (this license is derived and fully compatible with the Apache Software 
 * License - see http://www.apache.org/LICENSE.txt) 
 * 
 * Copyright (c) 2002-2005 jsptree.sourceforge.net . All rights reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in 
 *    the documentation and/or other materials provided with the 
 *    distribution. 
 * 
 * 3. The end-user documentation included with the redistribution, 
 *    if any, must include the following acknowledgment: 
 *       "This product includes software developed by 
 *        jsptree.sourceforge.net (http://jsptree.sourceforge.net/)." 
 *    Alternately, this acknowledgment may appear in the software itself, 
 *    if and wherever such third-party acknowledgments normally appear. 
 * 
 * 4. The name "JSP Tree" must not be used to endorse or promote 
 *    products derived from this software without prior written permission. 
 *    For written permission, please contact modano@users.sourceforge.net . 
 * 
 * 5. Products derived from this software may not be called "JSP Tree", 
 *    nor may "JSP Tree" appear in their name, without prior written 
 *    permission of jsptree.sourceforge.net. 
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE. 
 * ==================================================================== 
 */ 
 
package net.sf.jsptree.component; 
 
import javax.servlet.ServletContext; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import javax.servlet.jsp.JspTagException; 
import java.io.IOException; 
import java.util.Comparator; 
import java.util.List; 
import java.util.ArrayList; 
 
import org.apache.log4j.Logger; 
 
import net.sf.jsptree.WebWriter; 
import net.sf.jsptree.skin.AbstractSkin; 
import net.sf.jsptree.skin.DefaultSkinFactory; 
import net.sf.jsptree.skin.NodeInfo; 
import net.sf.jsptree.skin.Skin; 
import net.sf.jsptree.template.DeafaultNodeTemplateFactory; 
import net.sf.jsptree.template.NodeTemplate; 
import net.sf.jsptree.template.NodeTemplateFactory; 
import net.sf.jsptree.tree.*; 
 
/** 
 * @author Vladislav Kamensky 
 */ 
public class JSPTreeComponent { 
 
    private static Logger LOG = Logger.getLogger(JSPTreeComponent.class); 
 
    public static final String JSP_TREE_CACHE = "net.sf.jsptree.component.cache"; 
 
    private static final String JSP_TREE_STRUCTURE_CACHE = "net.sf.jsptree.component.structure.cache"; 
 
    private static final String JSP_TREE_STATE_CACHE = "net.sf.jsptree.component.state.cache"; 
 
    private Skin m_skin = DefaultSkinFactory.getInstance().getDefaultSkin(); 
 
    private ServletContext m_context; 
 
    private HttpServletRequest m_request; 
 
    private HttpServletResponse m_response; 
 
    private String m_imgsPath; 
 
    private int m_startAtDepth; 
 
    private String m_name; 
 
    private String m_requestURI; 
 
    private String m_stateManagerAction; 
 
    private int m_maxDepth; 
 
    private TreeFactory m_treeFactory; 
 
    private NodeTemplateFactory m_templateFactory; 
 
    private String m_templatePath; 
 
    private boolean m_shareTreeStructure = false; 
 
    private Comparator m_comparator = null; 
 
    public JSPTreeComponent() { 
        m_imgsPath = "imgs/tree"; 
        m_startAtDepth = 0; 
    } 
 
    public void setName(String p_name) { 
        m_name = p_name; 
    } 
 
    public String getName() { 
        return m_name; 
    } 
 
    public void setRequest(HttpServletRequest p_request) { 
        m_request = p_request; 
        m_requestURI = p_request.getRequestURI().substring(p_request.getRequestURI().lastIndexOf("/") + 1); 
    } 
 
    public void setResponse(HttpServletResponse p_httpServletResponse) { 
        m_response = p_httpServletResponse; 
    } 
 
    public void setContext(ServletContext m_context) { 
        this.m_context = m_context; 
    } 
 
    public String encodeRedirectURL(String p_url) { 
        return m_response.encodeRedirectURL(p_url); 
    } 
 
    public void setTreeFactory(TreeFactory p_treeFactory) { 
        m_treeFactory = p_treeFactory; 
    } 
 
    public TreeFactory getTreeFactory() { 
        return m_treeFactory; 
    } 
 
    public void setXMLTree(String p_pathToXMLTree) throws JspTagException { 
        try { 
            setTreeFactory(XMLTreeFactory.getInstance(p_pathToXMLTree)); 
        } catch (Exception exception) { 
 
            LOG.error("exception while building tree from " + p_pathToXMLTree + ": " + exception.getMessage()); 
            throw new JspTagException("Exception while building tree from XML: " + exception.getMessage()); 
        } 
    } 
 
    public void setSkin(String p_className) throws JspTagException { 
        if (LOG.isInfoEnabled()) { 
            if (!p_className.equalsIgnoreCase(AbstractSkin.DEFAULT_SKIN) 
                    && !p_className.equalsIgnoreCase(AbstractSkin.MENU_SKIN) 
                    && !p_className.equalsIgnoreCase(AbstractSkin.FOLDER_SKIN)) { 
 
                if (LOG.isInfoEnabled()) { 
                    LOG.info("User selected his own skin: " + p_className); 
                } 
            } 
 
        } 
        m_skin = DefaultSkinFactory.getInstance().getSkin(p_className); 
        m_templateFactory.loadTemplates(m_skin.getTemplateNames()); 
    } 
 
    public Skin getSkin() { 
        return m_skin; 
    } 
 
    public void setStartAtDepth(int i) { 
        m_startAtDepth = i; 
    } 
 
    public void setImagesPath(String s) { 
        m_imgsPath = s; 
    } 
 
    public String getImgsPath() { 
        return m_imgsPath; 
    } 
 
    public int getStartAtDepth() { 
        return m_startAtDepth; 
    } 
 
    public String getRequestURI() { 
        return m_requestURI; 
    } 
 
    public String getStateManagerAction() { 
        return m_stateManagerAction; 
    } 
 
    public void setStateManagerAction(String p_stateManagerAction) { 
        m_stateManagerAction = p_stateManagerAction; 
    } 
 
    public String getContextPath() { 
        return m_request.getContextPath(); 
    } 
 
    public void setTemplateFactory(NodeTemplateFactory p_templateFactory) { 
        m_templateFactory = p_templateFactory; 
    } 
 
    public void setTemplatePath(String p_path) { 
        m_templatePath = p_path; 
        m_templateFactory = DeafaultNodeTemplateFactory.getInstance(m_templatePath, m_skin.getTemplateNames()); 
    } 
 
    public void setShareTreeStructure(String p_share) { 
        this.m_shareTreeStructure = Boolean.valueOf(p_share).booleanValue(); 
    } 
 
    public NodeTemplate getTemplate(String p_name) { 
        return m_templateFactory.getTemplate(p_name); 
    } 
 
    public String getTemplatePath() { 
        return m_templatePath; 
    } 
 
    public int getMaxDepth() { 
        return m_maxDepth; 
    } 
 
    public void setComparator(Comparator comparator) { 
        LOG.info("Custom comparator was set:" + comparator.getClass().getName()); 
        this.m_comparator = comparator; 
    } 
 
    private void openNode(Tree tree, String p_openNode) { 
 
        if (p_openNode != null && tree != null) { 
 
            JSPTreeNode a_treeNode = new JSPTreeNodeImpl(p_openNode); 
            tree.openNode(a_treeNode); 
        } 
    } 
 
    private void closeNode(Tree tree, String p_closeNode) { 
 
        if (p_closeNode != null && tree != null) { 
 
            JSPTreeNode a_treeNode = new JSPTreeNodeImpl(p_closeNode); 
            tree.closeNode(a_treeNode); 
        } 
    } 
 
    private void selectNode(Tree tree, String p_openNode) { 
 
        if (p_openNode != null && tree != null) { 
 
            JSPTreeNode a_treeNode = new JSPTreeNodeImpl(p_openNode); 
            tree.selectNode(a_treeNode); 
        } 
    } 
 
    private Tree getTree() throws JspTagException { 
        HttpSession httpSession = m_request.getSession(); 
        if (httpSession == null) { 
            throw new JspTagException("Session is NULL. JSPTree cannot work without a session."); 
        } 
        if (LOG.isDebugEnabled()) { 
            LOG.debug("Getting TreeModel from cache"); 
        } 
        Tree tree = (Tree) httpSession.getAttribute(JSP_TREE_CACHE + "-" + m_name); 
        if (tree == null) { 
            tree = new StatefulTreeModel(getTreeStructure(), getTreeState()); 
            if (LOG.isDebugEnabled()) { 
                LOG.debug("Saving tree to cache"); 
            } 
            httpSession.setAttribute(JSP_TREE_CACHE + "-" + m_name, tree); 
        } 
        return tree; 
    } 
 
    private TreeStructureModel getTreeStructure() throws JspTagException { 
        TreeStructureModel treeStructure = null; 
        if (m_shareTreeStructure) { 
            treeStructure = (TreeStructureModel) m_context.getAttribute(JSP_TREE_STRUCTURE_CACHE + "-" + m_name); 
        } 
        if (treeStructure == null) { 
            if (LOG.isDebugEnabled()) { 
                LOG.debug("Obtaining TreeModel from TreeFactory"); 
            } 
            try { 
                treeStructure = m_treeFactory.getTree(m_name); 
            } catch (TreeFactoryException e) { 
                throw new JspTagException(e.getMessage()); 
            } 
        } 
        if (m_shareTreeStructure) { 
            m_context.setAttribute(JSP_TREE_STRUCTURE_CACHE + "-" + m_name, treeStructure); 
        } 
        return treeStructure; 
    } 
 
    private TreeStateModel getTreeState() throws JspTagException { 
        HttpSession httpSession = m_request.getSession(); 
        if (httpSession == null) { 
            throw new JspTagException("Session is NULL. JSPTree cannot work without a session."); 
        } 
 
        if (LOG.isDebugEnabled()) { 
            LOG.debug("Getting TreeStateModel from cache."); 
        } 
        TreeStateModel stateModel = (TreeStateModel) 
                httpSession.getAttribute(JSP_TREE_STATE_CACHE + "-" + m_name); 
 
        if (stateModel == null) { 
            if (LOG.isDebugEnabled()) { 
                LOG.debug("Obtaining TreeStateModel from TreeFactory"); 
            } 
            try { 
                stateModel = m_treeFactory.getTreeStates(m_name); 
            } catch (TreeFactoryException e) { 
                throw new JspTagException(e.getMessage()); 
            } 
            httpSession.setAttribute(JSP_TREE_STATE_CACHE + "-" + m_name, stateModel); 
        } 
        return stateModel; 
    } 
 
    public void printContent(WebWriter p_webWriter) throws IOException, JspTagException { 
 
        Tree a_tree = getTree(); 
 
        if (LOG.isDebugEnabled()) { 
            LOG.debug("parsing parameters"); 
        } 
 
        if (LOG.isDebugEnabled()) { 
            LOG.debug("obtaining opened nodes parameter"); 
        } 
 
        if (m_request != null) { 
            String openedNode = m_request.getParameter("oNode-" + m_name); 
            openNode(a_tree, openedNode); 
 
            String a_closedNode = m_request.getParameter("cNode-" + m_name); 
            closeNode(a_tree, a_closedNode); 
 
            String a_selectedNode = m_request.getParameter("sNode-" + m_name); 
            selectNode(a_tree, a_selectedNode); 
        } 
 
        this.m_maxDepth = a_tree.getMaxDepth(); 
        TreeNode rootNode = a_tree.getRootNode(); 
 
        if (rootNode != null) { 
            NodeInfo nodeInfo = new NodeInfo(this, rootNode, getTreeState(), p_webWriter); 
            nodeInfo.setLastChild(true); 
            String skinName = ((JSPTreeNode) rootNode.getData()).getSkinName(); 
 
            if (skinName == null) { 
                paint(nodeInfo, m_skin); 
            } else { 
                Skin a_rootSkin = initSkin(skinName); 
                paint(nodeInfo, a_rootSkin); 
            } 
        } 
    } 
 
    private void paint(NodeInfo p_nodeInfo, Skin p_nodeRenderer) 
            throws IOException, JspTagException { 
 
        p_nodeRenderer.paint(p_nodeInfo); 
 
        TreeNode a_treeNode = p_nodeInfo.getNode(); 
        //create new list on the basis of "unmodifiableList" 
        List a_childNodes = new ArrayList(a_treeNode.getChildNodes()); 
        if (m_comparator != null) { 
            java.util.Collections.sort(a_childNodes, m_comparator); 
        } 
 
        if (a_treeNode.hasChildren() && p_nodeInfo.isOpened()) { 
            for (int i = 0; i < a_childNodes.size(); i++) { 
 
                boolean a_lastChild = (i == (a_childNodes.size() - 1)); 
                TreeNode a_treeChildNode = (TreeNode) a_childNodes.get(i); 
                p_nodeInfo.setNode(a_treeChildNode); 
                p_nodeInfo.setLastChild(a_lastChild); 
                String a_skinName = ((JSPTreeNode) a_treeChildNode.getData()).getSkinName(); 
 
                if (a_skinName == null) { 
                    paint(p_nodeInfo, m_skin); 
                } else { 
                    Skin a_nodeSkin = initSkin(a_skinName); 
                    paint(p_nodeInfo, a_nodeSkin); 
                } 
            } 
        } 
    } 
 
    private Skin initSkin(String p_name) { 
        try { 
            Skin a_skin = DefaultSkinFactory.getInstance().getSkin(p_name); 
            m_templateFactory.loadTemplates(a_skin.getTemplateNames()); 
 
            return a_skin; 
        } catch (JspTagException e) { 
            LOG.error("Skin: " + p_name + " can not be loaded.", e); 
            return m_skin; 
        } 
    } 
 
}