Author: dolander Date: Sat Jan 29 07:37:17 2005 New Revision: 149049 URL: http://svn.apache.org/viewcvs?view=rev&rev=149049 Log: This checkin lays a bunch of the ground work for allowing runAtClient trees to do expandOnServer. ExpandOnServer will allow a tree node to be expanded on the server and an XML document containing the children nodes passed back to the client during the XmlHttpRequest call.
- Moved the tree rendering out of the Tree tag an put it into an Abstract class TreeRenderer. - Created the TagTreeRenderer class which is used by the Tree tag to render the tree. - Added the ServletResponse and ServletContext to the ServletIntereceptorContext - Added code the the Tree Interceptor to begin creating the XML document Added: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TagTreeRenderer.java incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderState.java incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/expandOnServer.jsp Modified: incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp Modified: incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js&r1=149048&p2=incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js (original) +++ incubator/beehive/trunk/netui/src/javascript/tagshtml/netui-tree.js Sat Jan 29 07:37:17 2005 @@ -77,10 +77,13 @@ // @param command this is the command name, it is a simple String // @param treeName this name of the tree // @param nodeName this is the node to apply the command to -NetUITree.prototype.getTreeCommandUrl = function(command,treeName,nodeName) +NetUITree.prototype.getTreeCommandUrl = function(command,treeName,nodeName,expandOnServer) { var url = netUI.webAppName + "/" + command + NetUI.prototype.xmlHttpRequestMapping + "?tree=" + treeName + "&node=" + nodeName; + if (expandOnServer == "true") { + url = url + "&expandOnServer=true"; + } return url; } @@ -94,7 +97,9 @@ var func = function() { if (req.readyState==4) { if (req.status == 200) { - callback(req); + if (req.responseXML!=null) { + callback(req); + } } else { reportError("Unable to retrieve XML data:" + req.statusText); @@ -120,8 +125,13 @@ } } -function NetUITreeXmlHttpRequestReturn() +// If the XmlHttpRequest results in a valid XML document, this will be called +function NetUITreeXmlHttpRequestReturn(req) { + var x = req.responseXML.getElementsByTagName("node"); + if (x == null || x.length == 0) + return; + alert(x[0].childNodes[0].nodeValue); } function NetUIExpandTree() @@ -134,7 +144,8 @@ // change in the client state. var treeName = netUI.netUITree.getTreeName(this); var nodeName = this.getAttribute("netui-tree-id"); - var url = netUI.netUITree.getTreeCommandUrl("treeExpand",treeName,nodeName); + var expandOnServer = this.getAttribute("netui:expandOnServer"); + var url = netUI.netUITree.getTreeCommandUrl("treeExpand",treeName,nodeName,expandOnServer); netUI.raiseCommand(url,NetUITreeXmlHttpRequestReturn); // find the image child so we can change the image @@ -192,7 +203,7 @@ if (raiseCommand) { var treeName = netUI.netUITree.getTreeName(node); var nodeName = node.getAttribute("netui-tree-id"); - var url = netUI.netUITree.getTreeCommandUrl("treeCollapse",treeName,nodeName); + var url = netUI.netUITree.getTreeCommandUrl("treeCollapse",treeName,nodeName,"false"); netUI.raiseCommand(url,NetUITreeXmlHttpRequestReturn); } Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java&r1=149048&p2=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/ServletInterceptorContext.java Sat Jan 29 07:37:17 2005 @@ -18,6 +18,8 @@ package org.apache.beehive.netui.pageflow.requeststate; import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.ServletContext; /** * @@ -25,12 +27,26 @@ public class ServletInterceptorContext extends InterceptorContext { private ServletRequest _request; - public ServletInterceptorContext(ServletRequest request) + private ServletResponse _response; + private ServletContext _context; + + public ServletInterceptorContext(ServletRequest request,ServletResponse response,ServletContext context) { _request = request; + _response = response; + _context = context; } public ServletRequest getRequest() { return _request; } + + public ServletResponse getResponse() { + return _response; + } + + public ServletContext getServletConteext() { + return _context; + } } + Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java&r1=149048&p2=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/xmlhttprequest/XmlHttpRequestServlet.java Sat Jan 29 07:37:17 2005 @@ -76,7 +76,7 @@ if (_interceptors == null || _interceptors.size() == 0) return; - ServletInterceptorContext ctxt = new ServletInterceptorContext(request); + ServletInterceptorContext ctxt = new ServletInterceptorContext(request,response,getServletContext()); for (IRequestInterceptor i : _interceptors) i.interceptRequest(ctxt); } Added: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TagTreeRenderer.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TagTreeRenderer.java?view=auto&rev=149049 ============================================================================== --- (empty file) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TagTreeRenderer.java Sat Jan 29 07:37:17 2005 @@ -0,0 +1,30 @@ +package org.apache.beehive.netui.tags.tree; + +import org.apache.beehive.netui.tags.rendering.AbstractHtmlState; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.jsp.JspException; + +class TagTreeRenderer extends TreeRenderer +{ + private Tree _tree; + + TagTreeRenderer(Tree tree,TreeRenderState trs,InheritableState iState,HttpServletRequest request,ServletContext servletContext) + { + super(trs,iState,request,servletContext); + _tree = tree; + } + + protected void registerTagError(String message, Throwable e) + throws JspException + { + _tree.registerTagError(message,e); + } + + protected String renderTagId(HttpServletRequest request, String tagId, AbstractHtmlState state) + { + return _tree.renderTagId(request,tagId,state); + } + +} Modified: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java&r1=149048&p2=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java (original) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/Tree.java Sat Jan 29 07:37:17 2005 @@ -17,32 +17,29 @@ */ package org.apache.beehive.netui.tags.tree; -import org.apache.beehive.netui.core.URLCodec; -import org.apache.beehive.netui.core.urls.MutableURI; -import org.apache.beehive.netui.pageflow.internal.AdapterManager; -import org.apache.beehive.netui.pageflow.internal.InternalUtils; import org.apache.beehive.netui.pageflow.requeststate.INameable; import org.apache.beehive.netui.pageflow.requeststate.NameService; -import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils; import org.apache.beehive.netui.script.ExpressionUpdateException; import org.apache.beehive.netui.script.IllegalExpressionException; -import org.apache.beehive.netui.tags.*; +import org.apache.beehive.netui.tags.AbstractSimpleTag; +import org.apache.beehive.netui.tags.ExpressionHandling; +import org.apache.beehive.netui.tags.IErrorCollector; +import org.apache.beehive.netui.tags.TagConfig; import org.apache.beehive.netui.tags.html.HtmlConstants; -import org.apache.beehive.netui.tags.internal.PageFlowTagUtils; import org.apache.beehive.netui.tags.javascript.CoreScriptFeature; import org.apache.beehive.netui.tags.javascript.IScriptReporter; import org.apache.beehive.netui.tags.javascript.ScriptRequestState; -import org.apache.beehive.netui.tags.rendering.*; +import org.apache.beehive.netui.tags.rendering.AbstractHtmlState; +import org.apache.beehive.netui.tags.rendering.DivTag; +import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender; +import org.apache.beehive.netui.tags.rendering.TagRenderingBase; 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 javax.servlet.jsp.PageContext; import java.io.IOException; -import java.net.URISyntaxException; -import java.util.HashMap; /** @@ -106,38 +103,28 @@ */ private TreeElement _rootNode = null; + private TreeRenderState _trs; + // The new style and class attributes - private String _selectionStyle; // selection style - private String _selectionClass; // selection class - private String _unselectStyle; // unselect style - private String _unselectClass; // unselect class - private String _disabledStyle; // disabled style - private String _disabledClass; // disabled class private String _treeStyle; // tree style private String _treeClass; // tree class private StringBuilder _errorText; // Text of any error that may have occurred. private String _dataSource = null; // The name of the tree. - - private String _tagId; // tag that should uniquely indentify a tree. Required for multiple tree using auto expand - private boolean _runAtClient = false; // run at client - private boolean _escapeContent = false; // esapce the content of labels private boolean _outputJavaScript = false; // cause the base javascript support to be output private InheritableState _iState = new InheritableState(); // These are used in a stateless manner. They do not have to be cleared // in the local release because each state is cleared before it is set to write a start tag. - 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 ExpressionHandling _expr; public Tree() { + _trs = new TreeRenderState(); _iState.initalizeTreeState(); } @@ -208,7 +195,7 @@ public void setTagId(String tagId) throws JspException { - _tagId = setRequiredValueAttribute(tagId, "tagId"); + _trs.tagId = setRequiredValueAttribute(tagId, "tagId"); } /** @@ -387,7 +374,7 @@ */ public void setRunAtClient(boolean runAtClient) { - _runAtClient = runAtClient; + _trs.runAtClient = runAtClient; } /** @@ -399,7 +386,7 @@ */ public void setEscapeForHtml(boolean htmlEscape) { - _escapeContent = htmlEscape; + _trs.escapeContent = htmlEscape; } /** @@ -443,7 +430,7 @@ */ public void setSelectionStyle(String selectionStyle) { - _selectionStyle = setNonEmptyValueAttribute(selectionStyle); + _trs.selectionStyle = setNonEmptyValueAttribute(selectionStyle); } /** @@ -458,7 +445,7 @@ public void setDisableClass(String disableClass) { - _disabledClass = setNonEmptyValueAttribute(disableClass); + _trs.disabledClass = setNonEmptyValueAttribute(disableClass); } /** @@ -472,7 +459,7 @@ */ public void setDisabledStyle(String disabledStyle) { - _disabledStyle = setNonEmptyValueAttribute(disabledStyle); + _trs.disabledStyle = setNonEmptyValueAttribute(disabledStyle); } /** @@ -486,7 +473,7 @@ */ public void setSelectionClass(String selectionClass) { - _selectionClass = setNonEmptyValueAttribute(selectionClass); + _trs.selectionClass = setNonEmptyValueAttribute(selectionClass); } /** @@ -500,7 +487,7 @@ */ public void setUnselectStyle(String unselectStyle) { - _unselectStyle = setNonEmptyValueAttribute(unselectStyle); + _trs.unselectStyle = setNonEmptyValueAttribute(unselectStyle); } /** @@ -514,7 +501,7 @@ */ public void setUnselectClass(String unselectClass) { - _unselectClass = setNonEmptyValueAttribute(unselectClass); + _trs.unselectClass = setNonEmptyValueAttribute(unselectClass); } /** @@ -633,7 +620,7 @@ // if we are running the tree at the client, then // we need to register the tree with the NameService - if (_runAtClient && treeRoot instanceof INameable) { + if (_trs.runAtClient && treeRoot instanceof INameable) { NameService ns = NameService.instance(pageContext.getSession()); ns.nameObject("Tree", (INameable) treeRoot); ns.put((INameable) treeRoot); @@ -642,7 +629,7 @@ // it's currently not legal to have a runAtClient but not be an instance of INameable which is // implemented by the ITreeRootElement. - if (_runAtClient && (!(treeRoot instanceof INameable))) { + if (_trs.runAtClient && (!(treeRoot instanceof INameable))) { String s = Bundle.getString("Tags_TreeRunAtClientRoot", null); registerTagError(s, null); reportErrors(); @@ -658,18 +645,18 @@ // this is the treeId from the request. If there was an tree expansion this will be // non-null and it identifies what tree had the expansion request. // we need to qualify the tree based upon the tagId - assert(_tagId != null); - _tagId = getIdForTagId(_tagId); + assert(_trs.tagId != null); + _trs.tagId = getIdForTagId(_trs.tagId); String treeId = request.getParameter(TreeElement.TREE_ID); - if (treeId != null && _tagId.equals(treeId)) { + if (treeId != null && _trs.tagId.equals(treeId)) { TreeHelpers.processTreeRequest(treeId, treeRoot, request); } // check for the nodes that are expanded... // Add the script support for the tree. - if (_runAtClient) { + if (_trs.runAtClient) { IScriptReporter sr = getScriptReporter(); ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request); if (!srs.isFeatureWritten(CoreScriptFeature.DYNAMIC_INIT)) { @@ -687,12 +674,12 @@ _divState.style = _treeStyle; String divId = null; if (_outputJavaScript) { - _divState.id = _tagId; + _divState.id = _trs.tagId; divId = _divState.id; } // if we are running on the client then we need to output the tree name into the top level tree <div> tag - if (_runAtClient) { + if (_trs.runAtClient) { _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, "netui:treeName", ((INameable) treeRoot).getObjectname()); } @@ -702,7 +689,8 @@ // Render the tree. AttributeRenderer extraAttrs = new AttributeRenderer(); - render(sb, request, response, treeRoot, 0, extraAttrs, _iState); + TagTreeRenderer ttr = new TagTreeRenderer(this,_trs,_iState,request,pageContext.getServletContext()); + ttr.render(sb, request, response, treeRoot, 0, extraAttrs, _iState); if (hasErrors()) { reportErrors(); return; @@ -744,425 +732,6 @@ } /** - * This is a recursive method which generates the markup for the tree. - * @param sb - * @param request - * @param response - * @param node - * @param level - * @param attrs - * @param state - * @throws JspException - */ - protected void render(StringBuilder sb, HttpServletRequest request, HttpServletResponse response, - TreeElement node, int level, AttributeRenderer attrs, InheritableState state) - throws JspException - { - // assert the values... - assert(sb != null); - assert(request != null); - assert(response != null); - assert(node != null); - - String encoding = response.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... - StringBuilder img = new StringBuilder(32); - TagRenderingBase imageRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.IMAGE_TAG, request); - TagRenderingBase anchorRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.ANCHOR_TAG, request); - TagRenderingBase divRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.DIV_TAG, request); - TagRenderingBase spanRenderer = TagRenderingBase.Factory.getRendering(TagRenderingBase.SPAN_TAG, request); - - - // Render the beginning of this node - _divState.clear(); - String tagId = node.getTagId(); - String script = null; - if (tagId != null) { - script = renderTagId(request, tagId, _divState); - } - attrs.renderDiv(_divState, node); - if (_runAtClient) { - _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, "netui-tree-level", Integer.toString(level)); - } - sb.append(" "); - StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb); - 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(request); - boolean devMode = !AdapterManager.getServletContainerAdapter(servletContext).isInProductionMode(); - if (devMode) { - boolean error = false; - StringBuilder errorText = new StringBuilder(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 - InheritableState is = node.getInheritableState(); - if (is != null) { - 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.getImageLineVertical()); - _imgState.style = "vertical-align:middle;"; - } - 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 (!_runAtClient) - closeAnchor = renderExpansionAnchor(sb, anchorRenderer, request, response, node, nodeName); - else { - // Render client expansion and initialize the tree JavaScript support - closeAnchor = renderClientExpansionAnchor(sb, anchorRenderer, node, encodedNodeName); - } - - // place the image into the anchor.... - // The type of the image depends upon the position and the type of the node. - img.setLength(0); - img.append(state.getImageRoot()); - img.append('/'); - if (node.isLeaf()) { // leaf node either last or middle - if (node.isLast()) - img.append(state.getImageLineLast()); - else - img.append(state.getImageLineMiddle()); - } - else if (node.isExpanded()) { // interior node that is expanded - if (node.isLast()) - img.append(state.getImageHandleDownLast()); - else - img.append(state.getImageHandleDownMiddle()); - } - else { // interior not expanded - if (node.isLast()) - img.append(state.getImageHandleRightLast()); - else - img.append(state.getImageHandleRightMiddle()); - } - - // write out the image which occurs next to the icon - if (!closeAnchor) - sb.append(" "); - - _imgState.clear(); - _imgState.src = img.toString(); - _imgState.style = "vertical-align:middle;"; - _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0"); - _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, 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(); - } - - // process the action into a URL - PageContext pageContext = getPageContext(); - if (action != null && selectionLink == null) { - HashMap params = new HashMap(); - params.put(TreeElement.SELECTED_NODE, nodeName); - if (_tagId != null) { - params.put(TreeElement.TREE_ID, _tagId); - } - - // Add the jpf ScopeID param if necessary. - String scope = node.getScope(); - if (scope != null) { - params.put(ScopedServletUtils.SCOPE_ID_PARAM, scope); - } - - MutableURI uri = null; - try { - uri = PageFlowTagUtils.rewriteActionURL(pageContext, action, params, null); - } - catch (URISyntaxException e) { - // report the error... - String s = Bundle.getString("Tags_Tree_Node_URLException", - new Object[]{action, e.getMessage()}); - registerTagError(s, e); - } - - if (uri != null) { - selectionLink = response.encodeURL(uri.toString()); - } - } - } - - TagRenderingBase endRender = null; - // if there is a selection link we need to put an anchor out. - if (selectionLink != null) { - _anchorState.clear(); - _anchorState.href = selectionLink; - _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, node.getTarget()); - - // set the selection styles - if (node.isSelected()) { - _anchorState.style = _selectionStyle; - _anchorState.styleClass = _selectionClass; - } - else { - _anchorState.style = _unselectStyle; - _anchorState.styleClass = _unselectClass; - } - - // render any attributes applied to the HTML - attrs.renderIconLink(_anchorState, node); - - // render the runAtClient attributes - if (_runAtClient) { - String action = node.getClientAction(); - if (action != null) { - action = HtmlUtils.escapeEscapes(action); - action = ScriptRequestState.getString("netuiAction", new Object[]{action}); - } - _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 = _disabledClass; - _spanState.style = _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.getImageRoot() + "/" + state.getDefaultIcon(); - } - else { - icon = state.getImageRoot() + "/" + icon; - } - - // write out the icon - if (icon != null) { - _imgState.clear(); - _imgState.src = icon; - _imgState.style = "vertical-align:middle"; - String 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) - String label = node.getLabel(); - if (label != null) { - if (_escapeContent) { - StringBuilder s = new StringBuilder(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 (_escapeContent) { - StringBuilder s = new StringBuilder(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"); - - // now remove all of the attributes scoped with this... - - attrs.removeElementScoped(node, removes); - // Render the children of this node - if (_runAtClient || node.isExpanded()) { - TreeElement children[] = node.getChildren(); - int newLevel = level + 1; - for (int i = 0; i < children.length; i++) { - render(sb, request, response, children[i], newLevel, attrs, state); - } - } - attrs.removeElement(node, removes); - } - - private boolean renderExpansionAnchor(StringBuilder sb, TagRenderingBase anchorRenderer, - HttpServletRequest request, HttpServletResponse response, - TreeElement node, String nodeName) - throws JspException - { - // Render the tree state image for this node - PageContext pageContext = getPageContext(); - String action = _iState.getExpansionAction(); - if (action == null) { - action = _iState.getSelectionAction(); - } - boolean isAction = PageFlowTagUtils.isAction(request, 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 (_tagId != null); - params.put(TreeElement.TREE_ID, _tagId); - MutableURI uri = null; - try { - uri = PageFlowTagUtils.rewriteActionURL(pageContext, action, params, null); - } - 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 = response.encodeURL(uri.toString()); - _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, _iState.getExpandTarget()); - 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(StringBuilder sb, TagRenderingBase anchorRenderer, - TreeElement node, String encodedNodeName) - { - 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_ID, encodedNodeName); - - sb.append(" "); - StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb); - anchorRenderer.doStartTag(writer, _anchorState); - return true; - } - return false; - } - - /** * Replace any occurrence of the specified placeholder in the specified * template string with the specified replacement value. * @param template Pattern string possibly containing the placeholder @@ -1199,7 +768,7 @@ */ protected final String renderTagId(HttpServletRequest request, String tagId, AbstractHtmlState state) { - assert(_tagId != null); + assert(_trs.tagId != null); state.id = getIdForTagId(tagId); String script = renderDefaultJavaScript(request, state.id); return script; @@ -1229,7 +798,7 @@ // map the tagId to the real id if (TagConfig.isDefaultJavaScript()) { ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request); - idScript = srs.mapTagId(getScriptReporter(), _tagId, realId, null); + idScript = srs.mapTagId(getScriptReporter(), _trs.tagId, realId, null); } return idScript; } Modified: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java&r1=149048&p2=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java (original) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeCRI.java Sat Jan 29 07:37:17 2005 @@ -18,20 +18,31 @@ package org.apache.beehive.netui.tags.tree; import org.apache.beehive.netui.pageflow.requeststate.*; +import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender; +import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletResponse; +import javax.servlet.jsp.JspWriter; +import java.io.IOException; +import java.io.Writer; public class TreeCRI implements IRequestInterceptor { private static final String TREE_COLLAPSE = "treeCollapse"; private static final String TREE_EXPAND = "treeExpand"; + // The elements we will create in the document + private static final String TREE_EXPAND_ELEM = "treeExpand"; + public void interceptRequest(InterceptorContext ctxt) { if (!(ctxt instanceof ServletInterceptorContext)) return; HttpServletRequest request = (HttpServletRequest) ((ServletInterceptorContext) ctxt).getRequest(); + ServletResponse response = ((ServletInterceptorContext) ctxt).getResponse(); // Create the command by striping off the context path and the extension String cmd = request.getRequestURI(); @@ -51,20 +62,21 @@ // check to see if we handle this command if (TREE_COLLAPSE.equals(cmd)) { - handleExpandCollapse(false, request); + handleExpandCollapse(false, request, response); } else if (TREE_EXPAND.equals(cmd)) { - handleExpandCollapse(true, request); + handleExpandCollapse(true, request, response); } return; } - private void handleExpandCollapse(boolean expand, HttpServletRequest req) + private void handleExpandCollapse(boolean expand, HttpServletRequest req, ServletResponse response) { String tree = req.getParameter("tree"); String node = req.getParameter("node"); - //System.err.println("TreeCommand:" + ((expand) ? "expand" : "collapse") + - // " Tree:" + tree + " Node:" + node); + String expandSvr = req.getParameter("expandOnServer"); + System.err.println("TreeCommand:" + ((expand) ? "expand" : "collapse") + + " Tree:" + tree + " Node:" + node + " expandSvr:" + expandSvr); NameService ns = NameService.instance(req.getSession()); assert(ns != null); @@ -88,5 +100,54 @@ } elem.onExpand(); elem.setExpanded(expand); + + if (expandSvr != null) { + StringBuilder sb = new StringBuilder(1024); + StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb); + // Start the document + writeStartElement(writer,TREE_EXPAND_ELEM); + + // add a tree identifier + writeElement(writer, "node",node); + + // add the tree text + writeElement(writer, "treeDiv","<![CDATA[<p>This is here</p>]]>"); + + writeEndElement(writer,TREE_EXPAND_ELEM); + write(response,sb.toString()); + } + } + + private void writeStartElement(AbstractRenderAppender writer,String elementName) + { + writer.append("<"); + writer.append(elementName); + writer.append(">"); + + } + + private void writeEndElement(AbstractRenderAppender writer,String elementName) + { + writer.append("</"); + writer.append(elementName); + writer.append(">"); + } + + private void writeElement(AbstractRenderAppender writer, String elementName, String value) + { + writeStartElement(writer,elementName); + writer.append(value); + writeEndElement(writer,elementName); + + } + + private void write(ServletResponse response, String string) + { + try { + Writer writer = response.getWriter(); + writer.write(string); + } + catch (IOException e) { + } } } Modified: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java&r1=149048&p2=incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java (original) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeElement.java Sat Jan 29 07:37:17 2005 @@ -43,6 +43,7 @@ */ public static final String TREE_ANCHOR = "netui-tree-anchor"; public static final String TREE_ANCHOR_ID = "netui-tree-id"; + public static final String TREE_EXPAND = "netui:expandOnServer"; public static final String TREE_EXPAND_STATE = "expand"; public static final String TREE_COLLAPSE_STATE = "collapse"; Added: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderState.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderState.java?view=auto&rev=149049 ============================================================================== --- (empty file) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderState.java Sat Jan 29 07:37:17 2005 @@ -0,0 +1,33 @@ +/* + * 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; + +public class TreeRenderState + { + public String selectionStyle; // selection style + public String selectionClass; // selection class + public String unselectStyle; // unselect style + public String unselectClass; // unselect class + public String disabledStyle; // disabled style + public String disabledClass; // disabled class + + public String tagId; // tag that should uniquely indentify a tree. Required for multiple tree using auto expand + + public boolean runAtClient; + public boolean escapeContent = false; // esapce the content of labels +} Added: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java?view=auto&rev=149049 ============================================================================== --- (empty file) +++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/tree/TreeRenderer.java Sat Jan 29 07:37:17 2005 @@ -0,0 +1,493 @@ +/* + * 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.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 InheritableState _iState; + + 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; + + TreeRenderer(TreeRenderState trs, InheritableState iState, HttpServletRequest request,ServletContext servletContext) + { + _trs = trs; + _iState = iState; + _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; + } + + abstract protected void registerTagError(String message, Throwable e) + throws JspException; + + abstract protected String renderTagId(HttpServletRequest request, String tagId, AbstractHtmlState state); + + /** + * This is a recursive method which generates the markup for the tree. + * @param sb + * @param request + * @param response + * @param node + * @param level + * @param attrs + * @param state + * @throws javax.servlet.jsp.JspException + */ + protected void render(StringBuilder sb, HttpServletRequest request, HttpServletResponse response, + TreeElement node, int level, AttributeRenderer attrs, InheritableState state) + throws JspException + { + // assert the values... + assert(sb != null); + assert(request != null); + assert(response != null); + assert(node != null); + + String encoding = response.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... + StringBuilder img = new StringBuilder(32); + + + // Render the beginning of this node + _divState.clear(); + String tagId = node.getTagId(); + String script = null; + if (tagId != null) { + script = renderTagId(request, tagId, _divState); + } + attrs.renderDiv(_divState, node); + if (_trs.runAtClient) { + _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, "netui-tree-level", Integer.toString(level)); + } + sb.append(" "); + StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb); + _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(request); + boolean devMode = !AdapterManager.getServletContainerAdapter(servletContext).isInProductionMode(); + if (devMode) { + boolean error = false; + StringBuilder errorText = new StringBuilder(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 + InheritableState is = node.getInheritableState(); + if (is != null) { + 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.getImageLineVertical()); + _imgState.style = "vertical-align:middle;"; + } + 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, request, response, node, nodeName); + else { + // Render client expansion and initialize the tree JavaScript support + closeAnchor = renderClientExpansionAnchor(sb, _anchorRenderer, node, encodedNodeName); + } + + // place the image into the anchor.... + // The type of the image depends upon the position and the type of the node. + img.setLength(0); + img.append(state.getImageRoot()); + img.append('/'); + if (node.isLeaf()) { // leaf node either last or middle + if (node.isLast()) + img.append(state.getImageLineLast()); + else + img.append(state.getImageLineMiddle()); + } + else if (node.isExpanded()) { // interior node that is expanded + if (node.isLast()) + img.append(state.getImageHandleDownLast()); + else + img.append(state.getImageHandleDownMiddle()); + } + else { // interior not expanded + if (node.isLast()) + img.append(state.getImageHandleRightLast()); + else + img.append(state.getImageHandleRightMiddle()); + } + + // write out the image which occurs next to the icon + if (!closeAnchor) + sb.append(" "); + + _imgState.clear(); + _imgState.src = img.toString(); + _imgState.style = "vertical-align:middle;"; + _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, BORDER, "0"); + _imgState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, 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(); + } + + // process the action into a URL + //PageContext pageContext = getPageContext(); + if (action != null && selectionLink == null) { + HashMap params = new HashMap(); + 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 { + uri = PageFlowUtils.getRewrittenActionURI(_servletContext,request,response,action,params,null,false); + //uri = PageFlowTagUtils.rewriteActionURL(pageContext, action, params, null); + } + catch (URISyntaxException e) { + // report the error... + String s = Bundle.getString("Tags_Tree_Node_URLException", + new Object[]{action, e.getMessage()}); + registerTagError(s, e); + } + + if (uri != null) { + selectionLink = response.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; + _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, node.getTarget()); + + // set the selection styles + if (node.isSelected()) { + _anchorState.style = _trs.selectionStyle; + _anchorState.styleClass = _trs.selectionClass; + } + else { + _anchorState.style = _trs.unselectStyle; + _anchorState.styleClass = _trs.unselectClass; + } + + // render any attributes applied to the HTML + attrs.renderIconLink(_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.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.disabledClass; + _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.getImageRoot() + "/" + state.getDefaultIcon(); + } + else { + icon = state.getImageRoot() + "/" + icon; + } + + // write out the icon + if (icon != null) { + _imgState.clear(); + _imgState.src = icon; + _imgState.style = "vertical-align:middle"; + String 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) + String label = node.getLabel(); + if (label != null) { + if (_trs.escapeContent) { + StringBuilder s = new StringBuilder(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) { + StringBuilder s = new StringBuilder(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"); + + // 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, request, response, children[i], newLevel, attrs, state); + } + } + attrs.removeElement(node, removes); + } + + private boolean renderExpansionAnchor(StringBuilder sb, TagRenderingBase anchorRenderer, + HttpServletRequest request, HttpServletResponse response, + TreeElement node, String nodeName) + throws JspException + { + // Render the tree state image for this node + String action = _iState.getExpansionAction(); + if (action == null) { + action = _iState.getSelectionAction(); + } + boolean isAction = PageFlowTagUtils.isAction(request, 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 { + uri = PageFlowUtils.getRewrittenActionURI(_servletContext,request,response,action,params,null,false); + //uri = PageFlowTagUtils.rewriteActionURL(pageContext, action, params, null); + } + 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 = response.encodeURL(uri); + _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, _iState.getExpandTarget()); + 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(StringBuilder sb, TagRenderingBase anchorRenderer, + TreeElement node, String encodedNodeName) + { + 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_ID, encodedNodeName); + if (node.isExpandOnServer()) { + _anchorState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TreeElement.TREE_EXPAND, "true"); + } + + sb.append(" "); + StringBuilderRenderAppender writer = new StringBuilderRenderAppender(sb); + anchorRenderer.doStartTag(writer, _anchorState); + return true; + } + return false; + } +} Modified: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf&r1=149048&p2=incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf (original) +++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/Controller.jpf Sat Jan 29 07:37:17 2005 @@ -58,6 +58,7 @@ private TreeElement _tree24; private TreeElement _tree25; private TreeElement _tree26; + private TreeElement _tree27; private String _expand = " "; private String _node = " "; @@ -268,6 +269,14 @@ public void setTree26(TreeElement tn) { _tree26 = tn; } + + public TreeElement getTree27() { + return _tree27; + } + + public void setTree27(TreeElement tn) { + _tree27 = tn; + } //************************************************************************ @@ -514,6 +523,7 @@ _tree24 = null; _tree25 = null; _tree26 = null; + _tree27 = null; buildTrees(); return forward; @@ -757,6 +767,15 @@ @Jpf.Forward(name = "success", path = "runAtClientError.jsp") }) protected Forward goRunAtClientError() { + Forward success = new Forward("success"); + clearExpand(); + return success; + } + + @Jpf.Action(forwards = { + @Jpf.Forward(name = "success", path = "expandOnServer.jsp") +}) + protected Forward goExpandOnServer() { Forward success = new Forward("success"); clearExpand(); return success; Added: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/expandOnServer.jsp Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/expandOnServer.jsp?view=auto&rev=149049 ============================================================================== --- (empty file) +++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/expandOnServer.jsp Sat Jan 29 07:37:17 2005 @@ -0,0 +1,66 @@ +<%@ page language="java" contentType="text/html;charset=UTF-8"%> +<%@ taglib uri="beehive-netui-tags-databinding.tld" prefix="netui-data"%> +<%@ taglib uri="beehive-netui-tags-html.tld" prefix="netui"%> +<%@ taglib uri="beehive-netui-tags-template.tld" prefix="netui-template"%> +<netui:html> + <head> + <title>expandOnServer.jsp</title> + <link href="style.css" rel="stylesheet" type="text/css"> + <netui:scriptHeader /> + <netui:base/> + </head> + <netui:body> + <h4 class="title"><netui:anchor action="begin" styleClass="homeAnchor">Home</netui:anchor>expandOnServer.jsp [goExpandOnServer.do] </h4> + <!-- Attribute Information --> + <div style='float:left;width:300px'> + <table cellpadding="2" cellspacing="0" border="1" width="300px"> + <tr><th>Creation</th><td>static</td></tr> + <tr><th>tree</th><td>{pageFlow.tree27}</td></tr> + <tr><th>action</th><td>postback</td></tr> + <tr><th>runAtClient</th><td>true</td></tr> + </table> + </div> + <!-- Postback information --> + <div style='float:right;width:250px;border:solid 1pt gray;margin:2 4;'> + <p style="font-weight:bold;text-align:center;margin: 0;padding:0;">Tree Postback Information</p> + <table cellpadding='0' cellspacing='2' width="100%"> + <tr><th style="text-align:right" width="100pt">Expand:</th><td><netui:content value="${pageFlow.expand}"/></td></tr> + <tr><th style="text-align:right" width="100pt">Selection:</th><td><netui:content value="${pageFlow.node}"/></td></tr> + </table> + </div> + Base test of the expandOnServer feature. + <hr style="clear:left"> + <div class="content"> + <netui:tree dataSource="pageFlow.tree25" selectionAction="postback" + runAtClient="true" tagId="treeOne"> + <netui:treeItem expanded="true"> + <netui:treeLabel>0</netui:treeLabel> + <netui:treeItem expandOnServer="true"> + <netui:treeLabel>0.0</netui:treeLabel> + <netui:treeItem> + <netui:treeLabel>0.0.0</netui:treeLabel> + <netui:treeItem>0.0.0.0</netui:treeItem> + <netui:treeItem>0.0.0.1</netui:treeItem> + </netui:treeItem> + </netui:treeItem> + <netui:treeItem expandOnServer="true"> + <netui:treeLabel>0.1</netui:treeLabel> + <netui:treeItem>0.1.0</netui:treeItem> + <netui:treeItem>0.1.1</netui:treeItem> + </netui:treeItem> + <netui:treeItem expandOnServer="true"> + <netui:treeLabel>0.2</netui:treeLabel> + <netui:treeItem>0.2.0</netui:treeItem> + </netui:treeItem> + <netui:treeItem expandOnServer="true"> + <netui:treeLabel>0.3</netui:treeLabel> + <netui:treeItem>0.3.0</netui:treeItem> + <netui:treeItem>0.3.1</netui:treeItem> + </netui:treeItem> + </netui:treeItem> + </netui:tree> + </div> + </netui:body> +</netui:html> + + \ No newline at end of file Modified: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp?view=diff&rev=149049&p1=incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp&r1=149048&p2=incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp&r2=149049 ============================================================================== --- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp (original) +++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/richTree/index.jsp Sat Jan 29 07:37:17 2005 @@ -35,6 +35,7 @@ <li><netui:anchor action="goClientContentForm">Client Content Form</netui:anchor> -- [tree22] Using an Form inside of the Content</li> <li><netui:anchor action="goTreeScriptContainer">RunAtClient ScriptContainer</netui:anchor> -- [tree24] Running a runAtClient tree in a script container</li> <li><netui:anchor action="goRunAtClient2">Multiple Trees in a Page</netui:anchor> -- [tree25 and tree26] Multiple tree controls doing runAtClient</li> + <li><netui:anchor action="goExpandOnServer">Expand On Server</netui:anchor> -- [tree27] Base test of expand on server.</li> </ul> <h4>Layout Bugs</h4> <ul>
