/* * Copyright 2006 The National Library of New Zealand * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.webcurator.core.store.tools.tree; import java.io.IOException; import java.util.Iterator; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; /** * This tag is used to support the generic display and management of a * NodeTree. * * @author bbeaumont * */ public class TreeTag extends TagSupport { /** Version ID for serialisation. */ private static final long serialVersionUID = -210301172665342852L; /** The image for spacing */ private static final String IMAGE_EMPTY = "./images/empty.gif"; /** The image for a vertical line */ private static final String IMAGE_JOIN_VERT_LINE = "./images/vertline.gif"; /** The image for the last of a parent's children when that child is a leaf node */ private static final String IMAGE_JOIN_END_WO_CHILDREN = "./images/ic_tree_end.gif"; /** The image for the last of a parent's children when that child has children and is expanded */ private static final String IMAGE_JOIN_END_WITH_CHILDREN_EXP = "./images/ic_tree_end_children_minus.gif"; /** The image for the last of a parent's children when that child has children and is collapsed */ private static final String IMAGE_JOIN_END_WITH_CHILDREN_COL = "./images/ic_tree_end_children_plus.gif"; /** The image for a child leaf node when that child is not the last child of its parent. */ private static final String IMAGE_JOIN_WO_CHILDREN = "./images/ic_tree_mid_no_children.gif"; /** The image for an expanded child node when that child is not the last child of its parent. */ private static final String IMAGE_JOIN_WITH_CHILDREN_EXP = "./images/ic_tree_mid_minus.gif"; /** The image for an collapsed child node when that child is not the last child of its parent. */ private static final String IMAGE_JOIN_WITH_CHILDREN_COL = "./images/ic_tree_mid_plus.gif"; /** The image for a closed folder. */ private static final String IMAGE_FOLDER_CLOSED = "./images/folder.gif"; /** The image for an open folder. */ private static final String IMAGE_FOLDER_OPEN = "./images/folder_open.gif"; /** The image for a resource. */ private static final String IMAGE_RESOURCE = "./images/resource.gif"; /** The tree to be displayed */ private NodeTree tree = null; private int rowAlt = 0; /** * Get the tree. * @return The tree. */ public NodeTree getTree() { return tree; } /** * Set the tree. * @param tree The tree. */ public void setTree(NodeTree tree) { this.tree = tree; } /* (non-Javadoc) * @see javax.servlet.jsp.tagext.Tag#doStartTag() */ @SuppressWarnings("unchecked") public int doStartTag() throws JspException { rowAlt = 0; try { //NodeTree theTree = (NodeTree) ExpressionUtil.evalNotNull("tree", "tree", tree, NodeTree.class, this, pageContext); NodeTree theTree = getTree(); Iterator<Node> rootIterator = theTree.getRootNodes().iterator(); pageContext.getOut().println("<table cellspacing=\"0\" cellpadding=\"0\">"); displayHeader(pageContext.getOut()); while (rootIterator.hasNext()) { display(pageContext.getOut(), rootIterator.next(), 0); } pageContext.getOut().println("</table>"); } catch (IOException ex) { throw new JspException(ex.getMessage(), ex); } // Never process the body. return TagSupport.SKIP_BODY; } /** * Overwrite this method if you want a header row. */ public void displayHeader(JspWriter out) throws IOException { } /** * Write the tree to the output stream. * @param out The output stream. * @param node The node to output. * @param level The level in the hierarchy at which this node sits. * @throws java.io.IOException if there are errors writing the output. */ @SuppressWarnings("unchecked") private void display(JspWriter out, Node node, int level) throws java.io.IOException { // Make sure the line does not wrap. if(rowAlt == 0) { out.print("<tr id=\"row_" + node.getId() + "\" style=\"background-color: #EEEEEE\"><td>"); rowAlt = 1; } else { out.print("<tr id=\"row_" + node.getId() + "\" style=\"background-color: #FFFFFF\"><td>"); rowAlt = 0; } // Pad out to where this element should sit. At each level of padding // we need to choose between displaying a vertical line (in case there // are more children that need to be attached to the tree) or a // blank space. for (int i = 1; i < level; i++) { if (node.getAncestor(i).isLastChild()) { drawImage(out, IMAGE_EMPTY); } else { drawImage(out, IMAGE_JOIN_VERT_LINE); } } if (node.getLevel() != 0) { // If this is the last child of its parents set of ordered children // then we need to use one set of images. if (node.isLastChild()) { if (node.hasChildren()) { out.print("<a id=\"a_" + node.getId()+ "\" href=\"javascript:toggle('" + node.getId() + "')\">"); if (node.isOpen()) { drawImage(out, IMAGE_JOIN_END_WITH_CHILDREN_EXP); } else { drawImage(out, IMAGE_JOIN_END_WITH_CHILDREN_COL); } out.print("</a>"); } else { drawImage(out, IMAGE_JOIN_END_WO_CHILDREN); } } // If this is not the last child of its parents set of ordered children // then we need to use a different set of images. else { if (node.hasChildren()) { out.print("<a id=\"a_" + node.getId()+ "\" href=\"javascript:toggle('" + node.getId() + "')\">"); if (node.isOpen()) { drawImage(out, IMAGE_JOIN_END_WITH_CHILDREN_EXP); } else { drawImage(out, IMAGE_JOIN_END_WITH_CHILDREN_COL); } out.print("</a>"); } else { drawImage(out, IMAGE_JOIN_WO_CHILDREN); } } } // If this is a leaf node (no children) then we display a page icon // to represent the resource. if (node.isLeafNode()) { drawImage(out, IMAGE_RESOURCE); } // If the element does have children, then we need to display and open // or closed folder. else { if (node.isOpen()) { drawImage(out, IMAGE_FOLDER_OPEN); } else { drawImage(out, IMAGE_FOLDER_CLOSED); } } // Output the display name of the node. out.print(" "); out.print("<span id=\"span_" + node.getId()+ "\" onclick=\"javascript:selRow(" + node.getId() + ");\">"); node.getRenderer().renderDisplayName(out, node); out.print("</span>"); out.println("</td>"); displayExtraInfo(out, node); out.println("</tr>"); // Now do the children. if (node.isOpen()) { Iterator<Node> children = node.getChildren().iterator(); while (children.hasNext()) { display(out, children.next(), level + 1); } } } /** * Overwrite this method to display extra columns if desired. * @param out * @param node */ public void displayExtraInfo(JspWriter out, Node node) throws IOException { } /** * Write the HTML for an image to the output stream. * @param out The output stream. * @param image The image to show. * @throws java.io.IOException if there are errors writing to the stream. */ private void drawImage(JspWriter out, String image) throws java.io.IOException { out.print("<img src='"); out.print(image); out .print("' height=16 width=16 border=0 vspace=0 hspace=0 align=left>"); } /* (non-Javadoc) * @see javax.servlet.jsp.tagext.Tag#doEndTag() */ public int doEndTag() throws JspException { return TagSupport.EVAL_PAGE; } }