实现基于FTL模板的菜单之一

来源:互联网 发布:逆火软件怎么使用 编辑:程序博客网 时间:2024/06/13 06:57

实现基于FTL模板的菜单之一

有前面我们提到过,在OFBIZ中form和screen以及树形目录,都是可以通过xml来定义,再通过ftl的模板来生成的,但是菜单却不可以这样。虽然我们也可以在xml文件中配置我们的菜单。但是转换为html时是在HtmlMenuRenderer通过在JAVA代码在硬编码实现的。从OFBIZ代码我们可以知道在未来,OFBIZ会支持FTL模板,但是到到目前为止(12.04版本)还没有实现功能。那么我们可不可以自己动手来实现这个模板呢?答案是肯定的。
思路是通过在java 代码中生成对ftl宏的调用。然后在ftl模板中定义这些宏即可。最后让OFBIZ加载我们的菜单模板即可。

首先们需要创建一个建一个新的类并且实现MenuStringRenderer。这个类就叫作 MacroMenuRenderer 吧。
实现的代码可以是如下。
   
/**
* Widget Library - Form Renderer implementation based on Freemarker macros
*
*/
public class MacroMenuRenderer implements MenuStringRenderer {

   
        public static final String module = MacroTreeRenderer.class.getName();
        protected HttpServletRequest request;
    protected String userLoginIdAtPermGrant;
    protected boolean userLoginIdHasChanged = true;
    private Template macroLibrary;
    private WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();

    protected boolean widgetCommentsEnabled = false;
    

    public MacroMenuRenderer(String macroLibraryPath, Appendable writer,HttpServletRequest request) throws TemplateException, IOException {
        this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
        this.request = request;
    }

    
    private void executeMacro(Appendable writer, String macro) throws IOException {
        try {
            Environment environment = getEnvironment(writer);
            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.getDefaultGorun8Config());
            templateReader.close();
            environment.include(template);
        } catch (TemplateException e) {
            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
        } catch (IOException e) {
            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
        }
    }

    private void executeMacro(Appendable writer, String macroName, Map<String, Object> parameters) throws IOException {
        StringBuilder sb = new StringBuilder("<@");
        sb.append(macroName);
        if (parameters != null) {
            for (Map.Entry<String, Object> parameter : parameters.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(" />");
        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;
    }
   
    public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menuObj) throws IOException {
        List<ModelMenuItem> menuItemList = ((ModelMenu) menuObj).getMenuItemList();
        for (ModelMenuItem currentMenuItem: menuItemList) {
            renderMenuItem(writer, context, currentMenuItem);
        }
    }

    public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException {

        //Debug.logInfo("in renderMenuItem, menuItem:" + menuItem.getName() + " context:" + context ,"");
        boolean hideThisItem = isHideIfSelected(menuItem, context);
        if (hideThisItem)
        {
                return;
        }

        String style = menuItem.getWidgetStyle();
        if (menuItem.isSelected(context)) {
            style = menuItem.getSelectedStyle();
            if (UtilValidate.isEmpty(style)) {
                style = "selected";
            }
        }
        String name = menuItem.getName();

        if (menuItem.getDisabled() || this.isDisableIfEmpty(menuItem, context)) {
            style = menuItem.getDisabledTitleStyle();
        }
        String alignStyle = menuItem.getAlignStyle();
        String toolTip = menuItem.getTooltip(context);
        Link link = menuItem.getLink();
        
        StringWriter sr = new StringWriter();
        sr.append("<@renderMenuItemOpen ");
        sr.append(" style=\"");
        sr.append(style);
        sr.append("\" alignStyle=\"");
        sr.append(alignStyle);
        sr.append("\" toolTip=\"");
        sr.append(toolTip);
        sr.append("\" name=\"");
        sr.append(name);
        sr.append("\" />");
      //  executeMacro(writer, sr.toString());
        
        if (link != null) {
                renderLink(writer, context, link);
        } else {
            String txt = menuItem.getTitle(context);
            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
            if (simpleEncoder != null) {
                txt = simpleEncoder.encode(txt);
            }
            //sr = new StringWriter();
            sr.append("<@renderMenuItemText ");
            sr.append(" text=\"");
            sr.append(txt);
            sr.append("\" />");
            //executeMacro(writer, sr.toString());
        }
        
        if (!menuItem.getMenuItemList().isEmpty()) {
                //sr = new StringWriter();
                sr.append("<@renderSubMenuOpen/> ");
                // executeMacro(writer, sr.toString());
                for (ModelMenuItem childMenuItem : menuItem.getMenuItemList()) {
                childMenuItem.renderMenuItemString(writer, context, this);
            }
                //sr = new StringWriter();
            sr.append("<@renderSubMenuClose/>");
            //executeMacro(writer, sr.toString());
        }
        //sr = new StringWriter();
        sr.append("<@renderMenuItemClose/>");
        executeMacro(writer, sr.toString());
        
    }
    
    public 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;
    }
         
        
        /**
     * Renders the beginning boundary comment string.
     * @param writer The writer to write to
     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
     * @param modelWidget The widget
     */
    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
        if (this.widgetCommentsEnabled) {
            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(writer, sr.toString());
        }
    }

    /**
     * Renders the ending boundary comment string.
     * @param writer The writer to write to
     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
     * @param modelWidget The widget
     */
    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
        if (this.widgetCommentsEnabled) {
            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(writer, sr.toString());
        }
    }
     
        public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {

        if (!userLoginIdHasChanged) {
            userLoginIdHasChanged = userLoginIdHasChanged();
        }
        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
        renderBeginningBoundaryComment(writer, "Menu Widget", modelMenu);
        String menuId = modelMenu.getId();
        String menuContainerStyle = modelMenu.getMenuContainerStyle(context);
        String menuWidth = modelMenu.getMenuWidth();
        String menuTitle = modelMenu.getTitle(context);
        int menuItemCount = modelMenu.renderedMenuItemCount(context);
        
        StringWriter sr = new StringWriter();
        sr.append("<@renderMenuOpen ");
        sr.append(" menuId=\"");
        sr.append(menuId);
        sr.append("\" containerStyle=\"");
        sr.append(menuContainerStyle);
        sr.append("\" menuWidth=\"");
        sr.append(menuWidth);
        sr.append("\" menuTitle=\"");
        sr.append(menuTitle);
        sr.append("\" menuItemCount=\"");
        sr.append(String.valueOf(menuItemCount));
        sr.append("\" />");
        
        executeMacro(writer, sr.toString());
    }

    /* (non-Javadoc)
     * @see cn.gorun8.widget.menu.MenuStringRenderer#renderMenuClose(java.io.Writer, java.util.Map, cn.gorun8.widget.menu.ModelMenu)
     */
    public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
        // TODO: div can't be directly inside an UL
        String fillStyle = modelMenu.getFillStyle();
        int menuItemCount = modelMenu.renderedMenuItemCount(context);
        renderEndingBoundaryComment(writer, "Menu Widget", modelMenu);
       
        StringWriter sr = new StringWriter();
        sr.append("<@renderMenuClose ");
        sr.append(" fillStyle=\"");
        sr.append(fillStyle);
        sr.append("\" menuItemCount=\"");
        sr.append(String.valueOf(menuItemCount));
        sr.append("\" />");
        
        executeMacro(writer, sr.toString());
        
        userLoginIdHasChanged = userLoginIdHasChanged();
        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
        if (userLogin != null) {
            String userLoginId = userLogin.getString("userLoginId");
            //request.getSession().setAttribute("userLoginIdAtPermGrant", userLoginId);
            setUserLoginIdAtPermGrant(userLoginId);
            //Debug.logInfo("in HtmlMenuRenderer, userLoginId(Close):" + userLoginId + " userLoginIdAtPermGrant:" + request.getSession().getAttribute("userLoginIdAtPermGrant"),"");
        } else {
            request.getSession().setAttribute("userLoginIdAtPermGrant", null);
        }
    }

    public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
        //appendWhitespace(writer);
    }

    public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
        //appendWhitespace(writer);
    }

    

    /**
     * @param string
     */
    public void setUserLoginIdAtPermGrant(String string) {
            //Debug.logInfo("in HtmlMenuRenderer,  userLoginIdAtPermGrant(setUserLoginIdAtPermGrant):" + string,"");
        this.userLoginIdAtPermGrant = string;
    }

    public String getUserLoginIdAtPermGrant() {
        return this.userLoginIdAtPermGrant;
    }

    public 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();
            //Debug.logInfo("in HtmlMenuRenderer, currentMenuItemName:" + currentMenuItemName + " currentItemName:" + currentItemName + " hideIfSelected:" + hideIfSelected,"");
        return (hideIfSelected != null && hideIfSelected.booleanValue() && currentMenuItemName != null && currentMenuItemName.equals(currentItemName));
    }


    public boolean userLoginIdHasChanged() {
        boolean hasChanged = false;
        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
        userLoginIdAtPermGrant = getUserLoginIdAtPermGrant();
        //userLoginIdAtPermGrant = (String)request.getSession().getAttribute("userLoginIdAtPermGrant");
        String userLoginId = null;
        if (userLogin != null)
            userLoginId = userLogin.getString("userLoginId");
            //Debug.logInfo("in HtmlMenuRenderer, userLoginId:" + userLoginId + " userLoginIdAtPermGrant:" + userLoginIdAtPermGrant ,"");
        if ((userLoginId == null && userLoginIdAtPermGrant != null)
           || (userLoginId != null && userLoginIdAtPermGrant == null)
           || ((userLoginId != null && userLoginIdAtPermGrant != null)
              && !userLoginId.equals(userLoginIdAtPermGrant))) {
            hasChanged = true;
        } else {
            if (userLoginIdAtPermGrant != null)
               hasChanged = true;
            else
               hasChanged = false;

            userLoginIdAtPermGrant = null;
        }
        return hasChanged;
    }


    public void setUserLoginIdHasChanged(boolean b) {
        userLoginIdHasChanged = b;
    }


    public String getTitle(ModelMenuItem menuItem, Map<String, Object> context) {
        String title = null;
        title = menuItem.getTitle(context);
        return title;
    }

    public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.Link link) throws IOException {
            String target = link.getTarget(context);
        ModelMenuItem menuItem = link.getLinkMenuItem();
        if (menuItem.getDisabled() || isDisableIfEmpty(menuItem, context)) {
            target = null;
        }
        HttpServletResponse response = (HttpServletResponse) context.get("response");
        //HttpServletRequest request = (HttpServletRequest) context.get("request");

        String targetWindow = link.getTargetWindow(context);
        String uniqueItemName = menuItem.getModelMenu().getName() + "_" + menuItem.getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE);
        String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
        String id = link.getId(context);
        String style = link.getStyle(context);
        String name = link.getName(context);
        String confirmationMsg = link.getConfirmation(context);
        String text = link.getText(context);
        
        String imgid ="";
        String imgstyle ="";
        String imgwid = "";
        String imghgt = "";
        String imgborder = "";
        String imgsrc = "";
        
        
        StringBuffer tmpbuf = new StringBuffer();
            StringBufferWriter strWriter =  new StringBufferWriter(tmpbuf);
        WidgetWorker.buildHyperlinkUrl(strWriter, target, link.getUrlMode(), null, link.getPrefix(context),
                link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
        String hyperlinkUrl = strWriter.toString();
        
        
        Image image = link.getImage();
        if (image != null) {
                imgid = image.getId(context);
                imgstyle = image.getStyle(context);
                imgwid = image.getWidth(context);
                imghgt = image.getHeight(context);
                imgborder = image.getBorder(context);
                imgsrc = image.getSrc(context);
                
                imgid = UtilValidate.isNotEmpty(imgid)?imgid:"";
                imgstyle = UtilValidate.isNotEmpty(imgstyle)?imgstyle:"";
                imgwid = UtilValidate.isNotEmpty(imgwid)?imgwid:"";
                imghgt = UtilValidate.isNotEmpty(imghgt)?imghgt:"";
                imgborder = UtilValidate.isNotEmpty(imgborder)?imgborder:"";
                imgsrc = UtilValidate.isNotEmpty(imgsrc)?imgsrc:"";
         }  
  
        StringWriter sr = new StringWriter();
        sr.append("<@renderLink ");
        sr.append("  targetWindow=\"");
        sr.append( targetWindow);
        sr.append("\"  uniqueItemName=\"");
        sr.append( uniqueItemName);
        sr.append("\"  linkType=\"");
        sr.append( linkType);
        sr.append("\"  id=\"");
        sr.append( id);
        sr.append("\"  style=\"");
        sr.append( style);
        sr.append("\"  name=\"");
        sr.append( name);
        sr.append("\"  confirmationMsg=\"");
        sr.append( confirmationMsg);
        sr.append("\"  imgid=\"");
        sr.append( imgid);
        sr.append("\"  imgstyle=\"");
        sr.append( imgstyle);
        sr.append("\"  imgwid=\"");
        sr.append( imgwid);
        sr.append("\"  imghgt=\"");
        sr.append( imghgt);
        sr.append("\"  imgborder=\"");
        sr.append( imgborder);
        sr.append("\"  imgsrc=\"");
        sr.append( imgsrc);
        sr.append("\"  text=\"");
        sr.append( text);
        sr.append("\"  hyperlinkUrl=\"");
        sr.append( hyperlinkUrl);
        
        
        sr.append("\" />");
        executeMacro(writer, sr.toString());
        
    }

    
     

    public void renderImage(Appendable writer, Map<String, Object> context, ModelMenuItem.Image image) throws IOException {
        // open tag
        writer.append("<img ");
        String id = image.getId(context);
         
        
        
        if (UtilValidate.isNotEmpty(id)) {
            writer.append(" id=\"");
            writer.append(id);
            writer.append("\"");
        }
        String style = image.getStyle(context);
        if (UtilValidate.isNotEmpty(style)) {
            writer.append(" class=\"");
            writer.append(style);
            writer.append("\"");
        }
        String wid = image.getWidth(context);
        if (UtilValidate.isNotEmpty(wid)) {
            writer.append(" width=\"");
            writer.append(wid);
            writer.append("\"");
        }
        String hgt = image.getHeight(context);
        if (UtilValidate.isNotEmpty(hgt)) {
            writer.append(" height=\"");
            writer.append(hgt);
            writer.append("\"");
        }
        String border = image.getBorder(context);
        if (UtilValidate.isNotEmpty(border)) {
            writer.append(" border=\"");
            writer.append(border);
            writer.append("\"");
        }
        String src = image.getSrc(context);
        if (UtilValidate.isNotEmpty(src)) {
            writer.append(" src=\"");
            String urlMode = image.getUrlMode();
            boolean fullPath = false;
            boolean secure = false;
            boolean encode = false;
            HttpServletResponse response = (HttpServletResponse) context.get("response");
            HttpServletRequest request = (HttpServletRequest) context.get("request");
            if (urlMode != null && urlMode.equalsIgnoreCase("gorun8")) {
                if (request != null && response != null) {
                    ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
                    RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
                    String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
                    writer.append(urlString);
                } else {
                    writer.append(src);
                }
            } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
                if (request != null && response != null) {
                    StringBuilder newURL = new StringBuilder();
                    ContentUrlTag.appendContentPrefix(request, newURL);
                    newURL.append(src);
                    writer.append(newURL.toString());
                }
            } else {
                writer.append(src);
            }

            writer.append("\"");
        }
        writer.append("/>");
    }
}

明天我们将讲如何定义FTL模板。
0 0
原创粉丝点击