Java tutorial
/* Copyright 2012 James Hu 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 net.sf.jabb.util.web; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.aop.framework.Advised; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.web.bind.annotation.RequestMapping; import net.sf.jabb.util.bean.StringKeyValueBean; import net.sf.jabb.util.col.MapValueFactory; import net.sf.jabb.util.col.PutIfAbsentMap; /** * Configuration information of a web application * @author James Hu * */ public class WebApplicationConfiguration implements InitializingBean, ApplicationContextAware { private static final Log log = LogFactory.getLog(WebApplicationConfiguration.class); protected List<String> mainMenuItems; protected List<StringKeyValueBean> supportedLocales; protected String defaultLocale; protected String jQueryTheme; protected ApplicationContext appContext; protected Map<String, WebMenuItem> menus; protected Map<String, Map<String, WebMenuItem>> menuItemPaths; // <menuName, <menuPath, WebMenuItem>> @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { appContext = applicationContext; } @Override public void afterPropertiesSet() throws Exception { scanForMenuItems(); } /** * Scan all the beans for menu items */ public void scanForMenuItems() { Map<String, Map<String, MenuItemExt>> allMenuItems = new PutIfAbsentMap<String, Map<String, MenuItemExt>>( new HashMap<String, Map<String, MenuItemExt>>(), new MapValueFactory<String, Map<String, MenuItemExt>>() { @Override public Map<String, MenuItemExt> createValue(String key) { return new TreeMap<String, MenuItemExt>(); } }); //new HashMap<String, Map<String, MenuItemExt>>(); // <menuName, <path, MenuItemExt>> // Get all beans that may have menu items defined Map<String, Object> beans = appContext.getBeansWithAnnotation(WebMenu.class); beans.putAll(appContext.getBeansWithAnnotation(RequestMapping.class)); // Find all menu items for (Object bean : beans.values()) { Class<?> beanClass; if (bean instanceof Advised) { // if EnhancerBySpringCGLIB beanClass = ((Advised) bean).getTargetClass(); } else { beanClass = bean.getClass(); } // Check class level annotations first RequestMapping classRequestMapping = beanClass.getAnnotation(RequestMapping.class); WebMenu classWebMenu = beanClass.getAnnotation(WebMenu.class); if (true) {//classWebMenu != null && classWebMenu.value().length() != 0){ // not hidden MenuItemExt classMenuItem = new MenuItemExt(classWebMenu, classRequestMapping); String basePath = classMenuItem.path != null ? classMenuItem.path : ""; if (classMenuItem.title != null && classMenuItem.title.length() > 0) { // it is also a visible menu item MenuItemExt existing = allMenuItems.get(classMenuItem.menuName).put(basePath, classMenuItem); if (existing != null) { log.error("Duplicated web menu item definitions in " + beanClass.getName() + ".\n\tExisting: " + existing + "\n\tCurrent: " + classMenuItem); } } // Then look into all the methods for (Method method : beanClass.getDeclaredMethods()) { RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class); WebMenu methodWebMenu = method.getAnnotation(WebMenu.class); if (methodWebMenu != null && methodWebMenu.value().length() != 0) { // not hidden MenuItemExt methodMenuItem = new MenuItemExt(methodWebMenu, methodRequestMapping, classMenuItem); if (methodMenuItem.menuName != null) { MenuItemExt existing = allMenuItems.get(methodMenuItem.menuName) .put(methodMenuItem.path, methodMenuItem); if (existing != null) { log.error("Duplicated web menu item definitions in " + beanClass.getName() + "." + method.toGenericString() + ".\n\tExisting: " + existing + "\n\tCurrent: " + methodMenuItem); } } } } } } // construct menu trees menus = new HashMap<String, WebMenuItem>(); menuItemPaths = new HashMap<String, Map<String, WebMenuItem>>(); for (Map.Entry<String, Map<String, MenuItemExt>> menuItems : allMenuItems.entrySet()) { String menuName = menuItems.getKey(); Map<String, MenuItemExt> items = menuItems.getValue(); WebMenuItem root = new WebMenuItem(); root.title = menuName; // for the root, set its title as menu name root.breadcrumbs = new ArrayList<WebMenuItem>(1); root.breadcrumbs.add(root); // root is the first in breadcrumbs menus.put(menuName, root); menuItemPaths.put(menuName, new HashMap<String, WebMenuItem>()); for (MenuItemExt itemExt : items.values()) { String path = itemExt.path; WebMenuItem parent = null; do { path = StringUtils.substringBeforeLast(path, "/"); if (path == null || path.indexOf('/') == -1) { parent = root; break; } parent = items.get(path); } while (parent == null); parent.addSubItem(itemExt); } // clean up the tree cleanUpMenuTree(root, menuName); log.info("Menu '" + menuName + "' loaded:\n" + root); } } /** * Convert MenuItemExt to WebMenuItem, and clean up all data * @param root */ protected void cleanUpMenuTree(WebMenuItem root, String menuName) { List<WebMenuItem> subMenu = root.getSubMenu(); List<WebMenuItem> rootBreadcrumbs = root.getBreadcrumbs(); if (subMenu != null && subMenu.size() > 0) { Collections.sort(subMenu); for (int i = 0; i < subMenu.size(); i++) { WebMenuItem item = subMenu.get(i); if (item instanceof MenuItemExt) { MenuItemExt itemExt = (MenuItemExt) item; item = itemExt.toWebMenuItem(); subMenu.set(i, item); menuItemPaths.get(menuName).put(itemExt.path, item); } item.breadcrumbs = new ArrayList<WebMenuItem>(); if (rootBreadcrumbs != null) { item.breadcrumbs.addAll(rootBreadcrumbs); } item.breadcrumbs.add(item); cleanUpMenuTree(item, menuName); } } } /** * Get the menu tree by the menu's name * @param menuName * @return */ public WebMenuItem getMenu(String menuName) { return menus.get(menuName); } /** * Get the default menu tree * @return */ public WebMenuItem getMenu() { return getMenu(""); } /** * Get the menu item by menu and path * @param menuName * @param path * @return */ public WebMenuItem getMenuItem(String menuName, String path) { try { return menuItemPaths.get(menuName).get(path); } catch (Exception e) { log.error("Error when getting menu item for: menuName='" + menuName + "', path='" + path + "'"); return null; } } /** * Get the menu item by path in default menu * @param path * @return */ public WebMenuItem getMenuItem(String path) { return getMenuItem("", path); } /** * @deprecated * @return */ public List<String> getMainMenuItems() { return mainMenuItems; } /** * @deprecated * @param mainMenuItems */ public void setMainMenuItems(List<String> mainMenuItems) { this.mainMenuItems = mainMenuItems; } public List<StringKeyValueBean> getSupportedLocales() { return supportedLocales; } public void setSupportedLocales(List<StringKeyValueBean> supportedLocales) { this.supportedLocales = supportedLocales; } public String getDefaultLocale() { return defaultLocale; } public void setDefaultLocale(String defaultLocale) { this.defaultLocale = defaultLocale; } public String getjQueryTheme() { return jQueryTheme; } public void setjQueryTheme(String jQueryTheme) { this.jQueryTheme = jQueryTheme; } }