您的位置:首页 > 其它

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

2016-08-17 10:23 225 查看
有前面我们提到过,在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模板。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: