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