Author: bibryam
Date: Mon Nov 16 09:16:24 2009 New Revision: 880683 URL: http://svn.apache.org/viewvc?rev=880683&view=rev Log: Added FTL macro for the tree widget. https://issues.apache.org/jira/browse/OFBIZ-2550 Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java ofbiz/trunk/framework/widget/templates/htmlTreeMacroLibrary.ftl Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java?rev=880683&r1=880682&r2=880683&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java (original) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java Mon Nov 16 09:16:24 2009 @@ -38,6 +38,8 @@ import org.ofbiz.webapp.view.ViewHandlerException; import org.ofbiz.widget.form.FormStringRenderer; import org.ofbiz.widget.form.MacroFormRenderer; +import org.ofbiz.widget.tree.TreeStringRenderer; +import org.ofbiz.widget.tree.MacroTreeRenderer; import org.xml.sax.SAXException; import freemarker.template.TemplateException; @@ -87,16 +89,15 @@ ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName() + ".name"), UtilProperties.getPropertyValue("widget", getName() + ".screenrenderer"), writer); FormStringRenderer formStringRenderer = new MacroFormRenderer(UtilProperties.getPropertyValue("widget", getName() + ".formrenderer"), writer, request, response); + TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() + ".treerenderer"), writer); // TODO: uncomment these lines when the renderers are implemented - //TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() + ".treerenderer"), writer); //MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() + ".menurenderer"), writer); ScreenRenderer screens = new ScreenRenderer(writer, null, screenStringRenderer); screens.populateContextForRequest(request, response, servletContext); // this is the object used to render forms from their definitions screens.getContext().put("formStringRenderer", formStringRenderer); - // TODO: uncomment these lines when the renderers are implemented - //screens.getContext().put("treeStringRenderer", treeStringRenderer); + screens.getContext().put("treeStringRenderer", treeStringRenderer); //screens.getContext().put("menuStringRenderer", menuStringRenderer); screens.getContext().put("simpleEncoder", StringUtil.getEncoder(UtilProperties.getPropertyValue("widget", getName() + ".encoder"))); screenStringRenderer.renderScreenBegin(writer, screens.getContext()); Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java?rev=880683&r1=880682&r2=880683&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java (original) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java Mon Nov 16 09:16:24 2009 @@ -911,23 +911,10 @@ Debug.logError(e, errMsg, module); throw new RuntimeException(errMsg); } - - // try finding the treeStringRenderer by name in the context in case one was prepared and put there + TreeStringRenderer treeStringRenderer = (TreeStringRenderer) context.get("treeStringRenderer"); - // if there was no treeStringRenderer put in place, now try finding the request/response in the context and creating a new one - if (treeStringRenderer == null) { - treeStringRenderer = new HtmlTreeRenderer(); - /* - String renderClassStyle = modelTree.getRenderStyle(); - if (UtilValidate.isNotEmpty(renderClassStyle) && renderClassStyle.equals("simple")) - treeStringRenderer = new HtmlTreeRenderer(); - else - treeStringRenderer = new HtmlTreeExpandCollapseRenderer(); - */ - } - // still null, throw an error if (treeStringRenderer == null) { - throw new IllegalArgumentException("Could not find a treeStringRenderer in the context, and could not find HTTP request/response objects need to create one."); + throw new IllegalArgumentException("Could not find a treeStringRenderer in the context"); } StringBuffer renderBuffer = new StringBuffer(); Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java?rev=880683&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java Mon Nov 16 09:16:24 2009 @@ -0,0 +1,382 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.widget.tree; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.StringUtil; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.template.FreeMarkerWorker; +import org.ofbiz.webapp.control.RequestHandler; +import org.ofbiz.webapp.taglib.ContentUrlTag; +import org.ofbiz.widget.ModelWidget; +import org.ofbiz.widget.WidgetWorker; +import org.ofbiz.widget.screen.ScreenRenderer; +import org.ofbiz.widget.screen.ScreenStringRenderer; +import org.ofbiz.widget.tree.ModelTree; +import org.ofbiz.widget.tree.TreeStringRenderer; + +import freemarker.core.Environment; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +/** + * Widget Library - Tree Renderer implementation based on Freemarker macros + * + */ +public class MacroTreeRenderer implements TreeStringRenderer { + + public static final String module = MacroTreeRenderer.class.getName(); + ScreenStringRenderer screenStringRenderer = null; + private Template macroLibrary; + private Environment environment; + + public MacroTreeRenderer(String macroLibraryPath, Appendable writer) throws TemplateException, IOException { + this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath); + Map<String, Object> input = UtilMisc.toMap("key", null); + this.environment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer); + } + + private void executeMacro(Appendable writer, String macro) throws IOException { + try { + Reader templateReader = new StringReader(macro); + // FIXME: I am using a Date as an hack to provide a unique name for the template... + Template template = new Template((new java.util.Date()).toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig()); + templateReader.close(); + if (writer != null) { + Map<String, Object> input = UtilMisc.toMap("key", null); + Environment tmpEnvironment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer); + tmpEnvironment.include(template); + } else { + this.environment.include(template); + } + } catch (TemplateException e) { + Debug.logError(e, "Error rendering screen thru ftl", module); + } catch (IOException e) { + Debug.logError(e, "Error rendering screen thru ftl", module); + } + } + + private void executeMacro(String macro) throws IOException { + executeMacro(null, macro); + } + + /** + * Renders the beginning boundary comment string. + * @param writer The writer to write to + * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc. + * @param modelWidget The widget + */ + public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException { + if (modelWidget.boundaryCommentsEnabled()) { + StringWriter sr = new StringWriter(); + sr.append("<@formatBoundaryComment "); + sr.append(" boundaryType=\""); + sr.append("Begin"); + sr.append("\" widgetType=\""); + sr.append(widgetType); + sr.append("\" widgetName=\""); + sr.append(modelWidget.getBoundaryCommentName()); + sr.append("\" />"); + executeMacro(sr.toString()); + } + } + + /** + * Renders the ending boundary comment string. + * @param writer The writer to write to + * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc. + * @param modelWidget The widget + */ + public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException { + if (modelWidget.boundaryCommentsEnabled()) { + StringWriter sr = new StringWriter(); + sr.append("<@formatBoundaryComment "); + sr.append(" boundaryType=\""); + sr.append("End"); + sr.append("\" widgetType=\""); + sr.append(widgetType); + sr.append("\" widgetName=\""); + sr.append(modelWidget.getBoundaryCommentName()); + sr.append("\" />"); + executeMacro(sr.toString()); + } + } + + public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException { + String currentNodeTrailPiped = null; + List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail")); + + String style = ""; + if (node.isRootNode()) { + renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree()); + style = "basic-tree"; + } + + StringWriter sr = new StringWriter(); + sr.append("<@renderNodeBegin "); + sr.append(" style=\""); + sr.append(style); + sr.append("\" />"); + executeMacro(sr.toString()); + + String pkName = node.getPkName(); + String entityId = null; + String entryName = node.getEntryName(); + if (UtilValidate.isNotEmpty(entryName)) { + Map map = (Map)context.get(entryName); + entityId = (String)map.get(pkName); + } else { + entityId = (String) context.get(pkName); + } + boolean hasChildren = node.hasChildren(context); + + ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link(); + // check to see if this node needs to be expanded. + if (hasChildren && node.isExpandCollapse()) { + String targetEntityId = null; + List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail")); + if (depth < targetNodeTrail.size()) { + targetEntityId = targetNodeTrail.get(depth); + } + + int openDepth = node.getModelTree().getOpenDepth(); + if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) { + // Not on the trail + if (node.showPeers(depth, context)) { + context.put("processChildren", Boolean.FALSE); + //expandCollapseLink.setText(" + "); + currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|"); + expandCollapseLink.setStyle("collapsed"); + expandCollapseLink.setText(" "); + StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context)); + String trailName = node.getModelTree().getTrailName(context); + if (target.indexOf("?") < 0) { + target.append("?"); + } else { + target.append("&"); + } + target.append(trailName).append("=").append(currentNodeTrailPiped); + expandCollapseLink.setTarget(target.toString()); + } + } else { + context.put("processChildren", Boolean.TRUE); + //expandCollapseLink.setText(" - "); + String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1); + currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|"); + if (currentNodeTrailPiped == null) { + currentNodeTrailPiped = ""; + } + expandCollapseLink.setStyle("expanded"); + expandCollapseLink.setText(" "); + StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context)); + String trailName = node.getModelTree().getTrailName(context); + if (target.indexOf("?") < 0) { + target.append("?"); + } else { + target.append("&"); + } + target.append(trailName).append("=").append(currentNodeTrailPiped); + expandCollapseLink.setTarget(target.toString()); + // add it so it can be remove in renderNodeEnd + currentNodeTrail.add(lastContentId); + } + renderLink(writer, context, expandCollapseLink); + } else if (!hasChildren) { + context.put("processChildren", Boolean.FALSE); + expandCollapseLink.setStyle("leafnode"); + expandCollapseLink.setText(" "); + renderLink(writer, context, expandCollapseLink); + } + } + + public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException { + Boolean processChildren = (Boolean) context.get("processChildren"); + if (node.isRootNode()) { + renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree()); + } + + StringWriter sr = new StringWriter(); + sr.append("<@renderNodeEnd "); + sr.append(" processChildren="); + sr.append(Boolean.toString(processChildren.booleanValue())); + sr.append(" isRootNode="); + sr.append(Boolean.toString(node.isRootNode())); + sr.append(" />"); + executeMacro(sr.toString()); + } + + public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException { + Boolean processChildren = (Boolean) context.get("processChildren"); + if (processChildren.booleanValue()) { + StringWriter sr = new StringWriter(); + sr.append("<@renderLastElement "); + sr.append("style=\""); + sr.append("basic-tree"); + sr.append("\" />"); + executeMacro(sr.toString()); + } + } + + public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException { + String id = label.getId(context); + String style = label.getStyle(context); + String labelText = label.getText(context); + + StringWriter sr = new StringWriter(); + sr.append("<@renderLabel "); + sr.append("\" id=\""); + sr.append(id); + sr.append("\" style=\""); + sr.append(style); + sr.append("\" labelText=\""); + sr.append(labelText); + sr.append("\" />"); + executeMacro(sr.toString()); + } + + public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException { + String target = link.getTarget(context); + StringBuilder linkUrl = new StringBuilder(); + HttpServletResponse response = (HttpServletResponse) context.get("response"); + HttpServletRequest request = (HttpServletRequest) context.get("request"); + + if (target != null && target.length() > 0) { + WidgetWorker.buildHyperlinkUrl(linkUrl, target, link.getUrlMode(), link.getParameterList(), link.getPrefix(context), + link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context); + } + + String id = link.getId(context); + String style = link.getStyle(context); + String name = link.getName(context); + String title = link.getTitle(context); + String targetWindow = link.getTargetWindow(context); + String linkText = link.getText(context); + + String imgStr = ""; + ModelTree.ModelNode.Image img = link.getImage(); + if (img != null) { + StringWriter sw = new StringWriter(); + renderImage(sw, context, img); + imgStr = sw.toString(); + } + + StringWriter sr = new StringWriter(); + sr.append("<@renderLink "); + sr.append("id=\""); + sr.append(id); + sr.append("\" style=\""); + sr.append(style); + sr.append("\" name=\""); + sr.append(name); + sr.append("\" title=\""); + sr.append(title); + sr.append("\" targetWindow=\""); + sr.append(targetWindow); + sr.append("\" linkUrl=\""); + sr.append(linkUrl); + sr.append("\" linkText=\""); + sr.append(linkText); + sr.append("\" imgStr=\""); + sr.append(imgStr.replaceAll("\"", "\\\\\"")); + sr.append("\" />"); + executeMacro(sr.toString()); + } + + public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException { + if (image == null) { + return ; + } + HttpServletResponse response = (HttpServletResponse) context.get("response"); + HttpServletRequest request = (HttpServletRequest) context.get("request"); + + String urlMode = image.getUrlMode(); + String src = image.getSrc(context); + String id = image.getId(context); + String style = image.getStyle(context); + String wid = image.getWidth(context); + String hgt = image.getHeight(context); + String border = image.getBorder(context); + String alt = ""; //TODO add alt to tree images image.getAlt(context); + + boolean fullPath = false; + boolean secure = false; + boolean encode = false; + String urlString = ""; + + if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) { + if (request != null && response != null) { + ServletContext ctx = (ServletContext) request.getAttribute("servletContext"); + RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_"); + urlString = rh.makeLink(request, response, src, fullPath, secure, encode); + } else { + urlString = src; + } + } else if (urlMode != null && urlMode.equalsIgnoreCase("content")) { + if (request != null && response != null) { + StringBuilder newURL = new StringBuilder(); + ContentUrlTag.appendContentPrefix(request, newURL); + newURL.append(src); + urlString = newURL.toString(); + } + } else { + urlString = src; + } + StringWriter sr = new StringWriter(); + sr.append("<@renderImage "); + sr.append("src=\""); + sr.append(src); + sr.append("\" id=\""); + sr.append(id); + sr.append("\" style=\""); + sr.append(style); + sr.append("\" wid=\""); + sr.append(wid); + sr.append("\" hgt=\""); + sr.append(hgt); + sr.append("\" border=\""); + sr.append(border); + sr.append("\" alt=\""); + sr.append(alt); + sr.append("\" urlString=\""); + sr.append(urlString); + sr.append("\" />"); + executeMacro(writer, sr.toString()); + } + + public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) { + ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens"); + if (screenRenderer != null) { + this.screenStringRenderer = screenRenderer.getScreenStringRenderer(); + } + return this.screenStringRenderer; + } +} Added: ofbiz/trunk/framework/widget/templates/htmlTreeMacroLibrary.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/templates/htmlTreeMacroLibrary.ftl?rev=880683&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/templates/htmlTreeMacroLibrary.ftl (added) +++ ofbiz/trunk/framework/widget/templates/htmlTreeMacroLibrary.ftl Mon Nov 16 09:16:24 2009 @@ -0,0 +1,64 @@ +<#-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<#macro renderNodeBegin style> +<#if style?has_content><ul class="${style}"></#if> +<li><#rt/> +</#macro> + +<#macro renderLastElement style> +<ul<#if style?has_content> class="${style}"</#if>> +<li><#rt/> +</#macro> + +<#macro renderNodeEnd processChildren isRootNode> +<#if processChildren?has_content && processChildren> +</ul><#lt/> +</#if> +</li><#rt/> +<#if isRootNode?has_content && isRootNode> +</ul><#lt/> +</#if> +</#macro> + +<#macro renderLabel id style labelText> +<span<#if id?has_content> id="${id}"</#if><#if style?has_content> class="${style}"</#if>><#rt/> +<#if id?has_content>{labelText}</#if><#rt/> +</span> +</#macro> + +<#macro formatBoundaryComment boundaryType widgetType widgetName> +<!-- ${boundaryType} ${widgetType} ${widgetName} --> +</#macro> + +<#macro renderLink id style name title targetWindow linkUrl linkText imgStr> +<a<#if id?has_content> id="${id}"</#if><#rt/> +<#if style?has_content> class="${style}"</#if><#rt/> +<#if name?has_content> name="${name}"</#if><#rt/> +<#if title?has_content> title="${title}"</#if><#rt/> +<#if targetWindow?has_content> target="${targetWindow}</#if> href="${linkUrl}"><#rt/> +<#if imgStr?has_content>${imgStr}<#else><#if linkText?has_content>${linkText}</#if></#if></a><#rt/> +</#macro> + +<#macro renderImage src id style wid hgt border alt urlString> +<#if src?has_content> +<img <#if id?has_content>id="${id}"</#if><#if style?has_content> class="${style}"</#if><#if wid?has_content> width="${wid}"</#if><#if hgt?has_content> height="${hgt}"</#if><#if border?has_content> border="${border}"</#if><#if alt?has_content> alt="${alt}"</#if> src="${urlString}" /><#rt/> +</#if> +</#macro> + \ No newline at end of file |
Free forum by Nabble | Edit this page |