Java tutorial
///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2013 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.web; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.projectforge.access.AccessChecker; import org.projectforge.core.UserException; import org.projectforge.plugins.todo.ToDoPlugin; import org.projectforge.user.PFUserContext; import org.projectforge.user.UserXmlPreferencesCache; import org.projectforge.user.UserXmlPreferencesDO; import org.projectforge.web.core.NavAbstractPanel; /** * The customizable menu of the user (stored in the data-base and customizable). */ public class FavoritesMenu implements Serializable { public static final String USER_PREF_FAVORITES_MENU_KEY = "usersFavoritesMenu"; static final String USER_PREF_FAVORITES_MENU_ENTRIES_KEY = "usersFavoriteMenuEntries"; private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(FavoritesMenu.class); private static final long serialVersionUID = -4954464926815538198L; private List<MenuEntry> menuEntries; private Menu menu; private final AccessChecker accessChecker; private final UserXmlPreferencesCache userXmlPreferencesCache; public static FavoritesMenu get(final UserXmlPreferencesCache userXmlPreferencesCache, final AccessChecker accessChecker) { FavoritesMenu favoritesMenu = (FavoritesMenu) userXmlPreferencesCache .getEntry(USER_PREF_FAVORITES_MENU_KEY); if (favoritesMenu != null) { return favoritesMenu; } favoritesMenu = new FavoritesMenu(userXmlPreferencesCache, accessChecker); userXmlPreferencesCache.putEntry(USER_PREF_FAVORITES_MENU_KEY, favoritesMenu, false); return favoritesMenu; } /** * @param userXmlPreferencesCache For storing and getting the persisted favorites menu. * @param accessChecker For building the menu entries regarding the access rights of the logged-in user. */ FavoritesMenu(final UserXmlPreferencesCache userXmlPreferencesCache, final AccessChecker accessChecker) { this.menu = (Menu) userXmlPreferencesCache.getEntry(NavAbstractPanel.USER_PREF_MENU_KEY); this.userXmlPreferencesCache = userXmlPreferencesCache; this.accessChecker = accessChecker; init(); } public List<MenuEntry> getMenuEntries() { return this.menuEntries; } /** * Only for test cases. * @param menu the menu to set * @return this for chaining. */ FavoritesMenu setMenu(final Menu menu) { this.menu = menu; return this; } public void readFromXml(final String menuAsXml) { if (menu == null) { log.error("User's menu is null, can't get FavoritesMenu!"); return; } if (log.isDebugEnabled() == true) { log.debug("readFromXml: " + menuAsXml); } Document document = null; try { document = DocumentHelper.parseText(menuAsXml); } catch (final DocumentException ex) { log.error("Exception encountered " + ex, ex); return; } final MenuBuilderContext context = new MenuBuilderContext(menu, accessChecker, PFUserContext.getUser(), false); final Element root = document.getRootElement(); menuEntries = new ArrayList<MenuEntry>(); for (final Iterator<?> it = root.elementIterator("item"); it.hasNext();) { final Element item = (Element) it.next(); final MenuEntry menuEntry = readFromXml(item, context); menuEntries.add(menuEntry); } } private MenuEntry readFromXml(final Element item, final MenuBuilderContext context) { if ("item".equals(item.getName()) == false) { log.error("Tag 'item' expected instead of '" + item.getName() + "'. Ignoring this tag."); return null; } String id = item.attributeValue("id"); MenuItemDef menuItemDef = null; if (id != null && id.startsWith("c-") == true) { id = id.substring(2); } if (id != null && menu != null) { // menu is only null for FavoritesMenuTest. final MenuEntry origEntry = menu.findById(id); menuItemDef = origEntry != null ? origEntry.menuItemDef : null; } final MenuEntry menuEntry; if (menuItemDef != null) { menuEntry = menu.getMenuEntry(menuItemDef); } else { menuEntry = new MenuEntry(); } menuEntry.setSorted(false); if (item != null) { final String trimmedTitle = item.getTextTrim(); if (trimmedTitle != null) { // menuEntry.setName(StringEscapeUtils.escapeXml(trimmedTitle)); if (StringUtils.isBlank(trimmedTitle) == true) { menuEntry.setName("???"); } else { menuEntry.setName(trimmedTitle); } } } for (final Iterator<?> it = item.elementIterator("item"); it.hasNext();) { if (menuItemDef != null) { log.warn("Menu entry shouldn't have children, because it's a leaf node."); } final Element child = (Element) it.next(); final MenuEntry childMenuEntry = readFromXml(child, context); if (childMenuEntry != null) { menuEntry.addMenuEntry(childMenuEntry); } } return menuEntry; } private void init() { this.menuEntries = new ArrayList<MenuEntry>(); final String userPrefString = (String) userXmlPreferencesCache .getEntry(USER_PREF_FAVORITES_MENU_ENTRIES_KEY); if (StringUtils.isBlank(userPrefString) == false) { if (userPrefString.contains("<root>") == false) { // Old format: buildFromOldUserPrefFormat(userPrefString); } else { readFromXml(userPrefString); } } if (this.menuEntries.size() == 0) { final MenuItemRegistry registry = MenuItemRegistry.instance(); if (accessChecker.isLoggedInUserMemberOfAdminGroup() == true) { final MenuEntry adminMenu = new MenuEntry() .setName(PFUserContext.getLocalizedString(MenuItemDefId.ADMINISTRATION.getI18nKey())); menuEntries.add(adminMenu); addFavoriteMenuEntry(adminMenu, registry.get(MenuItemDefId.ACCESS_LIST)); addFavoriteMenuEntry(adminMenu, registry.get(MenuItemDefId.USER_LIST)); addFavoriteMenuEntry(adminMenu, registry.get(MenuItemDefId.GROUP_LIST)); addFavoriteMenuEntry(adminMenu, registry.get(MenuItemDefId.SYSTEM)); } if (accessChecker.isRestrictedUser() == true) { // Restricted users see only the change password menu entry (as favorite). addFavoriteMenuEntry(registry.get(MenuItemDefId.CHANGE_PASSWORD)); } else { final MenuEntry projectManagementMenu = new MenuEntry() .setName(PFUserContext.getLocalizedString(MenuItemDefId.PROJECT_MANAGEMENT.getI18nKey())); menuEntries.add(projectManagementMenu); addFavoriteMenuEntry(projectManagementMenu, registry.get(MenuItemDefId.MONTHLY_EMPLOYEE_REPORT)); addFavoriteMenuEntry(projectManagementMenu, registry.get(MenuItemDefId.TIMESHEET_LIST)); addFavoriteMenuEntry(registry.get(MenuItemDefId.TASK_TREE)); addFavoriteMenuEntry(registry.get(MenuItemDefId.CALENDAR)); addFavoriteMenuEntry(registry.get(MenuItemDefId.ADDRESS_LIST)); addFavoriteMenuEntry(registry.get(MenuItemDefId.BOOK_LIST)); addFavoriteMenuEntry(registry.get(MenuItemDefId.PHONE_CALL)); addFavoriteMenuEntry(registry.get(ToDoPlugin.ID)); } } } private void addFavoriteMenuEntry(final MenuEntry parent, final MenuItemDef menuItemDef) { if (menu == null) { return; } final MenuEntry menuEntry = menu.getMenuEntry(menuItemDef); if (menuEntry == null) { return; } parent.addMenuEntry(menuEntry); } private void addFavoriteMenuEntry(final MenuItemDef menuItemDef) { if (menu == null) { return; } final MenuEntry menuEntry = menu.getMenuEntry(menuItemDef); if (menuEntry == null) { return; } for (final MenuEntry entry : this.menuEntries) { if (entry.menuItemDef == menuItemDef) { // Entry does already exist, ignore it. return; } } this.menuEntries.add(menuEntry); } /** * @param userPrefEntry coma separated list of MenuItemDefs. */ void buildFromOldUserPrefFormat(final String userPrefEntry) { this.menuEntries = new ArrayList<MenuEntry>(); if (userPrefEntry == null) { return; } final StringTokenizer tokenizer = new StringTokenizer(userPrefEntry, ","); while (tokenizer.hasMoreTokens() == true) { String token = tokenizer.nextToken(); if (token.startsWith("M_") == true) { token = token.substring(2); } try { final MenuEntry origEntry = menu.findById(token); final MenuItemDef menuItemDef = origEntry != null ? origEntry.menuItemDef : null; if (menuItemDef == null) { continue; } addFavoriteMenuEntry(menuItemDef); } catch (final Exception ex) { log.info("Menu '" + token + "' not found: " + ex.getMessage(), ex); } } } public void storeAsUserPref() { if (CollectionUtils.isEmpty(menuEntries) == true) { userXmlPreferencesCache.putEntry(USER_PREF_FAVORITES_MENU_ENTRIES_KEY, "", true); userXmlPreferencesCache.removeEntry(USER_PREF_FAVORITES_MENU_KEY); return; } final Document document = DocumentHelper.createDocument(); final Element root = document.addElement("root"); for (final MenuEntry menuEntry : menuEntries) { buildElement(root.addElement("item"), menuEntry); } final String xml = document.asXML(); if (xml.length() > UserXmlPreferencesDO.MAX_SERIALIZED_LENGTH) { throw new UserException("menu.favorite.maxSizeExceeded"); } userXmlPreferencesCache.putEntry(USER_PREF_FAVORITES_MENU_ENTRIES_KEY, xml, true); userXmlPreferencesCache.putEntry(USER_PREF_FAVORITES_MENU_KEY, this, false); if (log.isDebugEnabled() == true) { log.debug("Favorites menu stored: " + xml); } log.info("Favorites menu stored: " + xml); } private void buildElement(final Element element, final MenuEntry menuEntry) { if (menuEntry.getId() != null) { element.addAttribute("id", menuEntry.getId()); } if (menuEntry.getName() != null) { element.addText(menuEntry.getName()); } if (menuEntry.hasSubMenuEntries() == true) { for (final MenuEntry subMenuEntry : menuEntry.getSubMenuEntries()) { buildElement(element.addElement("item"), subMenuEntry); } } } }