Package org.apache.myfaces.custom.navmenu.jscookmenu

Source Code of org.apache.myfaces.custom.navmenu.jscookmenu.HtmlJSCookMenuRenderer

/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed 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.apache.myfaces.custom.navmenu.jscookmenu;

import org.apache.myfaces.component.html.util.AddResource;
import org.apache.myfaces.custom.navmenu.NavigationMenuItem;
import org.apache.myfaces.custom.navmenu.NavigationMenuUtils;
import org.apache.myfaces.custom.navmenu.UINavigationMenuItem;
import org.apache.myfaces.el.SimpleActionMethodBinding;
import org.apache.myfaces.renderkit.RendererUtils;
import org.apache.myfaces.renderkit.JSFAttr;
import org.apache.myfaces.renderkit.html.HtmlRenderer;
import org.apache.myfaces.renderkit.html.HTML;
import org.apache.myfaces.renderkit.html.util.DummyFormResponseWriter;
import org.apache.myfaces.renderkit.html.util.DummyFormUtils;
import org.apache.myfaces.renderkit.html.util.JavascriptUtils;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.ActionEvent;
import javax.faces.webapp.UIComponentTag;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* @author Thomas Spiegl
* @version $Revision: 291893 $ $Date: 2005-09-27 06:27:25 -0400 (Tue, 27 Sep 2005) $
*/
public class HtmlJSCookMenuRenderer
    extends HtmlRenderer
{
    //private static final Log log = LogFactory.getLog(HtmlJSCookMenuRenderer.class);

    private static final String JSCOOK_ACTION_PARAM = "jscook_action";

    public void decode(FacesContext context, UIComponent component)
    {
        RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);

        Map parameter = context.getExternalContext().getRequestParameterMap();
        String actionParam = (String)parameter.get(JSCOOK_ACTION_PARAM);
        if (actionParam != null && !actionParam.trim().equals("") &&
                !actionParam.trim().equals("null"))
        {
            String compId = getMenuId(context,component);
            int idx = actionParam.lastIndexOf(':');
            if (idx == -1) {
                return;
            }
            String actionId = actionParam.substring(0, idx);
            if (! compId.equals(actionId)) {
                return;
            }
            actionParam = actionParam.substring(idx + 1);
            actionParam = decodeValueBinding(actionParam, context);
            MethodBinding mb;
            if (UIComponentTag.isValueReference(actionParam))
            {
                mb = context.getApplication().createMethodBinding(actionParam, null);
            }
            else
            {
                mb = new SimpleActionMethodBinding(actionParam);
            }
            ((HtmlCommandJSCookMenu)component).setAction(mb);

            component.queueEvent(new ActionEvent(component));
        }
    }

    private String decodeValueBinding(String actionParam, FacesContext context)
    {
        int idx = actionParam.indexOf(";#{");
        if (idx == -1) {
            return actionParam;
        }

        String newActionParam = actionParam.substring(0, idx);
        String vbParam = actionParam.substring(idx + 1);

        idx = vbParam.indexOf('=');
        if (idx == -1) {
            return newActionParam;
        }
        String vbExpressionString = vbParam.substring(0, idx);
        String vbValue = vbParam.substring(idx + 1);

        ValueBinding vb =
            context.getApplication().createValueBinding(vbExpressionString);
        vb.setValue(context, vbValue);

        return newActionParam;
    }

    public boolean getRendersChildren()
    {
        return true;
    }

    public void encodeChildren(FacesContext context, UIComponent component) throws IOException
    {
        RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);

        List list = NavigationMenuUtils.getNavigationMenuItemList(component);
        if (list.size() > 0)
        {
            List uiNavMenuItemList = component.getChildren();
            DummyFormResponseWriter dummyFormResponseWriter = DummyFormUtils.getDummyFormResponseWriter(context);
            dummyFormResponseWriter.addDummyFormParameter(JSCOOK_ACTION_PARAM);
            dummyFormResponseWriter.setWriteDummyForm(true);

            String myId = getMenuId(context, component);

            ResponseWriter writer = context.getResponseWriter();

            writer.startElement(HTML.SCRIPT_ELEM,component);
            writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
            StringBuffer script = new StringBuffer();
            script.append("var ").append(getMenuId(context, component)).append(" =\n[");
            encodeNavigationMenuItems(context, script,
                                      (NavigationMenuItem[]) list.toArray(new NavigationMenuItem[list.size()]),
                                      uiNavMenuItemList,
                                      myId);

            script.append("];");
            writer.writeText(script.toString(),null);
            writer.endElement(HTML.SCRIPT_ELEM);
        }
    }

    private void encodeNavigationMenuItems(FacesContext context,
                                           StringBuffer writer,
                                           NavigationMenuItem[] items,
                                           List uiNavMenuItemList,
                                           String menuId)
        throws IOException
    {
        for (int i = 0; i < items.length; i++)
        {
            NavigationMenuItem item = items[i];
            Object tempObj = null;
            UINavigationMenuItem uiNavMenuItem = null;
            if (i < uiNavMenuItemList.size()) {
                tempObj = uiNavMenuItemList.get(i);
            }
            if (tempObj != null) {
                if (tempObj instanceof UINavigationMenuItem) {
                    uiNavMenuItem = (UINavigationMenuItem) tempObj;
                }
            }

            if (! item.isRendered()) {
                continue;
            }

            if (i > 0)
            {
                writer.append(",\n");
            }

            if (item.isSplit())
            {
                writer.append("_cmSplit,");
            }

            writer.append("[");
            if (item.getIcon() != null)
            {
                String iconSrc = context.getApplication().getViewHandler().getResourceURL(context, item.getIcon());
                writer.append("'<img src=\"");
                writer.append(context.getExternalContext().encodeResourceURL(iconSrc));
                writer.append("\"/>'");
            }
            else
            {
                writer.append("null");
            }
            writer.append(", '");
            if( item.getLabel() != null ) {
                writer.append(JavascriptUtils.encodeString(item.getLabel()));
            }
            writer.append("', ");
            if (item.getAction() != null && ! item.isDisabled())
            {
                writer.append("'");
                writer.append(menuId);
                writer.append(':');
                writer.append(item.getAction());
                if (uiNavMenuItem != null) {
                    encodeValueBinding(writer, uiNavMenuItem, item);
                }
                writer.append("'");
            }
            else
            {
                writer.append("null");
            }
            writer.append(", 'linkDummyForm', null"); // TODO Change here to allow the use of non dummy form if possible.

            if (item.isRendered() && ! item.isDisabled()) {
                // render children only if parent is visible/enabled
                NavigationMenuItem[] menuItems = item.getNavigationMenuItems();
                if (menuItems != null && menuItems.length > 0)
                {
                    writer.append(",");
                    if (uiNavMenuItem != null)
                    {
                        encodeNavigationMenuItems(context, writer, menuItems,
                                uiNavMenuItem.getChildren(), menuId);
                    } else {
                        encodeNavigationMenuItems(context, writer, menuItems,
                                new ArrayList(1), menuId);
                    }
                }
            }
            writer.append("]");
        }
    }

    private void encodeValueBinding(StringBuffer writer, UINavigationMenuItem uiNavMenuItem,
            NavigationMenuItem item)
    {
        ValueBinding vb = uiNavMenuItem.getValueBinding("NavMenuItemValue");
        if (vb == null) {
            return;
        }
        String vbExpression = vb.getExpressionString();
        if (vbExpression == null) {
            return;
        }
        Object tempObj = item.getValue();
        if (tempObj == null) {
            return;
        }
       
        writer.append(";");
        writer.append(vbExpression);
        writer.append("=");
        writer.append(tempObj.toString());
    }
   
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException
    {
        RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);
        HtmlCommandJSCookMenu menu = (HtmlCommandJSCookMenu)component;
       
        String theme = menu.getTheme();

        addResourcesToHeader(theme,menu,context);

        ResponseWriter writer = context.getResponseWriter();

        String menuId = getMenuId(context, component);

        writer.write("<div id=\"");
        writer.write(menuId);
        writer.write("\"></div>\n");
        writer.startElement(HTML.SCRIPT_ELEM,menu);
        writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);

        StringBuffer buf = new StringBuffer();
        buf.append("\tcmDraw ('").
                append(menuId).
                append("', ").
                append(menuId).
                append(", '").
                append(menu.getLayout()).
                append("', cm").
                append(theme).
                append(", '").
                append(theme).
                append("');");

        writer.writeText(buf.toString(),null);
        writer.endElement(HTML.SCRIPT_ELEM);
    }

    private void addResourcesToHeader(String themeName, HtmlCommandJSCookMenu menu, FacesContext context)
    {
        String javascriptLocation = (String) menu.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
        String imageLocation = (String) menu.getAttributes().get(JSFAttr.IMAGE_LOCATION);
        String styleLocation = (String) menu.getAttributes().get(JSFAttr.STYLE_LOCATION);

        if(javascriptLocation != null)
        {
            AddResource.addJavaScriptToHeader(javascriptLocation, "JSCookMenu.js", context);
            AddResource.addJavaScriptToHeader(javascriptLocation, "MyFacesHack.js", context);
        }
        else
        {
            AddResource.addJavaScriptToHeader(HtmlJSCookMenuRenderer.class, "JSCookMenu.js", context);
            AddResource.addJavaScriptToHeader(HtmlJSCookMenuRenderer.class, "MyFacesHack.js", context);
        }

        addThemeSpecificResources(themeName, styleLocation, javascriptLocation, imageLocation, context);
    }

    private void addThemeSpecificResources(String themeName, String styleLocation, String javascriptLocation, String imageLocation, FacesContext context)
    {
        if(themeName != null)
        {
            if(!(themeName.equals("ThemeOffice") || themeName.equals("ThemeMiniBlack")
                || themeName.equals("ThemeIE") || themeName.equals("ThemePanel")))
            {
                throw new IllegalArgumentException("You provided a wrong themeName. Must be one of ThemeOffice, ThemeMiniBlack, ThemeIE or ThemePanel");
            }
        }
        else
        {
            if(styleLocation == null || javascriptLocation == null || imageLocation == null)
                throw new IllegalArgumentException("If you don't provide a theme, "+
                        "you need to provide all resource-paths.");
        }

        StringBuffer buf = new StringBuffer();
        buf.append("my");
        buf.append(themeName);
        buf.append("Base='");
        if(imageLocation!=null)
        {
            buf.append(AddResource.getResourceBasePath(imageLocation));
        }
        else
        {
            buf.append(AddResource.getResourceBasePath(HtmlJSCookMenuRenderer.class,context));
            buf.append("/ThemeOffice/';");
        }

        AddResource.addInlineScriptToHeader(buf.toString(), context);

        if(javascriptLocation != null)
        {
            AddResource.addJavaScriptToHeader(javascriptLocation, "theme.js", context);
        }
        else
        {
            AddResource.addJavaScriptToHeader(HtmlJSCookMenuRenderer.class, themeName+"/theme.js", context);
        }

        if(styleLocation != null)
        {
            AddResource.addStyleSheet(styleLocation, "theme.css", context);
        }
        else
        {
            AddResource.addStyleSheet(HtmlJSCookMenuRenderer.class, themeName+"/theme.css", context);
        }
    }

    /**
     * Fetch the very last part of the menu id.
     *
     * @param context
     * @param component
     * @return String id of the menu
     */
    private String getMenuId(FacesContext context, UIComponent component) {
        String menuId = component.getClientId(context).replaceAll(":","_") + "_menu";
        while(menuId.startsWith("_"))
        {
            menuId = menuId.substring(1);
        }
        return menuId;
    }

}
TOP

Related Classes of org.apache.myfaces.custom.navmenu.jscookmenu.HtmlJSCookMenuRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.