package com.idega.content.tree; import java.io.IOException; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.apache.myfaces.custom.tree2.HtmlTree; import org.apache.myfaces.custom.tree2.HtmlTreeRenderer; import org.apache.myfaces.custom.tree2.TreeNode; import org.apache.myfaces.custom.tree2.TreeState; import org.apache.myfaces.custom.tree2.TreeWalker; import org.apache.myfaces.renderkit.html.util.AddResource; import org.apache.myfaces.renderkit.html.util.AddResourceFactory; import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils; import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML; import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils; /** * @author Sean Schofield * @author Chris Barlow * @author Hans Bergsten (Some code taken from an example in his O'Reilly * JavaServer Faces book. Copied with permission) * @version $Revision: 1.6 $ $Date: 2007/10/17 15:05:13 $ */ public class HtmlTreeRendererNew extends HtmlTreeRenderer { private static int node = 0; // private String currentNodeId; public String getNode() { node++; return "node" + node; } public HtmlTreeRendererNew() { } protected void beforeNodeEncode(FacesContext context, ResponseWriter out, HtmlTree tree) throws IOException { out.startElement(HTML.LI_ELEM, tree); out.writeAttribute(HTML.ID_ATTR, tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(), null); /* currentNodeId = */tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(); } protected void afterNodeEncode(FacesContext context, ResponseWriter out) throws IOException { out.endElement(HTML.LI_ELEM); } public void encodeChildren(FacesContext context, UIComponent component) throws IOException { // component.restoreState(context, component); HtmlTree tree = (HtmlTree) component; tree.setShowLines(false); if (!component.isRendered()) return; if (tree.getValue() == null) return; ResponseWriter out = context.getResponseWriter(); String clientId = null; if (component.getId() != null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) { clientId = component.getClientId(context); } boolean isOuterSpanUsed = false; if (clientId != null) { isOuterSpanUsed = true; out.startElement("span", component); // out.writeAttribute("id", clientId, "id"); out.writeAttribute("id", component.getId(), "id"); System.out.println("span Id = " + component.getId()); out.startElement("div", component); out.writeAttribute("id", "div_id_" + component.getId(), "id"); } boolean clientSideToggle = tree.isClientSideToggle(); boolean showRootNode = tree.isShowRootNode(); TreeState state = tree.getDataModel().getTreeState(); TreeWalker walker = tree.getDataModel().getTreeWalker(); walker.reset(); walker.setTree(tree); walker.setCheckState(!clientSideToggle); // walk all nodes in client mode out.startElement(HTML.UL_ELEM, tree); out.writeAttribute(HTML.ID_ATTR, "page_tree_div", null); out.writeAttribute(HTML.CLASS_ATTR, "tree_drag_drop", null); if (showRootNode) { // encode the tree (starting with the root node) if (walker.next()) { encodeRoot(context, out, tree, walker); } } else { TreeNode rootNode = tree.getNode(); String rootNodeId = tree.getNodeId(); if (!state.isNodeExpanded(rootNodeId)) { state.toggleExpanded(rootNodeId); } // now encode each of the nodes in the level immediately below the root for (int i = 0; i < rootNode.getChildCount(); i++) { if (walker.next()) { encodeRoot(context, out, tree, walker); } } } out.endElement(HTML.UL_ELEM); // reset the current node id once we're done encoding everything tree.setNodeId(null); if (isOuterSpanUsed) { out.endElement("div"); out.endElement("span"); } } protected void encodeTree(FacesContext context, ResponseWriter out, HtmlTree tree, TreeWalker walker, TreeNode node) throws IOException { boolean clientSideToggle = tree.isClientSideToggle(); HtmlRendererUtils.writePrettyLineSeparator(context); beforeNodeEncode(context, out, tree); encodeCurrentNode(context, out, tree, node); if (clientSideToggle) { // String spanId = TOGGLE_SPAN + ":" + tree.getId() + ":" + // tree.getNodeId(); out.startElement(HTML.SPAN_ELEM, tree); // out.writeAttribute(HTML.ID_ATTR, spanId, null); out.writeAttribute(HTML.ID_ATTR, tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(), null); // if (tree.isNodeExpanded()) { if (!tree.getDataModel().getNodeById(tree.getNodeId()).isLeaf()) { out.writeAttribute(HTML.STYLE_ATTR, "display:block", null); } else { out.writeAttribute(HTML.STYLE_ATTR, "display:none", null); } } if (tree.getDataModel().getNodeById(tree.getNodeId()).getChildCount() > 0) { out.startElement(HTML.UL_ELEM, tree); } if (tree.getDataModel().getNodeById(tree.getNodeId()).isLeaf()) { if (clientSideToggle) { out.endElement(HTML.SPAN_ELEM); } out.endElement(HTML.LI_ELEM); return; } else { int child_count = tree.getDataModel().getNodeById(tree.getNodeId()).getChildCount(); List children; if (child_count > 0) { children = tree.getDataModel().getNodeById(tree.getNodeId()).getChildren(); for (int i = 0; i < child_count; i++) { node = (TreeNode) children.get(i); walker.next(); encodeTree(context, out, tree, walker, node); } } out.endElement(HTML.UL_ELEM); if (clientSideToggle) { out.endElement(HTML.SPAN_ELEM); } out.endElement(HTML.LI_ELEM); } } protected void encodeRoot(FacesContext context, ResponseWriter out, HtmlTree tree, TreeWalker walker) throws IOException { boolean clientSideToggle = tree.isClientSideToggle(); boolean expanded = false; HtmlRendererUtils.writePrettyLineSeparator(context); out.startElement(HTML.LI_ELEM, tree); out.writeAttribute(HTML.ID_ATTR, tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(), null); out.writeAttribute("noDrag", "true", null); encodeRootNode(context, out, tree); if (clientSideToggle) { // String spanId = TOGGLE_SPAN + ":" + tree.getId() + ":" + // tree.getNodeId(); // String spanId = "spanId2" + // tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(); out.startElement(HTML.SPAN_ELEM, tree); // out.writeAttribute(HTML.ID_ATTR, spanId, null); out.writeAttribute(HTML.ID_ATTR, tree.getDataModel().getNodeById(tree.getNodeId()).getIdentifier(), null); // if (tree.isNodeExpanded()) { if (!tree.getDataModel().getNodeById(tree.getNodeId()).isLeaf()) { out.writeAttribute(HTML.STYLE_ATTR, "display:block", null); } else { out.writeAttribute(HTML.STYLE_ATTR, "display:none", null); } } TreeNode node = tree.getNode(); out.startElement(HTML.UL_ELEM, tree); expanded = true; int child_count = node.getChildCount(); for (int i = 0; i < child_count; i++) { if (walker.next()) { encodeTree(context, out, tree, walker, node); } } if (clientSideToggle) { out.endElement(HTML.SPAN_ELEM); } if (expanded) { out.endElement(HTML.UL_ELEM); } out.endElement(HTML.LI_ELEM); } /** * Handles the encoding related to the navigation functionality. * * @param context * FacesContext * @param out * ResponseWriter * @param tree * HtmlTree * @return The additional navigation image to display inside the node (if * any). Only used with client-side toggle. * @throws IOException */ private String getImageSrc(FacesContext context, UIComponent component, String imageName, boolean withContextPath) { String imageLocation = ((HtmlTree) component).getImageLocation(); AddResource addResource = AddResourceFactory.getInstance(context); // ((HtmlTree)component).setImageLocation("/idegaweb/bundles/com.idega.content.bundle/resources/images/"); if (imageLocation == null) { return addResource.getResourceUri(context, HtmlTreeRenderer.class, "images2/" + imageName, withContextPath); } else { return addResource.getResourceUri(context, imageLocation + "/" + imageName, withContextPath); } } protected void encodeCurrentNode(FacesContext context, ResponseWriter out, HtmlTree tree, TreeNode node) throws IOException { UIComponent nodeTypeFacet = tree.getFacet(node.getType()); if (nodeTypeFacet == null) { throw new IllegalArgumentException("Unable to locate facet with the name: " + node.getType()); } // render node padding /*String[] pathInfo =*/ tree.getPathInformation(tree.getNodeId()); RendererUtils.renderChild(context, nodeTypeFacet); } protected void encodeRootNode(FacesContext context, ResponseWriter out, HtmlTree tree) throws IOException { TreeNode node = tree.getNode(); boolean showRootNode = tree.isShowRootNode(); boolean showLines = tree.isShowLines(); UIComponent nodeTypeFacet = tree.getFacet(node.getType()); if (nodeTypeFacet == null) { throw new IllegalArgumentException("Unable to locate facet with the name: " + node.getType()); } String[] pathInfo = tree.getPathInformation(tree.getNodeId()); int paddingLevel = pathInfo.length - 1; for (int i = (showRootNode ? 0 : 1); i < paddingLevel; i++) { boolean lastChild = tree.isLastChild(pathInfo[i]); String lineSrc = (!lastChild && showLines) ? getImageSrc(context, tree, "line-trunk.gif", true) : getImageSrc(context, tree, "spacer.gif", true); out.startElement(HTML.IMG_ELEM, tree); out.writeURIAttribute(HTML.SRC_ATTR, lineSrc, null); out.endElement(HTML.IMG_ELEM); } RendererUtils.renderChild(context, nodeTypeFacet); } /*private UIComponent encodeNavigation(FacesContext context, ResponseWriter out, HtmlTree tree) throws IOException { TreeNode node = tree.getNode(); String nodeId = tree.getNodeId(); String spanId = TOGGLE_SPAN + ":" + tree.getId() + ":" + nodeId;// TOGGLE_SPAN // + nodeId; boolean showLines = tree.isShowLines(); boolean clientSideToggle = tree.isClientSideToggle(); UIComponent nodeTypeFacet = tree.getFacet(node.getType()); String navSrc = null; String altSrc = null; UIComponent nodeImgFacet = null; int bitMask = NOTHING; // bitMask += (node.isLeaf()) ? NOTHING : CHILDREN; // if (bitMask == CHILDREN) // if there are no children, ignore expand state // -> more flexible with dynamic tree-structures // bitMask += (tree.isNodeExpanded()) ? EXPANDED : NOTHING; // bitMask += (tree.isLastChild(tree.getNodeId())) ? LAST : NOTHING; // bitMask += (showLines) ? LINES : NOTHING; switch (bitMask) { case (NOTHING): case (LAST): navSrc = "spacer.gif"; // space is here // navSrc = "line-middle.gif"; break; case (LINES): navSrc = "line-middle.gif"; break; case (LINES + LAST): navSrc = "line-last.gif"; break; case (CHILDREN): case (CHILDREN + LAST): navSrc = "nav-plus.gif"; altSrc = "nav-minus.gif"; break; case (CHILDREN + LINES): navSrc = "nav-plus-line-middle.gif"; altSrc = "nav-minus-line-middle.gif"; break; case (CHILDREN + LINES + LAST): navSrc = "nav-plus-line-last.gif"; altSrc = "nav-minus-line-last.gif"; break; case (CHILDREN + EXPANDED): case (CHILDREN + EXPANDED + LAST): // is cia ima minusa navSrc = "nav-minus.gif"; altSrc = "nav-plus.gif"; break; case (CHILDREN + EXPANDED + LINES): navSrc = "nav-minus-line-middle.gif"; altSrc = "nav-plus-line-middle.gif"; break; case (CHILDREN + EXPANDED + LINES + LAST): navSrc = "nav-minus-line-last.gif"; altSrc = "nav-plus-line-last.gif"; break; // unacceptable bitmask combinations case (EXPANDED + LINES): case (EXPANDED + LINES + LAST): case (EXPANDED): case (EXPANDED + LAST): throw new IllegalStateException("Encountered a node [" + nodeId + "] + with an illogical state. " + "Node is expanded but it is also considered a leaf (a leaf cannot be considered expanded."); default: // catch all for any other combinations throw new IllegalArgumentException("Invalid bit mask of " + bitMask); } // adjust navSrc and altSrc so that the images can be retrieved using the // extensions filter String navSrcUrl = getImageSrc(context, tree, navSrc, false); navSrc = getImageSrc(context, tree, navSrc, true); altSrc = getImageSrc(context, tree, altSrc, true); // render nav cell // out.startElement(HTML.TD_ELEM, tree); // out.writeAttribute(HTML.WIDTH_ATTR, "19", null); // out.writeAttribute(HTML.HEIGHT_ATTR, "100%", null); // out.writeAttribute("valign", "top", null); if ((bitMask & LINES) != 0 && (bitMask & LAST) == 0) { // out.writeURIAttribute("background", getImageSrc(context, tree, // "line-trunk.gif", true), null); } // add the appropriate image for the nav control // UIGraphic image = new UIGraphic(); // image.setId(IMAGE_PREFIX); // image.setUrl(navSrcUrl); // Map imageAttrs = image.getAttributes(); // imageAttrs.put(HTML.WIDTH_ATTR, "19"); // imageAttrs.put(HTML.HEIGHT_ATTR, "18"); // imageAttrs.put(HTML.BORDER_ATTR, "0"); if (clientSideToggle) { /** * With client side toggle, user has the option to specify open/closed * images for the node (in addition to the navigtion ones provided by the * component.) */ /*String expandImgSrc = ""; String collapseImgSrc = ""; String nodeImageId = ""; UIComponent expandFacet = nodeTypeFacet.getFacet("expand"); if (expandFacet != null) { UIGraphic expandImg = (UIGraphic) expandFacet; expandImgSrc = context.getApplication().getViewHandler().getResourceURL(context, expandImg.getUrl()); if (expandImg.isRendered()) { expandImg.setId(IMAGE_PREFIX + NODE_STATE_EXPANDED); expandImg.setParent(tree); nodeImageId = expandImg.getClientId(context); nodeImgFacet = expandFacet; } } UIComponent collapseFacet = nodeTypeFacet.getFacet("collapse"); if (collapseFacet != null) { UIGraphic collapseImg = (UIGraphic) collapseFacet; collapseImgSrc = context.getApplication().getViewHandler().getResourceURL(context, collapseImg.getUrl()); if (collapseImg.isRendered()) { collapseImg.setId(IMAGE_PREFIX + NODE_STATE_CLOSED); collapseImg.setParent(tree); nodeImageId = collapseImg.getClientId(context); nodeImgFacet = collapseFacet; } } } return nodeImgFacet; }*/ }