Author: adrianc
Date: Sun Aug 25 18:00:43 2013
New Revision: 1517353
URL: http://svn.apache.org/r1517353
Log:
Converted menu widget HTML renderer to a macro renderer.
Added:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
Added:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java?rev=1517353&view=auto
==============================================================================
---
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
(added)
+++
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
Sun Aug 25 18:00:43 2013
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * 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.menu;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.util.HashMap;
+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.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.menu.ModelMenuItem.Image;
+import org.ofbiz.widget.menu.ModelMenuItem.Link;
+
+import freemarker.core.Environment;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+public class MacroMenuRenderer implements MenuStringRenderer {
+
+ public static final String module = MacroMenuRenderer.class.getName();
+ private int macroCount = 999;
+ private final Map<Appendable, Environment> environments = new
HashMap<Appendable, Environment>();
+ private final Template macroLibrary;
+ private final HttpServletRequest request;
+ private final HttpServletResponse response;
+
+ public MacroMenuRenderer(String macroLibraryPath, HttpServletRequest
request, HttpServletResponse response) throws TemplateException, IOException {
+ this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
+ this.request = request;
+ this.response = response;
+ }
+
+ // Made this a separate method so it can be externalized and reused.
+ private Map<String, Object> createImageParameters(Map<String, Object>
context, Image image) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put("id", image.getId(context));
+ parameters.put("style", image.getStyle(context));
+ parameters.put("width", image.getWidth(context));
+ parameters.put("height", image.getHeight(context));
+ parameters.put("border", image.getBorder(context));
+ String src = image.getSrc(context);
+ if (UtilValidate.isNotEmpty(src) && request != null && response !=
null) {
+ String urlMode = image.getUrlMode();
+ if ("ofbiz".equalsIgnoreCase(urlMode)) {
+ boolean fullPath = false;
+ boolean secure = false;
+ boolean encode = false;
+ ServletContext ctx = (ServletContext)
request.getAttribute("servletContext");
+ RequestHandler rh = (RequestHandler)
ctx.getAttribute("_REQUEST_HANDLER_");
+ src = rh.makeLink(request, response, src, fullPath, secure,
encode);
+ } else if ("content".equalsIgnoreCase(urlMode)) {
+ StringBuilder newURL = new StringBuilder();
+ ContentUrlTag.appendContentPrefix(request, newURL);
+ newURL.append(src);
+ src = newURL.toString();
+ }
+ }
+ parameters.put("src", src);
+ return parameters;
+ }
+
+ private void executeMacro(Appendable writer, String macro) throws
IOException, TemplateException {
+ Environment environment = getEnvironment(writer);
+ Reader templateReader = new StringReader(macro);
+ macroCount++;
+ String templateName = toString().concat("_") + macroCount;
+ Template template = new Template(templateName, templateReader,
FreeMarkerWorker.getDefaultOfbizConfig());
+ templateReader.close();
+ environment.include(template);
+ }
+
+ private void executeMacro(Appendable writer, String macroName, Map<String,
Object> macroParameters) throws IOException, TemplateException {
+ StringBuilder sb = new StringBuilder("<@");
+ sb.append(macroName);
+ if (macroParameters != null) {
+ for (Map.Entry<String, Object> parameter :
macroParameters.entrySet()) {
+ sb.append(' ');
+ sb.append(parameter.getKey());
+ sb.append("=");
+ Object value = parameter.getValue();
+ if (value instanceof String) {
+ sb.append('"');
+ sb.append(((String) value).replaceAll("\"", "\\\\\""));
+ sb.append('"');
+ } else {
+ sb.append(value);
+ }
+ }
+ }
+ sb.append(" />");
+ if (Debug.verboseOn()) {
+ Debug.logVerbose("Executing macro: " + sb, module);
+ }
+ executeMacro(writer, sb.toString());
+ }
+
+ private Environment getEnvironment(Appendable writer) throws
TemplateException, IOException {
+ Environment environment = environments.get(writer);
+ if (environment == null) {
+ Map<String, Object> input = UtilMisc.toMap("key", null);
+ environment = FreeMarkerWorker.renderTemplate(macroLibrary, input,
writer);
+ environments.put(writer, environment);
+ }
+ return environment;
+ }
+
+ private boolean isDisableIfEmpty(ModelMenuItem menuItem, Map<String,
Object> context) {
+ boolean disabled = false;
+ String disableIfEmpty = menuItem.getDisableIfEmpty();
+ if (UtilValidate.isNotEmpty(disableIfEmpty)) {
+ List<String> keys = StringUtil.split(disableIfEmpty, "|");
+ for (String key : keys) {
+ Object obj = context.get(key);
+ if (obj == null) {
+ disabled = true;
+ break;
+ }
+ }
+ }
+ return disabled;
+ }
+
+ private boolean isHideIfSelected(ModelMenuItem menuItem, Map<String,
Object> context) {
+ ModelMenu menu = menuItem.getModelMenu();
+ String currentMenuItemName =
menu.getSelectedMenuItemContextFieldName(context);
+ String currentItemName = menuItem.getName();
+ Boolean hideIfSelected = menuItem.getHideIfSelected();
+ return (hideIfSelected != null && hideIfSelected.booleanValue() &&
currentMenuItemName != null && currentMenuItemName.equals(currentItemName));
+ }
+
+ @Override
+ public void renderFormatSimpleWrapperClose(Appendable writer, Map<String,
Object> context, ModelMenu menu) throws IOException {
+ // Nothing to do.
+ }
+
+ @Override
+ public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String,
Object> context, ModelMenu menu) throws IOException {
+ // Nothing to do.
+ }
+
+ @Override
+ public void renderFormatSimpleWrapperRows(Appendable writer, Map<String,
Object> context, Object menu) throws IOException {
+ List<ModelMenuItem> menuItemList = ((ModelMenu)
menu).getMenuItemList();
+ for (ModelMenuItem currentMenuItem : menuItemList) {
+ renderMenuItem(writer, context, currentMenuItem);
+ }
+ }
+
+ @Override
+ public void renderImage(Appendable writer, Map<String, Object> context,
Image image) throws IOException {
+ Map<String, Object> parameters = createImageParameters(context, image);
+ try {
+ executeMacro(writer, "renderImage", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void renderLink(Appendable writer, Map<String, Object> context,
Link link) throws IOException {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ String target = link.getTarget(context);
+ ModelMenuItem menuItem = link.getLinkMenuItem();
+ if (menuItem.getDisabled() || isDisableIfEmpty(menuItem, context)) {
+ target = null;
+ }
+ parameters.put("id", link.getId(context));
+ parameters.put("style", link.getStyle(context));
+ parameters.put("name", link.getName(context));
+ parameters.put("text", link.getText(context));
+ parameters.put("targetWindow", link.getTargetWindow(context));
+ String uniqueItemName = menuItem.getModelMenu().getName() + "_" +
menuItem.getName() + "_LF_" + UtilMisc.<String> addToBigDecimalInMap(context,
"menuUniqueItemIndex", BigDecimal.ONE);
+ parameters.put("uniqueItemName", uniqueItemName);
+ String linkType =
WidgetWorker.determineAutoLinkType(link.getLinkType(), target,
link.getUrlMode(), request);
+ parameters.put("linkType", linkType);
+ String linkUrl = "";
+ String actionUrl = "";
+ StringBuilder targetParameters = new StringBuilder();
+ if ("hidden-form".equals(linkType) || "ajax-window".equals(linkType)) {
+ StringBuilder sb = new StringBuilder();
+ WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(),
null, link.getPrefix(context), link.getFullPath(), link.getSecure(),
link.getEncode(), request, response, context);
+ actionUrl = sb.toString();
+ targetParameters.append("[");
+ for (Map.Entry<String, String> parameter :
link.getParameterMap(context).entrySet()) {
+ if (targetParameters.length() > 1) {
+ targetParameters.append(",");
+ }
+ targetParameters.append("{'name':'");
+ targetParameters.append(parameter.getKey());
+ targetParameters.append("'");
+ targetParameters.append(",'value':'");
+ targetParameters.append(parameter.getValue());
+ targetParameters.append("'}");
+ }
+ targetParameters.append("]");
+
+ }
+ if (UtilValidate.isNotEmpty(target)) {
+ if (!"hidden-form".equals(linkType)) {
+ StringBuilder sb = new StringBuilder();
+ WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(),
link.getParameterMap(context), link.getPrefix(context), link.getFullPath(),
link.getSecure(), link.getEncode(), request, response, context);
+ linkUrl = sb.toString();
+ }
+ }
+ parameters.put("linkUrl", linkUrl);
+ parameters.put("actionUrl", actionUrl);
+ parameters.put("parameterList", targetParameters.toString());
+ String imgStr = "";
+ Image img = link.getImage();
+ if (img != null) {
+ StringWriter sw = new StringWriter();
+ renderImage(sw, context, img);
+ imgStr = sw.toString();
+ }
+ parameters.put("imgStr", imgStr);
+ try {
+ executeMacro(writer, "renderLink", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void renderMenuClose(Appendable writer, Map<String, Object>
context, ModelMenu menu) throws IOException {
+ Map<String, Object> parameters = null;
+ if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+ parameters = new HashMap<String, Object>();
+ StringBuilder sb = new StringBuilder("End Menu Widget ");
+ sb.append(menu.getBoundaryCommentName());
+ parameters.put("boundaryComment", sb.toString());
+ }
+ try {
+ executeMacro(writer, "renderMenuEnd", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void renderMenuItem(Appendable writer, Map<String, Object> context,
ModelMenuItem menuItem) throws IOException {
+ if (isHideIfSelected(menuItem, context))
+ return;
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ String style = menuItem.getWidgetStyle();
+ if (menuItem.isSelected(context)) {
+ style = menuItem.getSelectedStyle();
+ if (UtilValidate.isEmpty(style)) {
+ style = "selected";
+ }
+ }
+ if (menuItem.getDisabled() || this.isDisableIfEmpty(menuItem,
context)) {
+ style = menuItem.getDisabledTitleStyle();
+ }
+ if (style == null) {
+ style = "";
+ }
+ String alignStyle = menuItem.getAlignStyle();
+ if (UtilValidate.isNotEmpty(alignStyle)) {
+ style = style.concat(" ").concat(alignStyle);
+ }
+ parameters.put("style", style);
+ parameters.put("toolTip", menuItem.getTooltip(context));
+ String linkStr = "";
+ Link link = menuItem.getLink();
+ if (link != null) {
+ StringWriter sw = new StringWriter();
+ renderLink(sw, context, link);
+ linkStr = sw.toString();
+ } else {
+ linkStr = menuItem.getTitle(context);
+ StringUtil.SimpleEncoder simpleEncoder =
(StringUtil.SimpleEncoder) context.get("simpleEncoder");
+ if (simpleEncoder != null) {
+ linkStr = simpleEncoder.encode(linkStr);
+ }
+ }
+ parameters.put("linkStr", linkStr);
+ boolean containsNestedMenus = !menuItem.getMenuItemList().isEmpty();
+ parameters.put("containsNestedMenus", containsNestedMenus);
+ try {
+ executeMacro(writer, "renderMenuItemBegin", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ if (containsNestedMenus) {
+ for (ModelMenuItem childMenuItem : menuItem.getMenuItemList()) {
+ childMenuItem.renderMenuItemString(writer, context, this);
+ }
+ }
+ parameters.clear();
+ parameters.put("containsNestedMenus", containsNestedMenus);
+ try {
+ executeMacro(writer, "renderMenuItemEnd", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void renderMenuOpen(Appendable writer, Map<String, Object> context,
ModelMenu menu) throws IOException {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+ StringBuilder sb = new StringBuilder("Begin Menu Widget ");
+ sb.append(menu.getBoundaryCommentName());
+ parameters.put("boundaryComment", sb.toString());
+ }
+ parameters.put("id", menu.getId());
+ parameters.put("style", menu.getMenuContainerStyle(context));
+ parameters.put("title", menu.getTitle(context));
+ try {
+ executeMacro(writer, "renderMenuBegin", parameters);
+ } catch (TemplateException e) {
+ throw new IOException(e);
+ }
+ }
+}
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=1517353&r1=1517352&r2=1517353&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
Sun Aug 25 18:00:43 2013
@@ -38,8 +38,10 @@ import org.ofbiz.webapp.view.AbstractVie
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.menu.MacroMenuRenderer;
+import org.ofbiz.widget.menu.MenuStringRenderer;
import org.ofbiz.widget.tree.MacroTreeRenderer;
+import org.ofbiz.widget.tree.TreeStringRenderer;
import org.xml.sax.SAXException;
import freemarker.template.TemplateException;
@@ -90,15 +92,13 @@ public class MacroScreenViewHandler exte
ScreenStringRenderer screenStringRenderer = new
MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName() +
".name"), UtilProperties.getPropertyValue("widget", getName() +
".screenrenderer"));
FormStringRenderer formStringRenderer = new
MacroFormRenderer(UtilProperties.getPropertyValue("widget", getName() +
".formrenderer"), request, response);
TreeStringRenderer treeStringRenderer = new
MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() +
".treerenderer"), writer);
- // TODO: uncomment these lines when the renderers are implemented
- //MenuStringRenderer menuStringRenderer = new
MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() +
".menurenderer"), writer);
+ MenuStringRenderer menuStringRenderer = new
MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() +
".menurenderer"), request, response);
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);
screens.getContext().put("treeStringRenderer", treeStringRenderer);
- //screens.getContext().put("menuStringRenderer",
menuStringRenderer);
+ screens.getContext().put("menuStringRenderer", menuStringRenderer);
screens.getContext().put("simpleEncoder",
StringUtil.getEncoder(UtilProperties.getPropertyValue("widget", getName() +
".encoder")));
screenStringRenderer.renderScreenBegin(writer,
screens.getContext());
screens.render(page);
Added: ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl?rev=1517353&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl (added)
+++ ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl Sun Aug 25
18:00:43 2013
@@ -0,0 +1,72 @@
+<#--
+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 renderMenuBegin boundaryComment id style title>
+ <#if boundaryComment?has_content>
+<!-- ${boundaryComment} -->
+ </#if>
+ <div<#if id?has_content> id="${id}"</#if><#if style?has_content>
class="${style}"</#if>>
+ <#if title?has_content>
+ <h2>${title}</h2>
+ </#if>
+ <ul>
+ <li>
+ <ul>
+</#macro>
+
+<#macro renderMenuEnd boundaryComment>
+ </ul>
+ </li>
+ </ul>
+ <br class="clear"/>
+ </div>
+ <#if boundaryComment?has_content>
+<!-- ${boundaryComment} -->
+ </#if>
+</#macro>
+
+<#macro renderImage src id style width height border>
+ <img src="${src}"<#if id?has_content> id="${id}"</#if><#if
style?has_content> class="${style}"</#if><#if width?has_content>
width="${width}"</#if><#if height?has_content> height="${height}"</#if><#if
border?has_content> border="${border}"</#if> />
+</#macro>
+
+<#macro renderLink linkType linkUrl parameterList targetWindow uniqueItemName
actionUrl id="" style="" name="" height="" width="" text="" imgStr="">
+ <#if "hidden-form" == linkType>
+ <form method="post" action="${actionUrl}"<#if targetWindow?has_content>
target="${targetWindow}"</#if>
onsubmit="javascript:submitFormDisableSubmits(this)"
name="${uniqueItemName}"><#rt/>
+ <#list parameterList as parameter>
+ <input name="${parameter.name}" value="${parameter.value}"
type="hidden"/><#rt/>
+ </#list>
+ </form><#rt/>
+ </#if>
+ <a<#if id?has_content> id="${id}"</#if><#if style?has_content>
class="${style}"</#if><#if name?has_content> name="${name}"</#if><#if
targetWindow?has_content> target="${targetWindow}"</#if> href="<#if
"hidden-form"==linkType>javascript:document.${uniqueItemName}.submit()<#else>${linkUrl}</#if>"><#if
imgStr?has_content>${imgStr}</#if><#if text?has_content>${text}</#if></a>
+</#macro>
+
+<#macro renderMenuItemBegin style toolTip linkStr containsNestedMenus>
+ <li<#if style?has_content> class="${style}"</#if><#if toolTip?has_content>
title="${title}"</#if>>
+ <#if linkStr?has_content>${linkStr}</#if>
+ <#if containsNestedMenus>
+ <ul>
+ </#if>
+</#macro>
+
+<#macro renderMenuItemEnd containsNestedMenus>
+ <#if containsNestedMenus>
+ </ul>
+ </#if>
+ </li>
+</#macro>