You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ri...@apache.org on 2005/10/19 07:11:15 UTC
svn commit: r326395 [2/3] - in /beehive/trunk/netui:
src/tags-html/org/apache/beehive/netui/tags/
src/tags-html/org/apache/beehive/netui/tags/rendering/
src/tags-html/org/apache/beehive/netui/tags/tree/
src/util/org/apache/beehive/netui/util/config/bea...
Modified: beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java?rev=326395&r1=326394&r2=326395&view=diff
==============================================================================
--- beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java (original)
+++ beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java Tue Oct 18 22:10:36 2005
@@ -1,607 +1,898 @@
-/*
- * Copyright 2004 The Apache Software Foundation.
- *
- * 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.
- *
- * $Header:$
- */
-package org.apache.beehive.netui.tags.tree;
-
-import org.apache.beehive.netui.util.internal.InternalStringBuilder;
-
-import org.apache.beehive.netui.core.URLCodec;
-import org.apache.beehive.netui.pageflow.PageFlowUtils;
-import org.apache.beehive.netui.pageflow.internal.AdapterManager;
-import org.apache.beehive.netui.pageflow.internal.InternalUtils;
-import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
-import org.apache.beehive.netui.tags.HtmlUtils;
-import org.apache.beehive.netui.tags.html.HtmlConstants;
-import org.apache.beehive.netui.tags.internal.PageFlowTagUtils;
-import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
-import org.apache.beehive.netui.tags.rendering.*;
-import org.apache.beehive.netui.util.Bundle;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.jsp.JspException;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-
-abstract public class TreeRenderer implements HtmlConstants
-{
- private TagRenderingBase _imageRenderer;
- private TagRenderingBase _anchorRenderer;
- private TagRenderingBase _divRenderer;
- private TagRenderingBase _spanRenderer;
-
- private TreeRenderState _trs;
-
- private ImageTag.State _imgState = new ImageTag.State();
- private AnchorTag.State _anchorState = new AnchorTag.State();
- private DivTag.State _divState = new DivTag.State();
- private SpanTag.State _spanState = new SpanTag.State();
-
- private ServletContext _servletContext;
- private HttpServletRequest _req;
- private HttpServletResponse _res;
-
- TreeRenderer(TreeRenderState trs, HttpServletRequest request,
- HttpServletResponse response, ServletContext servletContext)
- {
- _trs = trs;
- _imageRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.IMAGE_TAG, request);
- _anchorRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.ANCHOR_TAG, request);
- _divRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.DIV_TAG, request);
- _spanRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.SPAN_TAG, request);
- _servletContext = servletContext;
- _req = request;
- _res = response;
- }
-
- abstract protected void registerTagError(String message, Throwable e)
- throws JspException;
-
- abstract protected String renderTagId(HttpServletRequest request, String tagId, AbstractHtmlState state);
-
- protected void renderBeforeNode(AbstractRenderAppender writer, TreeElement node)
- {
- }
-
- protected void renderAfterNode(AbstractRenderAppender writer, TreeElement node)
- {
- }
-
- /**
- * This is a recursive method which generates the markup for the tree.
- * @param sb
- * @param node
- * @param level
- * @param attrs
- * @param state
- * @throws javax.servlet.jsp.JspException
- */
- protected void render(InternalStringBuilder sb, TreeElement node, int level, AttributeRenderer attrs,
- InheritableState state)
- throws JspException
- {
- // assert the values...
- assert(sb != null);
- assert(node != null);
-
- String encoding = _res.getCharacterEncoding();
- String nodeName = node.getName();
-
- assert(nodeName != null);
-
- // HACK to take into account special characters like = and &
- // in the node name, could remove this code if encode URL
- // and later request.getParameter() could deal with = and &
- // character in parameter values.
- String encodedNodeName = null;
- try {
- encodedNodeName = URLCodec.encode(nodeName, encoding);
- assert(encodedNodeName != null);
- }
- catch (IOException e) {
- // report the exception and return.
- String s = Bundle.getString("Tags_TreeEncodingError", null);
- registerTagError(s, e);
- return;
- }
-
- // add any attributes to the renderer
- AttributeRenderer.RemoveInfo removes = attrs.addElement(node);
-
- // get the renderers for this tree...
- InternalStringBuilder img = new InternalStringBuilder(32);
-
-
- // Render the beginning of this node
- _divState.clear();
- String tagId = node.getTagId();
- String script = null;
- if (tagId != null) {
- script = renderTagId(_req, tagId, _divState);
- }
- attrs.renderDiv(_divState, node);
- if (_trs.runAtClient) {
- _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_LEVEL, Integer.toString(level));
- }
- sb.append(" ");
- StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb);
- renderBeforeNode(writer, node);
- _divRenderer.doStartTag(writer, _divState);
- sb.append("\n");
- if (script != null)
- sb.append(script);
-
- // In devMode we will verify the structure of the tree. This will not run in
- // production mode.
- ServletContext servletContext = InternalUtils.getServletContext(_req);
- boolean devMode = !AdapterManager.getServletContainerAdapter(servletContext).isInProductionMode();
- if (devMode) {
- boolean error = false;
- InternalStringBuilder errorText = new InternalStringBuilder(64);
- if (node.getName() == null) {
- errorText.append("name");
- error = true;
- }
- if (node.getParent() == null) {
- if (error)
- errorText.append(", ");
- errorText.append("parent");
- }
-
- if (error)
- registerTagError(Bundle.getString("Tags_TreeStructureError", errorText.toString()), null);
- }
-
- // check for tree override properties, the second
- // case here is because the root runs through this an by definitions
- // has InheritableState == state
- InheritableState is = node.getInheritableState();
- if (is != null && is != state) {
- is.setParent(state);
- state = is;
- }
-
- // Create the appropriate number of indents
- // These are either the spacer.gif if the parent is the last in the line or the
- // vertical line gif if the parent is not the last child.
- _imgState.clear();
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, WIDTH, "16px");
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, "", false);
- for (int i = 0; i < level; i++) {
- int levels = level - i;
- TreeElement parent = node;
- for (int j = 1; j <= levels; j++)
- parent = parent.getParent();
-
- img.setLength(0);
- img.append(state.getImageRoot());
- img.append('/');
- if (parent.isLast()) {
- img.append(state.getImageSpacer());
- _imgState.style = null;
- }
- else {
- img.append(state.getVerticalLineImage());
- _imgState.style = "vertical-align:bottom;";
- }
- sb.append(" ");
- _imgState.src = img.toString();
- _imageRenderer.doStartTag(writer, _imgState);
- _imageRenderer.doEndTag(writer);
- sb.append("\n");
- }
-
- // boolean flag that will indicate if there is an open anchor created
- boolean closeAnchor = false;
- if (!_trs.runAtClient)
- closeAnchor = renderExpansionAnchor(sb, _anchorRenderer, node, nodeName, state);
- else {
- // Render client expansion and initialize the tree JavaScript support
- closeAnchor = renderClientExpansionAnchor(sb, _anchorRenderer, node, encodedNodeName, state);
- }
-
- // place the image into the anchor....
- // The type of the image depends upon the position and the type of the node.
- String alt = "";
- img.setLength(0);
- img.append(state.getImageRoot());
- img.append('/');
- if (node.isLeaf()) { // leaf node either last or middle
- if (node.isLast())
- img.append(state.getLastLineJoinImage());
- else
- img.append(state.getLineJoinImage());
- }
- else if (node.isExpanded()) { // interior node that is expanded
- alt = Bundle.getString("Tags_TreeAltTextCollapse", null);
- String rImg = null;
- if (node.getParent() == null && node instanceof ITreeRootElement) {
- rImg = ((ITreeRootElement) node).getRootNodeExpandedImage();
- if (rImg != null) {
- img.append(rImg);
- }
- }
- if (rImg == null) {
- if (node.isLast())
- img.append(state.getLastNodeExpandedImage());
- else
- img.append(state.getNodeExpandedImage());
- }
- }
- else { // interior not expanded
- alt = Bundle.getString("Tags_TreeAltTextExpand", null);
- String rImg = null;
- if (node.getParent() == null && node instanceof ITreeRootElement) {
- rImg = ((ITreeRootElement) node).getRootNodeCollapsedImage();
- if (rImg != null) {
- img.append(rImg);
- }
- }
- if (rImg == null) {
- if (node.isLast())
- img.append(state.getLastNodeCollapsedImage());
- else
- img.append(state.getNodeCollapsedImage());
- }
- }
-
- // write out the image which occurs next to the icon
- if (!closeAnchor)
- sb.append(" ");
-
- _imgState.clear();
- _imgState.src = img.toString();
- _imgState.style = "vertical-align:bottom;";
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, alt, false);
-
- _imageRenderer.doStartTag(writer, _imgState);
- _imageRenderer.doEndTag(writer);
-
- // close the anchor if one was openned...
- if (closeAnchor)
- _anchorRenderer.doEndTag(writer);
- sb.append("\n");
-
- // Calculate the selection link for this node, if the node is disabled, we can skip
- // this because a disabled node may not be selected.
- String selectionLink = null;
- if (!node.isDisabled()) {
-
- // The action on the node overrides all. Otherwise, check to see if there
- // is either an href or clientAction. If neither is set, then we inherit the
- // action defined on the trees inheritable state.
- String action = node.getAction();
- if (action == null) {
- selectionLink = node.getHref();
- if (selectionLink == null && node.getClientAction() != null)
- selectionLink = "";
- if (selectionLink == null)
- action = state.getSelectionAction();
- }
-
- // create the selection link
- if (action != null && selectionLink == null) {
-
- HashMap params = null;
- boolean remove = false;
- params = node.getParams();
- if (params == null) {
- params = new HashMap();
- remove = true;
- }
- params.put(TreeElement.SELECTED_NODE, nodeName);
- if (_trs.tagId != null) {
- params.put(TreeElement.TREE_ID, _trs.tagId);
- }
-
- // Add the jpf ScopeID param if necessary.
- String scope = node.getScope();
- if (scope != null) {
- params.put(ScopedServletUtils.SCOPE_ID_PARAM, scope);
- }
-
- String uri = null;
- try {
- boolean xml = TagRenderingBase.Factory.isXHTML(_req);
- uri = PageFlowUtils.getRewrittenActionURI(_servletContext, _req, _res, action, params, null, xml);
- }
- catch (URISyntaxException e) {
- // report the error...
- String s = Bundle.getString("Tags_Tree_Node_URLException",
- new Object[]{action, e.getMessage()});
- registerTagError(s, e);
- }
-
- if (remove) {
- params.remove(TreeElement.SELECTED_NODE);
- if (_trs.tagId != null) {
- params.remove(TreeElement.TREE_ID);
- }
-
- if (scope != null) {
- params.remove(ScopedServletUtils.SCOPE_ID_PARAM);
- }
- }
-
- if (uri != null) {
- selectionLink = _res.encodeURL(uri);
- }
- }
- }
-
- TagRenderingBase endRender = null;
- // if there is a selection link we need to put an anchor out.
- if (selectionLink != null) {
- _anchorState.clear();
- _anchorState.href = selectionLink;
- String target = node.getTarget();
- if (target == null) {
- target = state.getSelectionTarget();
- }
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, target);
- String title = node.getTitle();
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TITLE, title);
-
- // set the selection styles
- if (node.isSelected()) {
- _anchorState.style = _trs.selectedStyle;
- _anchorState.styleClass = _trs.selectedStyleClass;
- }
- else {
- _anchorState.style = _trs.unselectedStyle;
- _anchorState.styleClass = _trs.unselectedStyleClass;
- }
- if (_anchorState.style == null && _anchorState.styleClass == null) {
- _anchorState.style = "text-decoration: none";
- }
-
- // render any attributes applied to the HTML
- attrs.renderSelectionLink(_anchorState, node);
-
- // render the runAtClient attributes
- if (_trs.runAtClient) {
- String action = node.getClientAction();
- if (action != null) {
- action = HtmlUtils.escapeEscapes(action);
- action = ScriptRequestState.getString("netuiAction", new Object[]{action});
- }
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK, action);
- // Jira 299
- //_anchorState.onClick = action;
- }
-
- // actually render the anchor.
- sb.append(" ");
- _anchorRenderer.doStartTag(writer, _anchorState);
- endRender = _anchorRenderer;
- }
- else {
- // This node doesn's support selection. This means we consider it disabled. We will
- // put a span around it and set the style/class to indicate that it is disabled.
- _spanState.clear();
- _spanState.styleClass = _trs.disabledStyleClass;
- _spanState.style = _trs.disabledStyle;
- sb.append(" ");
- _spanRenderer.doStartTag(writer, _spanState);
- endRender = _spanRenderer;
- }
- sb.append(" ");
-
- // Render the icon for this node, there will always unless the tree turns off default
- // icons by setting the useDefaultIcons attribute to false.
- String icon = node.getIcon();
- if (icon == null) {
- icon = state.getIconRoot() + "/" + state.getItemIcon();
- }
- else {
- icon = state.getIconRoot() + "/" + icon;
- }
-
- // write out the icon
- String label = node.getLabel();
- if (icon != null) {
- _imgState.clear();
- _imgState.src = icon;
- _imgState.style = "vertical-align:text-top";
- alt = null;
- if (label != null && node.isLabelLegalAsAlt())
- alt = label;
- else
- alt = node.getTitle();
- if (alt == null)
- alt = Bundle.getString("Tags_TreeAltText", null);
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, alt, false);
- _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
-
- // set the inheritted attributes
- attrs.renderIconImage(_imgState, node);
- _imageRenderer.doStartTag(writer, _imgState);
- _imageRenderer.doEndTag(writer);
- sb.append(" ");
- }
-
- // Render the label for this node (if any)
- if (label != null) {
- if (_trs.escapeContent) {
- InternalStringBuilder s = new InternalStringBuilder(label.length() + 16);
- StringBuilderRenderAppender sbAppend = new StringBuilderRenderAppender(sb);
- HtmlUtils.filter(label, sbAppend);
- label = s.toString();
- }
- sb.append(label);
- sb.append(" ");
- }
- endRender.doEndTag(writer);
-
- // if there is content then we should render that here...
- String ctnt = node.getContent();
- if (ctnt != null) {
- if (_trs.escapeContent) {
- InternalStringBuilder s = new InternalStringBuilder(ctnt.length() + 16);
- StringBuilderRenderAppender sbAppend = new StringBuilderRenderAppender(sb);
- HtmlUtils.filter(ctnt, sbAppend);
- ctnt = s.toString();
- }
- sb.append("\n ");
- sb.append(ctnt);
- }
-
- // Render the end of this node
- sb.append("\n ");
- _divRenderer.doEndTag(writer);
- sb.append("\n");
- renderAfterNode(writer, node);
-
- // now remove all of the attributes scoped with this...
-
- attrs.removeElementScoped(node, removes);
- // Render the children of this node
- // If the node is expanded we render it
- // If we are runAtClient and the node is Not expandOnServer then render it
- if (node.isExpanded() || (_trs.runAtClient && !node.isExpandOnServer())) {
- TreeElement children[] = node.getChildren();
- int newLevel = level + 1;
- for (int i = 0; i < children.length; i++) {
- render(sb, children[i], newLevel, attrs, state);
- }
- }
- attrs.removeElement(node, removes);
- }
-
- private boolean renderExpansionAnchor(InternalStringBuilder sb, TagRenderingBase anchorRenderer,
- TreeElement node, String nodeName, InheritableState state)
- throws JspException
- {
- // Render the tree state image for this node
- String action = state.getExpansionAction();
- if (action == null) {
- action = state.getSelectionAction();
- }
- boolean isAction = PageFlowTagUtils.isAction(_req, action);
- if (!isAction) {
- registerTagError(Bundle.getString("Tags_BadAction", action), null);
- return false;
- }
-
- // encode the tree parameters into the action.
- HashMap params = new HashMap();
- params.put(TreeElement.EXPAND_NODE, nodeName);
- assert (_trs.tagId != null);
- params.put(TreeElement.TREE_ID, _trs.tagId);
- String uri = null;
- try {
- boolean xml = TagRenderingBase.Factory.isXHTML(_req);
- uri = PageFlowUtils.getRewrittenActionURI(_servletContext, _req, _res, action, params, null, xml);
- }
- catch (URISyntaxException e) {
- // report the error...
- String s = Bundle.getString("Tags_Tree_Node_URLException",
- new Object[]{action, e.getMessage()});
- registerTagError(s, e);
- }
-
- boolean ret = false;
- if ((uri != null) && !node.isLeaf()) {
- _anchorState.clear();
- _anchorState.href = _res.encodeURL(uri);
- sb.append(" ");
- StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb);
- anchorRenderer.doStartTag(writer, _anchorState);
- ret = true;
- }
- return ret;
- }
-
- /**
- * @param sb
- * @param node
- * @param encodedNodeName
- * @return
- */
- private boolean renderClientExpansionAnchor(InternalStringBuilder sb, TagRenderingBase anchorRenderer,
- TreeElement node, String encodedNodeName,
- InheritableState state)
- {
- boolean imgOverride = (state != state.getParent() && state.getParent() != null) ||
- (node.getParent() == null);
-
- if (!node.isLeaf()) {
- boolean expanded = node.isExpanded();
- _anchorState.clear();
- _anchorState.href = "";
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR,
- (expanded ? TreeElement.TREE_EXPAND_STATE : TreeElement.TREE_COLLAPSE_STATE));
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR_INIT, "true");
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR_ID, encodedNodeName);
- if (node.isLast()) {
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_NODE_LAST, "true");
- }
-
- // Does this node have it's images being overridden?
- if (imgOverride) {
- if (node.getParent() == null) {
- String rootImg = ((ITreeRootElement) node).getRootNodeCollapsedImage();
- if (rootImg != null)
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
- state.getImageRoot() + "/" + rootImg);
- else
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
- state.getImageRoot() + "/" + state.getLastNodeCollapsedImage());
- rootImg = ((ITreeRootElement) node).getRootNodeExpandedImage();
- if (rootImg != null)
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
- state.getImageRoot() + "/" + rootImg);
- else
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
- state.getImageRoot() + "/" + state.getLastNodeExpandedImage());
- }
- else if (node.isLast()) {
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
- state.getImageRoot() + "/" + state.getLastNodeCollapsedImage());
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
- state.getImageRoot() + "/" + state.getLastNodeExpandedImage());
- }
- else {
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
- state.getImageRoot() + "/" + state.getNodeCollapsedImage());
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
- state.getImageRoot() + "/" + state.getNodeExpandedImage());
- }
- }
-
- if (node.isExpandOnServer() && !node.isExpanded()) {
- String path = _req.getServletPath();
- int idx = path.lastIndexOf('/');
- if (idx != -1) {
- path = path.substring(1, idx);
- }
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND, "true");
- _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_PATH, path);
- }
-
- sb.append(" ");
- StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb);
- anchorRenderer.doStartTag(writer, _anchorState);
- return true;
- }
- return false;
- }
-}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.tags.tree;
+
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
+
+import org.apache.beehive.netui.core.URLCodec;
+import org.apache.beehive.netui.pageflow.PageFlowUtils;
+import org.apache.beehive.netui.pageflow.internal.AdapterManager;
+import org.apache.beehive.netui.pageflow.internal.InternalUtils;
+import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
+import org.apache.beehive.netui.tags.HtmlUtils;
+import org.apache.beehive.netui.tags.html.HtmlConstants;
+import org.apache.beehive.netui.tags.internal.PageFlowTagUtils;
+import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
+import org.apache.beehive.netui.tags.rendering.*;
+import org.apache.beehive.netui.util.Bundle;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+
+/**
+ * This class renders the HTML markup for the NetUI Tree. The {@link #render} method
+ * recursively renders child nodes of the tree if they're expanded.
+ */
+public class TreeRenderer implements HtmlConstants
+{
+ protected static final String FORMAT_INDENT = " ";
+ protected static final String FORMAT_NBSP = " ";
+ protected static final String FORMAT_NEWLINE = "\n";
+
+ private TagRenderingBase _imageRenderer;
+ private TagRenderingBase _anchorRenderer;
+ private TagRenderingBase _divRenderer;
+ private TagRenderingBase _spanRenderer;
+
+ private ImageTag.State _imgState = new ImageTag.State();
+ private AnchorTag.State _anchorState = new AnchorTag.State();
+ private DivTag.State _divState = new DivTag.State();
+ private SpanTag.State _spanState = new SpanTag.State();
+
+ protected TreeRenderState _trs;
+
+ protected ServletContext _servletContext;
+ protected HttpServletRequest _req;
+ protected HttpServletResponse _res;
+
+ private TreeRenderSupport _treeRenderSupport;
+
+ public void init(TreeRenderState trs, HttpServletRequest request,
+ HttpServletResponse response, ServletContext servletContext)
+ {
+ _trs = trs;
+ _imageRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.IMAGE_TAG, request);
+ _anchorRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.ANCHOR_TAG, request);
+ _divRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.DIV_TAG, request);
+ _spanRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.SPAN_TAG, request);
+ _servletContext = servletContext;
+ _req = request;
+ _res = response;
+ }
+
+ /**
+ * This method is set by the NetUI internals to defined an object that
+ * handles issues specific to rendering a tree for certain paths of
+ * execution in NetUI.
+ * @param treeRenderSupport the class to handle NetUI specific issues while
+ * rendering the tree.
+ */
+ protected void setTreeRenderSupport(TreeRenderSupport treeRenderSupport)
+ {
+ _treeRenderSupport = treeRenderSupport;
+ }
+
+ protected TreeRenderSupport getTreeRenderSupport()
+ {
+ return _treeRenderSupport;
+ }
+
+ protected void registerTagError(String message, Throwable e)
+ throws JspException
+ {
+ _treeRenderSupport.registerTagError(message, e);
+ }
+
+ protected String renderTagId(HttpServletRequest request, String tagId, AbstractHtmlState state)
+ {
+ return _treeRenderSupport.renderTagId(request, tagId, state);
+ }
+
+ protected void renderBeforeNode(AbstractRenderAppender writer, TreeElement node)
+ {
+ _treeRenderSupport.renderBeforeNode(writer, node);
+ }
+
+ protected void renderAfterNode(AbstractRenderAppender writer, TreeElement node)
+ {
+ _treeRenderSupport.renderAfterNode(writer, node);
+ }
+
+ /**
+ * This is a recursive method which generates the markup for the tree.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ * @param level the level or depth of the node within the tree
+ * @param attrs renderer for supported attributes
+ * @param state the set of tree properties that are used to render the tree markup
+ * @throws javax.servlet.jsp.JspException
+ */
+ public void render(AbstractRenderAppender writer, TreeElement node, int level,
+ AttributeRenderer attrs, InheritableState state)
+ throws JspException
+ {
+ // assert the values...
+ assert(writer != null);
+ assert(node != null);
+
+ String nodeName = node.getName();
+ assert(nodeName != null);
+
+ // add any attributes to the renderer
+ AttributeRenderer.RemoveInfo removes = attrs.addElement(node);
+
+ // Render the beginning of this node
+ _divState.clear();
+ String tagId = node.getTagId();
+ String script = null;
+ if (tagId != null) {
+ script = renderTagId(_req, tagId, _divState);
+ }
+ attrs.renderDiv(_divState, node);
+ if (_trs.runAtClient) {
+ _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_LEVEL, Integer.toString(level));
+ }
+ writer.append(" ");
+ renderBeforeNode(writer, node);
+ _divRenderer.doStartTag(writer, _divState);
+ writer.append("\n");
+ if (script != null)
+ writer.append(script);
+
+ // In devMode we will verify the structure of the tree. This will not run in
+ // production mode.
+ ServletContext servletContext = InternalUtils.getServletContext(_req);
+ boolean devMode = !AdapterManager.getServletContainerAdapter(servletContext).isInProductionMode();
+ if (devMode) {
+ boolean error = false;
+ InternalStringBuilder errorText = new InternalStringBuilder(64);
+ if (node.getName() == null) {
+ errorText.append("name");
+ error = true;
+ }
+ if (node.getParent() == null) {
+ if (error)
+ errorText.append(", ");
+ errorText.append("parent");
+ }
+
+ if (error)
+ registerTagError(Bundle.getString("Tags_TreeStructureError", errorText.toString()), null);
+ }
+
+ // check for tree override properties, the second
+ // case here is because the root runs through this an by definitions
+ // has InheritableState == state
+ InheritableState is = node.getInheritableState();
+ if (is != null && is != state) {
+ is.setParent(state);
+ state = is;
+ }
+
+ // write out the images that create the leading indentation for the given node
+ renderIndentation(writer, node, level, state);
+
+ // write out the image which occurs next to the node icon
+ renderConnectionImage(writer, node, nodeName, state);
+
+ // If needed, render the selection link around the icon for this node.
+ // Note that the tag rendered here needs to be closed after the actual
+ // icon and label are rendered.
+ TagRenderingBase endRender = renderSelectionLink(writer, node, nodeName, attrs, state);
+
+ // render the actual icon for this node
+ renderItemIcon(writer, node, attrs, state);
+
+ // render the label for this node (if any)
+ renderLabel(writer, node);
+
+ // now, close the selection link (or span) tag
+ if (endRender != null) {
+ endRender.doEndTag(writer);
+ }
+ renderSelectionLinkSuffix(writer, node);
+
+ // if there is content then we should render that here...
+ renderContent(writer, node);
+
+ // render the end of this node
+ writer.append("\n ");
+ _divRenderer.doEndTag(writer);
+ writer.append("\n");
+ renderAfterNode(writer, node);
+
+ // now remove all of the attributes scoped with this...
+ attrs.removeElementScoped(node, removes);
+
+ // Render the children of this node
+ // If the node is expanded we render it
+ // If we are runAtClient and the node is Not expandOnServer then render it
+ if (node.isExpanded() || (_trs.runAtClient && !node.isExpandOnServer())) {
+ TreeElement children[] = node.getChildren();
+ int newLevel = level + 1;
+ for (int i = 0; i < children.length; i++) {
+ render(writer, children[i], newLevel, attrs, state);
+ }
+ }
+ attrs.removeElement(node, removes);
+ }
+
+ /**
+ * Write out the images that create the leading indentation for the given node.
+ * @param writer the appender where the node indentation images are appended
+ * @param node the node to render
+ * @param level the level or depth of the node within the tree
+ * @param state the set of tree properties that are used to render the tree markup
+ */
+ protected void renderIndentation(AbstractRenderAppender writer, TreeElement node, int level, InheritableState state)
+ {
+ InternalStringBuilder img = new InternalStringBuilder(32);
+
+ // Create the appropriate number of indents
+ // These are either the spacer.gif if the parent is the last in the line or the
+ // vertical line gif if the parent is not the last child.
+ _imgState.clear();
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, WIDTH, "16px");
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, "", false);
+ for (int i = 0; i < level; i++) {
+ int levels = level - i;
+ TreeElement parent = node;
+ for (int j = 1; j <= levels; j++) {
+ parent = parent.getParent();
+ }
+
+ img.setLength(0);
+ img.append(state.getImageRoot());
+ img.append('/');
+ if (parent.isLast()) {
+ renderSpacerPrefix(writer, node);
+ img.append(state.getImageSpacer());
+ _imgState.style = null;
+ }
+ else {
+ renderVerticalLinePrefix(writer, node);
+ img.append(state.getVerticalLineImage());
+ _imgState.style = "vertical-align:bottom;";
+ }
+ _imgState.src = img.toString();
+ _imageRenderer.doStartTag(writer, _imgState);
+ _imageRenderer.doEndTag(writer);
+ if (parent.isLast()) {
+ renderSpacerSuffix(writer, node);
+ }
+ else {
+ renderVerticalLineSuffix(writer, node);
+ }
+ }
+ }
+
+ /**
+ * Write out the image which occurs next to the node icon. This is
+ * usually some kind of connecting line, expand, or collapse image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ * @param nodeName the unique name of the node
+ * @param state the set of tree properties that are used to render the tree markup
+ * @throws JspException
+ */
+ protected void renderConnectionImage(AbstractRenderAppender writer, TreeElement node, String nodeName, InheritableState state)
+ throws JspException
+ {
+ InternalStringBuilder img = new InternalStringBuilder(32);
+
+ // HACK to take into account special characters like = and &
+ // in the node name, could remove this code if encode URL
+ // and later request.getParameter() could deal with = and &
+ // character in parameter values.
+ String encodedNodeName = null;
+ try {
+ encodedNodeName = URLCodec.encode(nodeName, _res.getCharacterEncoding());
+ assert(encodedNodeName != null);
+ }
+ catch (IOException e) {
+ // report the exception and return.
+ String s = Bundle.getString("Tags_TreeEncodingError", null);
+ registerTagError(s, e);
+ return;
+ }
+
+ // boolean flag that will indicate if there is an open anchor created
+ boolean closeAnchor = false;
+ if (!_trs.runAtClient) {
+ closeAnchor = renderExpansionAnchor(writer, _anchorRenderer, node, nodeName, state);
+ }
+ else {
+ // Render client expansion and initialize the tree JavaScript support
+ closeAnchor = renderClientExpansionAnchor(writer, _anchorRenderer, node, encodedNodeName, state);
+ }
+
+ // place the image into the anchor....
+ // The type of the image depends upon the position and the type of the node.
+ String alt = "";
+ img.setLength(0);
+ img.append(state.getImageRoot());
+ img.append('/');
+ if (node.isLeaf()) { // leaf node either last or middle
+ if (node.isLast())
+ img.append(state.getLastLineJoinImage());
+ else
+ img.append(state.getLineJoinImage());
+ }
+ else if (node.isExpanded()) { // interior node that is expanded
+ alt = Bundle.getString("Tags_TreeAltTextCollapse", null);
+ String rImg = null;
+ if (node.getParent() == null && node instanceof ITreeRootElement) {
+ rImg = ((ITreeRootElement) node).getRootNodeExpandedImage();
+ if (rImg != null) {
+ img.append(rImg);
+ }
+ }
+ if (rImg == null) {
+ if (node.isLast())
+ img.append(state.getLastNodeExpandedImage());
+ else
+ img.append(state.getNodeExpandedImage());
+ }
+ }
+ else { // interior not expanded
+ alt = Bundle.getString("Tags_TreeAltTextExpand", null);
+ String rImg = null;
+ if (node.getParent() == null && node instanceof ITreeRootElement) {
+ rImg = ((ITreeRootElement) node).getRootNodeCollapsedImage();
+ if (rImg != null) {
+ img.append(rImg);
+ }
+ }
+ if (rImg == null) {
+ if (node.isLast())
+ img.append(state.getLastNodeCollapsedImage());
+ else
+ img.append(state.getNodeCollapsedImage());
+ }
+ }
+
+ if (!closeAnchor) {
+ renderConnectionImagePrefix(writer, node);
+ }
+
+ // write out the image which occurs next to the icon
+ _imgState.clear();
+ _imgState.src = img.toString();
+ _imgState.style = "vertical-align:bottom;";
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, alt, false);
+
+ _imageRenderer.doStartTag(writer, _imgState);
+ _imageRenderer.doEndTag(writer);
+
+ // close the anchor if one was openned...
+ if (closeAnchor) {
+ _anchorRenderer.doEndTag(writer);
+ }
+ renderConnectionImageSuffix(writer, node);
+ }
+
+ private boolean renderExpansionAnchor(AbstractRenderAppender writer, TagRenderingBase anchorRenderer,
+ TreeElement node, String nodeName, InheritableState state)
+ throws JspException
+ {
+ // Render the tree state image for this node
+ String action = state.getExpansionAction();
+ if (action == null) {
+ action = state.getSelectionAction();
+ }
+ boolean isAction = PageFlowTagUtils.isAction(_req, action);
+ if (!isAction) {
+ registerTagError(Bundle.getString("Tags_BadAction", action), null);
+ return false;
+ }
+
+ // encode the tree parameters into the action.
+ HashMap params = new HashMap();
+ params.put(TreeElement.EXPAND_NODE, nodeName);
+ assert (_trs.tagId != null);
+ params.put(TreeElement.TREE_ID, _trs.tagId);
+ String uri = null;
+ try {
+ boolean xml = TagRenderingBase.Factory.isXHTML(_req);
+ uri = PageFlowUtils.getRewrittenActionURI(_servletContext, _req, _res, action, params, null, xml);
+ }
+ catch (URISyntaxException e) {
+ // report the error...
+ String s = Bundle.getString("Tags_Tree_Node_URLException",
+ new Object[]{action, e.getMessage()});
+ registerTagError(s, e);
+ }
+
+ boolean ret = false;
+ if ((uri != null) && !node.isLeaf()) {
+ _anchorState.clear();
+ _anchorState.href = _res.encodeURL(uri);
+ renderConnectionImagePrefix(writer, node);
+ anchorRenderer.doStartTag(writer, _anchorState);
+ ret = true;
+ }
+ return ret;
+ }
+
+ private boolean renderClientExpansionAnchor(AbstractRenderAppender writer, TagRenderingBase anchorRenderer,
+ TreeElement node, String encodedNodeName,
+ InheritableState state)
+ {
+ boolean imgOverride = (state != state.getParent() && state.getParent() != null) ||
+ (node.getParent() == null);
+
+ if (!node.isLeaf()) {
+ boolean expanded = node.isExpanded();
+ _anchorState.clear();
+ _anchorState.href = "";
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR,
+ (expanded ? TreeElement.TREE_EXPAND_STATE : TreeElement.TREE_COLLAPSE_STATE));
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR_INIT, "true");
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_ANCHOR_ID, encodedNodeName);
+ if (node.isLast()) {
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_NODE_LAST, "true");
+ }
+
+ // Does this node have it's images being overridden?
+ if (imgOverride) {
+ if (node.getParent() == null) {
+ String rootImg = ((ITreeRootElement) node).getRootNodeCollapsedImage();
+ if (rootImg != null)
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
+ state.getImageRoot() + "/" + rootImg);
+ else
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
+ state.getImageRoot() + "/" + state.getLastNodeCollapsedImage());
+ rootImg = ((ITreeRootElement) node).getRootNodeExpandedImage();
+ if (rootImg != null)
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
+ state.getImageRoot() + "/" + rootImg);
+ else
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
+ state.getImageRoot() + "/" + state.getLastNodeExpandedImage());
+ }
+ else if (node.isLast()) {
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
+ state.getImageRoot() + "/" + state.getLastNodeCollapsedImage());
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
+ state.getImageRoot() + "/" + state.getLastNodeExpandedImage());
+ }
+ else {
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_COLLAPSE_IMAGE,
+ state.getImageRoot() + "/" + state.getNodeCollapsedImage());
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_IMAGE,
+ state.getImageRoot() + "/" + state.getNodeExpandedImage());
+ }
+ }
+
+ if (node.isExpandOnServer() && !node.isExpanded()) {
+ String path = _req.getServletPath();
+ int idx = path.lastIndexOf('/');
+ if (idx != -1) {
+ path = path.substring(1, idx);
+ }
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND, "true");
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND_PATH, path);
+ }
+
+ renderConnectionImagePrefix(writer, node);
+ anchorRenderer.doStartTag(writer, _anchorState);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If needed, render the selection link around the icon for this node.
+ * Note that the tag rendered here needs to be closed after the actual
+ * icon and label are rendered.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ * @param nodeName the unique name of the node
+ * @param attrs renderer for supported attributes
+ * @param state the set of tree properties that are used to render the tree markup
+ * @return the selection link (or span) tag renderer to close after the item
+ * icon and label rendered
+ * @throws JspException
+ */
+ protected TagRenderingBase renderSelectionLink(AbstractRenderAppender writer,
+ TreeElement node, String nodeName,
+ AttributeRenderer attrs,
+ InheritableState state)
+ throws JspException
+ {
+ // calculate the selection link for this node
+ String selectionLink = getSelectionlink(node, nodeName, state);
+
+ TagRenderingBase endRender = null;
+ // if there is a selection link we need to put an anchor out.
+ if (selectionLink != null) {
+ _anchorState.clear();
+ _anchorState.href = selectionLink;
+ String target = node.getTarget();
+ if (target == null) {
+ target = state.getSelectionTarget();
+ }
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, target);
+ String title = node.getTitle();
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TITLE, title);
+
+ // set the selection styles
+ if (node.isSelected()) {
+ _anchorState.style = _trs.selectedStyle;
+ _anchorState.styleClass = _trs.selectedStyleClass;
+ }
+ else {
+ _anchorState.style = _trs.unselectedStyle;
+ _anchorState.styleClass = _trs.unselectedStyleClass;
+ }
+ if (_anchorState.style == null && _anchorState.styleClass == null) {
+ _anchorState.style = "text-decoration: none";
+ }
+
+ // render any attributes applied to the HTML
+ attrs.renderSelectionLink(_anchorState, node);
+
+ // render the runAtClient attributes
+ if (_trs.runAtClient) {
+ String action = node.getClientAction();
+ if (action != null) {
+ action = HtmlUtils.escapeEscapes(action);
+ action = ScriptRequestState.getString("netuiAction", new Object[]{action});
+ }
+ _anchorState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK, action);
+ // Jira 299
+ //_anchorState.onClick = action;
+ }
+
+ // actually render the anchor.
+ renderSelectionLinkPrefix(writer, node);
+ _anchorRenderer.doStartTag(writer, _anchorState);
+ endRender = _anchorRenderer;
+ }
+ else {
+ // This node doesn's support selection. This means we consider it disabled. We will
+ // put a span around it and set the style/class to indicate that it is disabled.
+ _spanState.clear();
+ _spanState.styleClass = _trs.disabledStyleClass;
+ _spanState.style = _trs.disabledStyle;
+ renderSelectionLinkPrefix(writer, node);
+ _spanRenderer.doStartTag(writer, _spanState);
+ endRender = _spanRenderer;
+ }
+
+ return endRender;
+ }
+
+ /**
+ * Calculate the selection link for this node, if the node is disabled, we can skip
+ * this because a disabled node may not be selected.
+ * @param node the node to render
+ * @param nodeName the unique name of the node
+ * @param state the set of tree properties that are used to render the tree markup
+ * @return the URL for the selection link
+ * @throws JspException
+ */
+ protected String getSelectionlink(TreeElement node, String nodeName, InheritableState state)
+ throws JspException
+ {
+ String selectionLink = null;
+
+ if (!node.isDisabled()) {
+
+ // The action on the node overrides all. Otherwise, check to see if there
+ // is either an href or clientAction. If neither is set, then we inherit the
+ // action defined on the trees inheritable state.
+ String action = node.getAction();
+ if (action == null) {
+ selectionLink = node.getHref();
+ if (selectionLink == null && node.getClientAction() != null) {
+ selectionLink = "";
+ }
+ if (selectionLink == null) {
+ action = state.getSelectionAction();
+ }
+ }
+
+ // create the selection link
+ if (action != null && selectionLink == null) {
+ HashMap params = null;
+ boolean remove = false;
+ params = node.getParams();
+ if (params == null) {
+ params = new HashMap();
+ remove = true;
+ }
+ params.put(TreeElement.SELECTED_NODE, nodeName);
+ if (_trs.tagId != null) {
+ params.put(TreeElement.TREE_ID, _trs.tagId);
+ }
+
+ // Add the jpf ScopeID param if necessary.
+ String scope = node.getScope();
+ if (scope != null) {
+ params.put(ScopedServletUtils.SCOPE_ID_PARAM, scope);
+ }
+
+ String uri = null;
+ try {
+ boolean xml = TagRenderingBase.Factory.isXHTML(_req);
+ uri = PageFlowUtils.getRewrittenActionURI(_servletContext, _req, _res, action, params, null, xml);
+ }
+ catch (URISyntaxException e) {
+ // report the error...
+ String s = Bundle.getString("Tags_Tree_Node_URLException",
+ new Object[]{action, e.getMessage()});
+ registerTagError(s, e);
+ }
+
+ if (remove) {
+ params.remove(TreeElement.SELECTED_NODE);
+ if (_trs.tagId != null) {
+ params.remove(TreeElement.TREE_ID);
+ }
+
+ if (scope != null) {
+ params.remove(ScopedServletUtils.SCOPE_ID_PARAM);
+ }
+ }
+
+ if (uri != null) {
+ selectionLink = _res.encodeURL(uri);
+ }
+ }
+ }
+ return selectionLink;
+ }
+
+ /**
+ * Render the icon for this node.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ * @param attrs renderer for supported attributes
+ * @param state the set of tree properties that are used to render the tree markup
+ */
+ protected void renderItemIcon(AbstractRenderAppender writer,
+ TreeElement node,
+ AttributeRenderer attrs,
+ InheritableState state)
+ {
+ renderItemIconPrefix(writer, node);
+
+ // There should always be one unless the tree turns off default
+ // icons by setting the useDefaultIcons attribute to false.
+ String icon = node.getIcon();
+ if (icon == null) {
+ icon = state.getIconRoot() + "/" + state.getItemIcon();
+ }
+ else {
+ icon = state.getIconRoot() + "/" + icon;
+ }
+
+ // write out the icon
+ if (icon != null) {
+ _imgState.clear();
+ _imgState.src = icon;
+ _imgState.style = "vertical-align:text-top";
+ String alt = null;
+ String label = node.getLabel();
+ if (label != null && node.isLabelLegalAsAlt())
+ alt = label;
+ else
+ alt = node.getTitle();
+ if (alt == null)
+ alt = Bundle.getString("Tags_TreeAltText", null);
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, alt, false);
+ _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0");
+
+ // set the inheritted attributes
+ attrs.renderIconImage(_imgState, node);
+ _imageRenderer.doStartTag(writer, _imgState);
+ _imageRenderer.doEndTag(writer);
+ renderItemIconSuffix(writer, node);
+ }
+ }
+
+ /**
+ * Render the label for this node (if any).
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderLabel(AbstractRenderAppender writer, TreeElement node)
+ {
+ String label = node.getLabel();
+ if (label != null) {
+ renderLabelPrefix(writer, node);
+ if (_trs.escapeContent) {
+ HtmlUtils.filter(label, writer);
+ }
+ else {
+ writer.append(label);
+ }
+ renderLabelSuffix(writer, node);
+ }
+ }
+
+ /**
+ * Render the Content for this node (if any).
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderContent(AbstractRenderAppender writer, TreeElement node)
+ {
+ String ctnt = node.getContent();
+ if (ctnt != null) {
+ renderContentPrefix(writer, node);
+ if (_trs.escapeContent) {
+ HtmlUtils.filter(ctnt, writer);
+ }
+ else {
+ writer.append(ctnt);
+ }
+ renderContentSuffix(writer, node);
+ }
+ }
+
+ // Methods that control formatting (beautifying) the node markup. Override these to
+ // manage the white space displayed in the page or to add additional markup.
+
+ /**
+ * Render the formatting before a spacer image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderSpacerPrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_INDENT);
+ }
+
+ /**
+ * Render the formatting after a spacer image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderSpacerSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NEWLINE);
+ }
+
+ /**
+ * Render the formatting before a vertical line image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderVerticalLinePrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_INDENT);
+ }
+
+ /**
+ * Render the formatting following a vertical line image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderVerticalLineSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NEWLINE);
+ }
+
+ /**
+ * Render the formatting before the connecting/expand/collapse image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderConnectionImagePrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_INDENT);
+ }
+
+ /**
+ * Render the formatting after the connecting/expand/collapse image.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderConnectionImageSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NEWLINE);
+ }
+
+ /**
+ * Render the formatting before the node selection anchor.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderSelectionLinkPrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_INDENT);
+ }
+
+ /**
+ * Render the formatting after the node selection anchor.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderSelectionLinkSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ }
+
+ /**
+ * Render the formatting before the node icon.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderItemIconPrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NBSP);
+ }
+
+ /**
+ * Render the formatting after the node icon.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderItemIconSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NBSP);
+ }
+
+ /**
+ * Render the formatting before the node label.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderLabelPrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ }
+
+ /**
+ * Render the formatting after the node label.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderLabelSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NBSP);
+ }
+
+ /**
+ * Render the formatting before the node content.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderContentPrefix(AbstractRenderAppender writer, TreeElement node)
+ {
+ writer.append(FORMAT_NEWLINE);
+ writer.append(FORMAT_INDENT);
+ }
+
+ /**
+ * Render the formatting after the node content.
+ * @param writer the appender where the tree markup is appended
+ * @param node the node to render
+ */
+ protected void renderContentSuffix(AbstractRenderAppender writer, TreeElement node)
+ {
+ }
+}
Added: beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRendererFactory.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRendererFactory.java?rev=326395&view=auto
==============================================================================
--- beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRendererFactory.java (added)
+++ beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRendererFactory.java Tue Oct 18 22:10:36 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.tags.tree;
+
+import org.apache.beehive.netui.util.internal.DiscoveryUtils;
+import org.apache.beehive.netui.util.logging.Logger;
+
+import java.io.Serializable;
+
+
+/**
+ * Instantiates a TreeRenderer object that can be used to render the
+ * Tree, writing out the formatting and markup for the Tree elements.
+ *
+ * @see org.apache.beehive.netui.tags.tree.TreeRenderer
+ */
+public class TreeRendererFactory implements Serializable
+{
+ private static final Logger _log = Logger.getInstance(TreeRendererFactory.class);
+
+ /* do not construct */
+ private TreeRendererFactory()
+ {
+ }
+
+ /**
+ * Create an instance of a {@link TreeRenderer} object. This method
+ * creates an instance that provides the NetUI predefined default
+ * implementation for tree rendering.
+ *
+ * @return the default tree renderer object.
+ */
+ public static final TreeRenderer getInstance()
+ {
+ return new TreeRenderer();
+ }
+
+ /**
+ * Create an instance of a {@link TreeRenderer} object given a class
+ * name. The given class must extend the {@link TreeRenderer} base class.
+ *
+ * @param className the name of the TreeRenderer class to instantiate
+ * @return the new {@link TreeRenderer} instance
+ */
+ public static final TreeRenderer getInstance(String className)
+ {
+ TreeRenderer renderer = null;
+ if (className != null) {
+ className = className.trim();
+
+ // create an instance of the def template formatter class
+ ClassLoader cl = DiscoveryUtils.getClassLoader();
+ try {
+ Class rendererClass = cl.loadClass(className);
+ if (!TreeRenderer.class.isAssignableFrom(rendererClass)) {
+ _log.error("The tree renderer class, " + className
+ + ", does not extend TreeRenderer.");
+ }
+ else {
+ renderer = (TreeRenderer) rendererClass.newInstance();
+ }
+ }
+ catch ( ClassNotFoundException e ) {
+ _log.error( "Could not find TreeRenderer class " + className, e );
+ }
+ catch (InstantiationException e) {
+ _log.error( "Could not instantiate TreeRenderer class " + className, e );
+ }
+ catch (IllegalAccessException e) {
+ _log.error( "Could not instantiate TreeRenderer class " + className, e );
+ }
+ }
+ return renderer;
+ }
+}
Propchange: beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRendererFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/bean/JspTagConfig.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/bean/JspTagConfig.java?rev=326395&r1=326394&r2=326395&view=diff
==============================================================================
--- beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/bean/JspTagConfig.java (original)
+++ beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/bean/JspTagConfig.java Tue Oct 18 22:10:36 2005
@@ -24,14 +24,18 @@
private static final DocType DEFAULT_DOC_TYPE = DocType.HTML4_LOOSE_QUIRKS;
private static final IdJavascript DEFAULT_ID_JAVASCRIPT = IdJavascript.DEFAULT;
+ private static final String DEFAULT_TREE_RENDERER_CLASS =
+ "org.apache.beehive.netui.tags.tree.TreeRenderer";
private DocType _docType;
private IdJavascript _idJavascript;
private String _treeImageLocation;
+ private String _treeRendererClass;
public JspTagConfig() {
_docType = DEFAULT_DOC_TYPE;
_idJavascript = DEFAULT_ID_JAVASCRIPT;
+ _treeRendererClass = DEFAULT_TREE_RENDERER_CLASS;
}
public JspTagConfig(DocType docType, IdJavascript idJavascript, String treeImageLocation) {
@@ -46,6 +50,13 @@
_treeImageLocation = treeImageLocation;
}
+ public JspTagConfig(DocType docType, IdJavascript idJavascript, String treeImageLocation, String treeRendererClass) {
+ this(docType, idJavascript, treeImageLocation);
+
+ if(treeRendererClass != null)
+ _treeRendererClass = treeRendererClass;
+ }
+
public DocType getDocType() {
return _docType;
}
@@ -56,5 +67,9 @@
public String getTreeImageLocation() {
return _treeImageLocation;
+ }
+
+ public String getTreeRendererClass() {
+ return _treeRendererClass;
}
}
Modified: beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/parser/NetUIConfigParser.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/parser/NetUIConfigParser.java?rev=326395&r1=326394&r2=326395&view=diff
==============================================================================
--- beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/parser/NetUIConfigParser.java (original)
+++ beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/parser/NetUIConfigParser.java Tue Oct 18 22:10:36 2005
@@ -460,6 +460,7 @@
DocType docType = null;
IdJavascript idJavascript = null;
String treeImageLocation = null;
+ String treeRendererClass = null;
String tmp = null;
Element elem = DomUtils.getChildElementByName(document.getDocumentElement(), "jsp-tag-config");
@@ -488,8 +489,9 @@
}
treeImageLocation = DomUtils.getChildElementText(elem, "tree-image-location");
+ treeRendererClass = DomUtils.getChildElementText(elem, "tree-renderer-class");
- return new JspTagConfig(docType, idJavascript, treeImageLocation);
+ return new JspTagConfig(docType, idJavascript, treeImageLocation, treeRendererClass);
}
private static final PrefixHandlerConfig[] parsePrefixHandlerConfig(Document document) {
Modified: beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/schema/beehive-netui-config.xsd
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/schema/beehive-netui-config.xsd?rev=326395&r1=326394&r2=326395&view=diff
==============================================================================
--- beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/schema/beehive-netui-config.xsd (original)
+++ beehive/trunk/netui/src/util/org/apache/beehive/netui/util/config/schema/beehive-netui-config.xsd Tue Oct 18 22:10:36 2005
@@ -200,6 +200,7 @@
</xsd:simpleType>
</xsd:element>
<xsd:element name="tree-image-location" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="tree-renderer-class" type="xsd:string" minOccurs="0" maxOccurs="1" default=""/>
</xsd:sequence>
</xsd:complexType>
Modified: beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/updateFormFromNested/Controller.jpf
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/updateFormFromNested/Controller.jpf?rev=326395&r1=326394&r2=326395&view=diff
==============================================================================
--- beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/updateFormFromNested/Controller.jpf (original)
+++ beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/updateFormFromNested/Controller.jpf Tue Oct 18 22:10:36 2005
@@ -111,35 +111,3 @@
}
}
-@Jpf.ViewProperties(value = {
- "<!-- This data is auto-generated. Hand-editing this section is not recommended. -->",
- "<view-properties>",
- "<pageflow-object id='pageflow:/miniTests/updateFormFromNested/Controller.jpf'/>",
- "<pageflow-object id='page:index.jsp'><property name='x' value='360'/><property name='y' value='100'/></pageflow-object>",
- "<pageflow-object id='page:results.jsp'><property name='x' value='480'/><property name='y' value='240'/></pageflow-object>",
- "<pageflow-object id='action:submit.do#miniTests.updateFormFromNested.Controller.SubmitForm'><property name='x' value='480'/><property name='y' value='120'/></pageflow-object>",
- "<pageflow-object id='action:getZip.do#miniTests.updateFormFromNested.Controller.SubmitForm'><property name='x' value='60'/><property name='y' value='40'/></pageflow-object>",
- "<pageflow-object id='formbean:java.lang.String'/>",
- "<pageflow-object id='forward:path#success#results.jsp#@action:submit.do#miniTests.updateFormFromNested.Controller.SubmitForm@'/>",
- "<pageflow-object id='return-to:@forward:returnTo#fail#currentPage#@action:submit.do#miniTests.updateFormFromNested.Controller.SubmitForm@@'><property name='x' value='180'/><property name='y' value='160'/></pageflow-object>",
- "<pageflow-object id='forward:returnTo#fail#currentPage#@action:submit.do#miniTests.updateFormFromNested.Controller.SubmitForm@'/>",
- "<pageflow-object id='external-jpf:getZip/GetZip.jpf'><property name='x' value='120'/><property name='y' value='100'/></pageflow-object>",
- "<pageflow-object id='action:zipCancel.do'><property name='x' value='80'/><property name='y' value='60'/></pageflow-object>",
- "<pageflow-object id='action-call:@external-jpf:getZip/GetZip.jpf@#@action:zipCancel.do@'/>",
- "<pageflow-object id='forward:path#getZipFlow#getZip/GetZip.jpf#@action:getZip.do#miniTests.updateFormFromNested.Controller.SubmitForm@'/>",
- "<pageflow-object id='action-call:@page:index.jsp@#@action:submit.do#miniTests.updateFormFromNested.Controller.SubmitForm@'><property name='elbowsX' value='397,420,420,443'/><property name='elbowsY' value='92,92,101,101'/><property name='fromPort' value='East_1'/><property name='toPort' value='West_0'/></pageflow-object>",
- "<pageflow-object id='action-call:@page:index.jsp@#@action:getZip.do#miniTests.updateFormFromNested.Controller.SubmitForm@'><property name='elbowsX' value='323,210,210,97'/><property name='elbowsY' value='92,92,43,43'/><property name='fromPort' value='West_1'/><property name='toPort' value='East_2'/></pageflow-object>",
- "<pageflow-object id='action:begin.do'><property value='80' name='x'/><property value='100' name='y'/></pageflow-object>",
- "<pageflow-object id='action-call:@page:results.jsp@#@action:begin.do@'><property name='elbowsX' value='443,280,280,117'/><property name='elbowsY' value='232,232,103,103'/><property name='fromPort' value='West_1'/><property name='toPort' value='East_2'/></pageflow-object>",
- "<pageflow-object id='action:zipSuccess.do#java.lang.String'><property name='x' value='120'/><property name='y' value='320'/></pageflow-object>",
- "<pageflow-object id='action-call:@external-jpf:getZip/GetZip.jpf@#@action:zipSuccess.do#java.lang.String@'><property name='elbowsX' value='120,120,120,120'/><property name='elbowsY' value='145,210,210,275'/><property name='fromPort' value='South_1'/><property name='toPort' value='North_1'/></pageflow-object>",
- "<pageflow-object id='formbean:SubmitForm'/>",
- "<pageflow-object id='validation-field:zip#@formbean:SubmitForm@'/>",
- "<pageflow-object id='validation-rule:1#{}#@validation-field:zip#@formbean:SubmitForm@@'/>",
- "<pageflow-object id='validation-field:name#@formbean:SubmitForm@'/>",
- "<pageflow-object id='validation-rule:1#{}#@validation-field:name#@formbean:SubmitForm@@'/>",
- "<pageflow-object id='return-to:@forward:returnTo#success#currentPage#@action:zipSuccess.do#java.lang.String@@'><property name='x' value='220'/><property name='y' value='200'/></pageflow-object>",
- "<pageflow-object id='forward:returnTo#success#currentPage#@action:zipSuccess.do#java.lang.String@'><property name='elbowsX' value='157,170,170,183'/><property name='elbowsY' value='312,312,192,192'/><property name='fromPort' value='East_1'/><property name='toPort' value='West_1'/><property name='label' value='success'/></pageflow-object>",
- "</view-properties>"
-})
-interface VIEW_PROPERTIES { }
Added: beehive/trunk/netui/test/webapps/drt/coreWeb/tree/renderer/Controller.jpf
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/test/webapps/drt/coreWeb/tree/renderer/Controller.jpf?rev=326395&view=auto
==============================================================================
--- beehive/trunk/netui/test/webapps/drt/coreWeb/tree/renderer/Controller.jpf (added)
+++ beehive/trunk/netui/test/webapps/drt/coreWeb/tree/renderer/Controller.jpf Tue Oct 18 22:10:36 2005
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package tree.renderer;
+
+import org.apache.beehive.netui.pageflow.PageFlowController;
+import org.apache.beehive.netui.pageflow.annotations.Jpf;
+import org.apache.beehive.netui.pageflow.requeststate.NameService;
+import org.apache.beehive.netui.tags.tree.ITreeRootElement;
+import org.apache.beehive.netui.tags.tree.TreeElement;
+import org.apache.beehive.netui.tags.tree.TreeRenderState;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpSession;
+import org.apache.beehive.netui.pageflow.Forward;
+
+@Jpf.Controller (
+ simpleActions = {
+ @Jpf.SimpleAction(name="postback", navigateTo=Jpf.NavigateTo.currentPage),
+ @Jpf.SimpleAction(name = "select", path = "index.jsp")
+ }
+)
+public class Controller extends PageFlowController
+{
+ private TreeElement _root;
+ private int[] _children = {3,2,0,2,0,2,1,1,2};
+ private int _child = 0;
+
+ public TreeElement getRoot()
+ {
+ return _root;
+ }
+
+ // Tree represented by tags in the JSP
+ TreeElement myJspTree;
+ public TreeElement getMyJspTree()
+ {
+ return this.myJspTree;
+ }
+ public void setMyJspTree(TreeElement myJspTree)
+ {
+ this.myJspTree = myJspTree;
+ }
+
+ @Jpf.Action(
+ forwards={
+ @Jpf.Forward(name="index", path="index.jsp")
+ }
+ )
+ protected Forward begin()
+ {
+ NameService ns = NameService.instance(getRequest().getSession());
+ ns.debugSetNameIntValue(17);
+ return new Forward("index");
+ }
+
+ @Jpf.Action(
+ forwards={
+ @Jpf.Forward(name="index", path="index.jsp")
+ }
+ )
+ protected Forward reset()
+ {
+ _child = 0;
+ myJspTree = null;
+ _root = new ExtTreeRootElement("0", false, getChildCount());
+ return new Forward("index");
+ }
+
+ /**
+ * Callback that is invoked when this controller instance is created.
+ */
+ protected void onCreate()
+ {
+ _root = new ExtTreeRootElement("0", false, getChildCount());
+ }
+
+ /**
+ * Callback that is invoked when this controller instance is destroyed.
+ */
+ protected void onDestroy(HttpSession session)
+ {
+ }
+
+ private int getChildCount()
+ {
+ if (_child == _children.length)
+ return 0;
+ return _children[_child++];
+ }
+
+ class ExtTreeElement extends TreeElement
+ {
+ private boolean _leaf;
+ private int _children;
+
+ public ExtTreeElement(String s, boolean b, int children)
+ {
+ super(s, b);
+ _leaf = (children == 0);
+ _children = children;
+ setExpandOnServer(!_leaf);
+ }
+
+ public void onExpand(ServletRequest request, ServletResponse response)
+ {
+ if (_children > 0 && size() == 0) {
+ for (int i=0;i<_children;i++) {
+ String name = getLabel() + "." + i;
+ ExtTreeElement m = new ExtTreeElement(name, false, getChildCount());
+ addChild(m);
+ }
+ }
+ }
+
+ public boolean isLeaf()
+ {
+ return _leaf;
+ }
+ }
+
+ class ExtTreeRootElement extends ExtTreeElement implements ITreeRootElement
+ {
+ private String _name = null;
+ private TreeRenderState _trs = null;
+ private TreeElement _selectedNode;
+ private String _rootNodeExpandedImage;
+ private String _rootNodeCollapsedImage;
+
+ public ExtTreeRootElement(String s, boolean b, int children)
+ {
+ super(s, b, children);
+ }
+
+ public TreeElement getSelectedNode()
+ {
+ return _selectedNode;
+ }
+
+ public void changeSelected(String selectNode,ServletRequest request)
+ {
+ // if there is a selectedNode then we need to raise the onSelect
+ // event on that node indicating it will soon not be selected
+ TreeElement n = findNode(selectNode);
+ if (n == null) {
+ return;
+ }
+
+ // change the node that was selected so it is no longer selected
+ if (_selectedNode != null) {
+ _selectedNode.onSelect(request);
+ _selectedNode.setSelected(false);
+ }
+
+ // change the node that is to be selected
+ n.onSelect(request);
+ n.setSelected(true);
+ _selectedNode = n;
+ return;
+ }
+
+ public TreeRenderState getTreeRenderState()
+ {
+ return _trs;
+ }
+
+ public void setTreeRenderState(TreeRenderState treeRenderState)
+ {
+ _trs = treeRenderState;
+ }
+
+ public void setObjectName(String s)
+ {
+ _name = s;
+ }
+
+ public String getObjectName()
+ {
+ return _name;
+ }
+
+ public String getRootNodeExpandedImage()
+ {
+ return _rootNodeExpandedImage;
+ }
+
+ public void setRootNodeExpandedImage(String rootNodeExpandedImage)
+ {
+ _rootNodeExpandedImage = rootNodeExpandedImage;
+ }
+
+ public String getRootNodeCollapsedImage()
+ {
+ return _rootNodeCollapsedImage;
+ }
+
+ public void setRootNodeCollapsedImage(String rootNodeCollapsedImage)
+ {
+ _rootNodeCollapsedImage = rootNodeCollapsedImage;
+ }
+ }
+}
+
+
+
Propchange: beehive/trunk/netui/test/webapps/drt/coreWeb/tree/renderer/Controller.jpf
------------------------------------------------------------------------------
svn:eol-style = native