org.projectforge.web.FavoritesMenu.java Source code

Java tutorial

Introduction

Here is the source code for org.projectforge.web.FavoritesMenu.java

Source

/////////////////////////////////////////////////////////////////////////////
//
// 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);
            }
        }
    }
}