Java tutorial
/* * XMLMenuLoader.java * * Copyright (c) 1998 - 2006 BusinessTechnology, Ltd. * All rights reserved * * This program is the proprietary and confidential information * of BusinessTechnology, Ltd. and may be used and disclosed only * as authorized in a license agreement authorizing and * controlling such use and disclosure * * Millennium ERP system. * */ package com.mg.framework.support.ui; import com.mg.framework.api.ApplicationException; import com.mg.framework.api.Logger; import com.mg.framework.api.ui.MenuCommand; import com.mg.framework.utils.MiscUtils; import com.mg.framework.utils.ServerUtils; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.ElementHandler; import org.dom4j.ElementPath; import org.dom4j.io.SAXReader; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Stack; /** * , ? ?? ? {@link * #XMLMenuLoader.AbstractHandler} * * @author Oleg V. Safonov * @version $Id: XMLMenuLoader.java,v 1.4 2008/04/09 14:34:01 safonov Exp $ */ public class XMLMenuLoader { /** * ?? ? ?? ? */ private static final String GLOBAL_MENU = "/conf/GlobalMenu.xml"; //$NON-NLS-1$ /** * ? ? ?? */ private static final String ACTION = "action"; //$NON-NLS-1$ /** * ? ? ? ? */ private static final String TEXT = "text"; //$NON-NLS-1$ /** * ? ? ? */ private static final String MENU_ITEM = "menuItem"; //$NON-NLS-1$ /** * ? ? */ private static final String MENU = "menu"; //$NON-NLS-1$ /** * ? ? ? */ private static final String SEPARATOR = "separator"; //$NON-NLS-1$ /** * ? ? ? */ private static final String NAME_ATTR = "name"; //$NON-NLS-1$ /** * */ private static final String DEFAULT_LOCALE = "ru_RU"; //$NON-NLS-1$ ? ? /** * ? ? ?? */ private static final String ACTION_PARAM = "param"; //$NON-NLS-1$ /** * ? ? ?? ? */ private static final String ACTION_CODE = "code"; //$NON-NLS-1$ private static Logger logger = ServerUtils.getLogger(XMLMenuLoader.class); private URL descriptor; private SAXReader parser; private Stack<Object> menus = new Stack<Object>(); private Object currentMenuItem = null; private String localeStr = DEFAULT_LOCALE; private Object rootItem = null; public XMLMenuLoader(AbstractHandler handler, URL descriptor, Locale locale) { handler.loader = this; if (descriptor != null) this.descriptor = descriptor; else try { this.descriptor = new File(ServerUtils.MBSA_CUSTOM_LOCATION.concat(GLOBAL_MENU)).toURI().toURL(); } catch (MalformedURLException e) { throw new IllegalArgumentException("Menu descriptor not found", e); //$NON-NLS-1$ } if (this.descriptor == null) throw new IllegalArgumentException("Menu descriptor is null"); //$NON-NLS-1$ if (locale != null) localeStr = locale.toString(); parser = new SAXReader(); parser.setDefaultHandler(handler); } public static Object build(AbstractHandler handler, URL descriptor, Locale locale) { XMLMenuLoader loader = new XMLMenuLoader(handler, descriptor, locale); loader.parse(); return loader.getRootItem(); } private void parse() { try { parser.read(descriptor); } catch (DocumentException e) { throw new ApplicationException(e); } } private Object getRootItem() { return rootItem; } /** * @author Oleg V. Safonov * @version $Id: XMLMenuLoader.java,v 1.4 2008/04/09 14:34:01 safonov Exp $ */ public static abstract class AbstractHandler implements ElementHandler { private XMLMenuLoader loader; /** * * * @return */ abstract protected Object createMenu(); /** * ? * * @return ? */ abstract protected Object createMenuItem(); /** * ? ? * * @param menuItem ? * @param text ? */ abstract protected void adjustText(Object menuItem, String text); /** * ? ? ? * * @param menuItem ? * @param action ? */ abstract protected void adjustAction(Object menuItem, MenuCommand action); /** * ? ?? * * @param menuItem ? * @param element ? XML ?? ? */ abstract protected void adjustProperties(Object menuItem, Element element); /** * ? ? * * @param menu * @param menuItem ? */ abstract protected void addMenuItem(Object menu, Object menuItem); /** * ? * * @param menu */ abstract protected void addMenuSeparator(Object menu); private void parseMenu(Element element) { Object menu = createMenu(); if (loader.menus.size() != 0) addMenuItem(loader.menus.peek(), menu); loader.menus.push(menu); //? ? ? if (loader.rootItem == null) loader.rootItem = menu; } private void parseMenuItem(Element element) { if (element.attributeValue(NAME_ATTR).equals(SEPARATOR)) { addMenuSeparator(loader.menus.peek()); return; } Object menuItem = createMenuItem(); adjustProperties(menuItem, element); addMenuItem(loader.menus.peek(), menuItem); loader.currentMenuItem = menuItem; //? ? ? if (loader.rootItem == null) loader.rootItem = menuItem; } private void parseText(Element element) { String text; Element captionTextElement = (Element) element.selectSingleNode(loader.localeStr); if (captionTextElement != null) text = captionTextElement.getStringValue(); // ? else { Element parent = element.getParent(); text = parent != null ? parent.attributeValue("name") : element.getName(); } if (loader.currentMenuItem == null) adjustText(loader.menus.peek(), text); else adjustText(loader.currentMenuItem, text); } private void parseAction(Element element) { //? ? ? ? if (loader.currentMenuItem == null) return; try { MenuCommand action = (MenuCommand) ServerUtils.loadClass(element.attributeValue(ACTION_CODE, "")) //$NON-NLS-1$ .newInstance(); List<Element> list = MiscUtils.convertUncheckedList(Element.class, element.elements(ACTION_PARAM)); Map<String, String> params = new HashMap<String, String>(); for (Element param : list) params.put(param.attributeValue(NAME_ATTR), param.getStringValue()); action.init(params); adjustAction(loader.currentMenuItem, action); } catch (Throwable e) { logger.error("Create menu action failed", e); //$NON-NLS-1$ } } /* (non-Javadoc) * @see org.dom4j.ElementHandler#onStart(org.dom4j.ElementPath) */ public final void onStart(ElementPath path) { Element element = path.getCurrent(); if (element.getName().equals(MENU)) parseMenu(element); else if (element.getName().equals(MENU_ITEM)) parseMenuItem(element); } /* (non-Javadoc) * @see org.dom4j.ElementHandler#onEnd(org.dom4j.ElementPath) */ public final void onEnd(ElementPath path) { Element element = path.getCurrent(); if (element.getName().equals(MENU)) { adjustProperties(loader.menus.peek(), element); loader.menus.pop(); } else if (element.getName().equals(MENU_ITEM)) { adjustProperties(loader.currentMenuItem, element); loader.currentMenuItem = null; } else if (element.getName().equals(TEXT)) parseText(element); else if (element.getName().equals(ACTION)) parseAction(element); } } }