org.mifos.framework.components.mifosmenu.MenuParser.java Source code

Java tutorial

Introduction

Here is the source code for org.mifos.framework.components.mifosmenu.MenuParser.java

Source

/*
 * Copyright (c) 2005-2011 Grameen Foundation USA
 * All rights reserved.
 *
 * 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.
 *
 * See also http://www.apache.org/licenses/LICENSE-2.0.html for an
 * explanation of the license and how it is applied.
 */

package org.mifos.framework.components.mifosmenu;

import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.apache.commons.lang.StringUtils;
import org.mifos.config.business.MifosConfigurationManager;
import org.mifos.core.MifosResourceUtil;
import org.mifos.framework.exceptions.MenuParseException;
import org.mifos.framework.exceptions.SystemException;
import org.mifos.framework.util.helpers.FilePaths;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * It parses xml, builds and return crude menu for application
 */
public class MenuParser {

    /**
     * Method to parse xml and return crude menu
     *
     * @return array of crude Menu objects
     */
    public static Menu[] parse() throws SystemException {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            SchemaFactory schfactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            schfactory.setErrorHandler(null);
            Schema schema = schfactory.newSchema(
                    new StreamSource(MifosResourceUtil.getClassPathResourceAsStream(FilePaths.MENUSCHEMA)));
            factory.setNamespaceAware(false);
            factory.setValidating(false);
            factory.setSchema(schema);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(MifosResourceUtil.getClassPathResourceAsStream(FilePaths.MENUPATH));
            NodeList tabNodeList = document.getElementsByTagName(MenuConstants.TOPMENUTAB);
            Menu leftMenus[] = new Menu[tabNodeList.getLength()];
            for (int i = 0; i < tabNodeList.getLength(); i++) {
                leftMenus[i] = new Menu();
                leftMenus[i].setTopMenuTabName(((Element) tabNodeList.item(i)).getAttribute(MenuConstants.NAME));
                leftMenus[i].setMenuGroups(createMenuGroup(tabNodeList.item(i)));
                String menuHeading = ((Element) tabNodeList.item(i))
                        .getElementsByTagName(MenuConstants.LEFTMENULABEL).item(0).getFirstChild().getTextContent()
                        .trim();
                leftMenus[i].setMenuHeading(menuHeading);
            }
            return leftMenus;
        } catch (SAXParseException spe) {
            throw new MenuParseException(spe);
        } catch (SAXException sxe) {
            throw new MenuParseException(sxe);
        } catch (ParserConfigurationException pce) {
            throw new MenuParseException(pce);
        } catch (IOException ioe) {
            throw new MenuParseException(ioe);
        }
    }

    /**
     * Method to build crude MenuGroup objects for a given top-menu-tab
     *
     * @param leftMenu
     *            is the root node for a top-menu-tab
     * @return array of MenuGroup objects
     */
    static MenuGroup[] createMenuGroup(Node leftMenu) throws SystemException {
        NodeList menuGpNodeList = ((Element) leftMenu).getElementsByTagName(MenuConstants.MENUGROUP);
        MenuGroup menuGroup[] = new MenuGroup[menuGpNodeList.getLength()];
        for (int i = 0; i < menuGpNodeList.getLength(); i++) {
            menuGroup[i] = new MenuGroup();
            menuGroup[i].setMenuItems(createMenuItems(menuGpNodeList.item(i)));
            menuGroup[i].setDisplayName(getDisplayName((Element) menuGpNodeList.item(i)));
        }
        return menuGroup;
    }

    /**
     * Method to build crude MenuItem objects for a MenuGroup
     *
     * @param menuGroup
     *            is the root node for MenuGroup.
     * @return array of MenuItem objects
     */
    static MenuItem[] createMenuItems(Node menuGroup) throws SystemException {
        NodeList menuItemNodeList = ((Element) menuGroup).getElementsByTagName(MenuConstants.MENUITEM);
        MenuItem menuItem[] = new MenuItem[menuItemNodeList.getLength()];
        int hiddenItems = 0;
        for (int i = 0, j = 0; i < menuItemNodeList.getLength(); i++) {
            if (isMenuItemVisible((Element) menuItemNodeList.item(i))) {
                menuItem[j] = new MenuItem();
                menuItem[j].setDisplayName(getDisplayName((Element) menuItemNodeList.item(i)));
                menuItem[j].setLinkValue(getLinkValue((Element) menuItemNodeList.item(i)));
                j++;
            } else {
                hiddenItems++;
            }
        }
        if (hiddenItems > 0) {
            menuItem = removeEmptyMenuItems(menuItem, hiddenItems);
        }
        return menuItem;
    }

    private static MenuItem[] removeEmptyMenuItems(MenuItem menuItems[], int hiddenItems) {
        MenuItem newMenuItems[] = new MenuItem[menuItems.length - hiddenItems];
        for (int i = 0, j = 0; i < menuItems.length; i++) {
            if (menuItems[i] != null) {
                newMenuItems[j++] = menuItems[i];
            }
        }
        return newMenuItems;
    }

    /**
     * Uses boolean keys in the application-wide configuration to determine if
     * menu items should be displayed. Missing keys will cause
     * {@link java.util.NoSuchElementException} to be thrown. Keys are
     * configured in menu.xml.
     */
    private static boolean isMenuItemVisible(Element element) {
        String visiKey = element.getAttribute(MenuConstants.KEY_FOR_HIDDEN);
        if (StringUtils.isNotBlank(visiKey)) {
            MifosConfigurationManager cm = MifosConfigurationManager.getInstance();
            return cm.getBoolean(visiKey);
        }
        // if attribute doesn't exist, a configuration key wasn't specified,
        // so menu item must be visible
        return true;
    }

    /**
     * Method to get all keys for a displayname of a given node
     *
     * @param node
     *            is the element whose display name is to be obtained
     * @return array of keys respective to display name
     */
    static String[] getDisplayName(Element node) {
        NodeList displaynameNodeList = node.getElementsByTagName(MenuConstants.DISPLAYNAME);
        NodeList nameNodeList = ((Element) displaynameNodeList.item(0))
                .getElementsByTagName(MenuConstants.NAMEFRAGMENT);
        String displayNameStr[] = new String[nameNodeList.getLength()];
        for (int i = 0; i < nameNodeList.getLength(); i++) {
            displayNameStr[i] = nameNodeList.item(i).getFirstChild().getTextContent().trim();
        }
        return displayNameStr;
    }

    /**
     * Method to get link value for a menu item
     *
     * @param node
     *            is the menu item whose link is to be obtained
     * @return link as string
     */
    static String getLinkValue(Element node) {
        return node.getElementsByTagName(MenuConstants.LINKVALUE).item(0).getFirstChild().getTextContent().trim();
    }
}