Package org.projectforge.web

Source Code of org.projectforge.web.MenuItemDef

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 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 org.apache.commons.lang.Validate;
import org.apache.wicket.Page;
import org.projectforge.access.AccessChecker;
import org.projectforge.user.PFUserDO;
import org.projectforge.user.ProjectForgeGroup;
import org.projectforge.user.UserRight;
import org.projectforge.user.UserRightAccessCheck;
import org.projectforge.user.UserRightId;
import org.projectforge.user.UserRightValue;
import org.projectforge.user.UserRights;
import org.projectforge.web.wicket.WicketApplication;

/**
* The menu is defined once. The user's personal menu is calculated by this menu definitions (which menu entries are visible and which not).
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
public class MenuItemDef implements Serializable
{
  private static final long serialVersionUID = 6793153590139785117L;

  private String id;

  private String i18nKey;

  private MenuItemDef parent, mobileParentMenu;

  private Class< ? extends Page> pageClass;

  private String url;

  private String[] params;

  private boolean newWindow;

  private Class< ? extends Page> mobilePageClass;

  private boolean visible = true;

  private ProjectForgeGroup[] visibleForGroups;

  private UserRightId requiredRightId;

  private UserRightValue[] requiredRightValues;

  private int orderNumber, mobileMenuOrderNumber;

  private boolean mobileMenuSupport = false;

  private boolean desktopMenuSupport = true;

  private boolean visibleForRestrictedUsers;

  /**
   * Overwrite this if you need special access checking.
   * @param context
   * @return true (at default).
   */
  protected boolean isVisible(final MenuBuilderContext context)
  {
    return visible;
  }

  public boolean isVisible()
  {
    return this.visible;
  }

  /**
   * @param visible
   * @return this for chaining.
   */
  public MenuItemDef setVisible(final boolean visible)
  {
    this.visible = visible;
    return this;
  }

  /**
   * Most menus aren't visibly for restrictedUsers.
   * @return the visibleByRestrictedUsers
   */
  public boolean isVisibleForRestrictedUsers()
  {
    return visibleForRestrictedUsers;
  }

  /**
   * @param visibleForRestrictedUsers the visibleByRestrictedUsers to set
   * @return this for chaining.
   */
  public MenuItemDef setVisibleForRestrictedUsers(final boolean visibleForRestrictedUsers)
  {
    this.visibleForRestrictedUsers = visibleForRestrictedUsers;
    return this;
  }

  /**
   * Creates a menu entry if the user has access to.
   * @return null if not visible otherwise the created MenuEntry.
   */
  protected MenuEntry createMenuEntry(final Menu menu, final MenuBuilderContext context)
  {
    if (visibleForRestrictedUsers == false && context.getLoggedInUser().isRestrictedUser() == true) {
      // Restricted users have not access to.
      return null;
    }
    if (context.isMobileMenu() == true && mobileMenuSupport == false) {
      // this menu item doesn't support the mobile menu.
      return null;
    }
    if (context.isMobileMenu() == false && desktopMenuSupport == false) {
      // this menu item doesn't support the desktop menu.
      return null;
    }
    if (requiredRightId != null && hasRight(context.getAccessChecker(), context.getLoggedInUser()) == false) {
      return null;
    }
    if (isVisible(context) == false) {
      return null;
    }
    final ProjectForgeGroup[] visibleForGroups = getVisibleForGroups();
    if (visibleForGroups != null
        && visibleForGroups.length > 0
        && context.getAccessChecker().isLoggedInUserMemberOfGroup(visibleForGroups) == false) {
      // Do nothing because menu is not visible for logged in user.
      return null;
    }
    final MenuEntry menuEntry = new MenuEntry(this, context);
    afterMenuEntryCreation(menuEntry, context);
    menuEntry.setMenu(menu);
    return menuEntry;
  }

  /**
   * Override this method if some modifications needed after a menu entry for an user's menu is created.
   * @param createdMenuEntry The fresh created menu entry (is never null).
   * @param context
   */
  protected void afterMenuEntryCreation(final MenuEntry createdMenuEntry, final MenuBuilderContext context)
  {
  }

  public MenuItemDef()
  {
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param pageClass The linked page class (if the user clicks on this menu entry).
   * @param requiredRightId Reduce the visibility of this menu entry (if wanted): which user right is required?
   * @param requiredRightValues Reducing the visibility: which right values are required?
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey,
      final Class< ? extends Page> pageClass, final UserRightId requiredRightId, final UserRightValue... requiredRightValues)
  {
    this(parent, id, orderNumber, i18nKey, pageClass, null, requiredRightId, requiredRightValues);
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param pageClass The linked page class (if the user clicks on this menu entry).
   * @param params Parameters used when calling the pageClass (PageParameters).
   * @param requiredRightId Reduce the visibility of this menu entry (if wanted): which user right is required?
   * @param requiredRightValues Reducing the visibility: which right values are required?
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey,
      final Class< ? extends Page> pageClass, final String[] params, final UserRightId requiredRightId,
      final UserRightValue... requiredRightValues)
  {
    this.parent = parent;
    this.id = id;
    this.orderNumber = orderNumber;
    this.i18nKey = i18nKey;
    this.pageClass = pageClass;
    this.params = params;
    this.requiredRightId = requiredRightId;
    this.requiredRightValues = requiredRightValues;
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param pageClass The linked page class (if the user clicks on this menu entry).
   * @param visibleForGroups Reduce the visibility of this menu entry (if wanted).
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey,
      final Class< ? extends Page> pageClass, final ProjectForgeGroup... visibleForGroups)
  {
    this(parent, id, orderNumber, i18nKey, pageClass, null, visibleForGroups);
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param pageClass The linked page class (if the user clicks on this menu entry).
   * @param params Parameters used when calling the pageClass (PageParameters).
   * @param visibleForGroups Reduce the visibility of this menu entry (if wanted).
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey,
      final Class< ? extends Page> pageClass, final String[] params, final ProjectForgeGroup... visibleForGroups)
  {
    this.parent = parent;
    this.id = id;
    this.orderNumber = orderNumber;
    this.i18nKey = i18nKey;
    this.pageClass = pageClass;
    this.params = params;
    this.visibleForGroups = visibleForGroups;
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param url The linked url (if the user clicks on this menu entry).
   * @param visibleForGroups Reduce the visibility of this menu entry (if wanted).
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey, final String url,
      final ProjectForgeGroup... visibleForGroups)
  {
    this(parent, id, orderNumber, i18nKey, url, false, visibleForGroups);
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param url The linked url (if the user clicks on this menu entry).
   * @param newWindow If true, then the link will be opened in a new browser window.
   * @param visibleForGroups Reduce the visibility of this menu entry (if wanted).
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey, final String url,
      final boolean newWindow, final ProjectForgeGroup... visibleForGroups)
  {
    this.parent = parent;
    this.id = id;
    this.orderNumber = orderNumber;
    this.i18nKey = i18nKey;
    this.url = url;
    this.newWindow = newWindow;
    this.visibleForGroups = visibleForGroups;
  }

  /**
   * A menu entry without a link (e. g. a parent menu entry).
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param visibleForGroups Reduce the visibility of this menu entry (if wanted).
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey,
      final ProjectForgeGroup... visibleForGroups)
  {
    this.parent = parent;
    this.id = id;
    this.orderNumber = orderNumber;
    this.i18nKey = i18nKey;
    this.visibleForGroups = visibleForGroups;
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param url The linked url (if the user clicks on this menu entry).
   * @param requiredRightId Reduce the visibility of this menu entry (if wanted): which user right is required?
   * @param requiredRightValues Reducing the visibility: which right values are required?
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey, final String url,
      final UserRightId requiredRightId, final UserRightValue... requiredRightValues)
  {
    this(parent, id, orderNumber, i18nKey, url, false, requiredRightId, requiredRightValues);
  }

  /**
   * @param parent The parent menu entry
   * @param id The unique id
   * @param orderNumber The order of the sibling menu entries is done implemented by this order number (ascending order).
   * @param i18nKey For displaying the menu entry localized.
   * @param url The linked url (if the user clicks on this menu entry).
   * @param newWindow If true, then the link will be opened in a new browser window.
   * @param requiredRightId Reduce the visibility of this menu entry (if wanted): which user right is required?
   * @param requiredRightValues Reducing the visibility: which right values are required?
   */
  public MenuItemDef(final MenuItemDef parent, final String id, final int orderNumber, final String i18nKey, final String url,
      final boolean newWindow, final UserRightId requiredRightId, final UserRightValue... requiredRightValues)
  {
    this.parent = parent;
    this.id = id;
    this.orderNumber = orderNumber;
    this.i18nKey = i18nKey;
    this.url = url;
    this.newWindow = newWindow;
    this.requiredRightId = requiredRightId;
    this.requiredRightValues = requiredRightValues;
  }

  /**
   * @return parent menu item definition or null if this definition represents a top level menu item.
   */
  public MenuItemDef getParent()
  {
    return parent;
  }

  /**
   * @return Id used for html markup and for referencing in config.xml.
   */
  public String getId()
  {
    return id;
  }

  /**
   * Order number for sorting menu entries.
   */
  public int getOrderNumber()
  {
    return orderNumber;
  }

  /**
   * If set to false then this menu entry will not be displayed in the classical web menu version. Default is true.
   * @param desktopMenuSupport
   */
  public void setDesktopMenuSupport(final boolean desktopMenuSupport)
  {
    this.desktopMenuSupport = desktopMenuSupport;
  }

  /**
   * Will be automatically set if any setter regarding mobile menu properties is calles (with not-null params), default is false.
   * @param mobileMenuSupport
   */
  public void setMobileMenuSupport(final boolean mobileMenuSupport)
  {
    this.mobileMenuSupport = mobileMenuSupport;
  }

  /**
   * Order number for sorting menu entries (mobile menu).
   */
  public int getMobileMenuOrderNumber()
  {
    return mobileMenuOrderNumber;
  }

  /**
   * @return The parent menu entry of the mobile menu.
   */
  public MenuItemDef getMobileParentMenu()
  {
    return mobileParentMenu;
  }

  /**
   * TODO: Not yet supported. The menu entry is set as a top level menu entry.
   * @param mobileParentEntry
   * @param mobileMenuOrderNumber
   * @return this for chaining.
   */
  public MenuItemDef setMobileMenu(final MenuItemDef mobileParentEntry, final Class< ? extends Page> mobilePageClass,
      final int mobileMenuOrderNumber)
  {
    this.mobileParentMenu = mobileParentEntry;
    setMobileMenu(mobilePageClass, mobileMenuOrderNumber);
    return this;
  }

  /**
   * Adds the given menu entry as root menu entry.
   * @param mobileParentEntry
   * @param mobileMenuOrderNumber
   * @return this for chaining.
   */
  public MenuItemDef setMobileMenu(final Class< ? extends Page> mobilePageClass, final int mobileMenuOrderNumber)
  {
    this.mobileMenuSupport = true;
    this.mobilePageClass = mobilePageClass;
    this.mobileMenuOrderNumber = mobileMenuOrderNumber;
    return this;
  }

  /**
   * @return Key used in the i18n resource bundle.
   */
  public String getI18nKey()
  {
    return i18nKey;
  }

  /**
   * @return Wicket page or null for non Wicket pages.
   */
  public Class< ? extends Page> getPageClass()
  {
    return pageClass;
  }

  /**
   * @param pageClass the pageClass to set
   * @return this for chaining.
   */
  public void setPageClass(final Class< ? extends Page> pageClass)
  {
    this.pageClass = pageClass;
  }

  /**
   * @return Wicket page or null for non Wicket pages.
   */
  public Class< ? extends Page> getMobilePageClass()
  {
    return mobilePageClass;
  }

  /**
   * @return true, if pageClass (Wicket page) is given otherwise false.
   */
  public boolean isWicketPage()
  {
    return this.pageClass != null;
  }

  public boolean hasUrl()
  {
    return url != null;
  }

  /**
   * @return true if this menu entry has a link (to a Wicket page or an url). Otherwise false (e. g. if this menu item def represents only a
   *         menu with sub menus).
   */
  public boolean isLink()
  {
    return isWicketPage() == true || hasUrl() == true;
  }

  /**
   * @return The url for non-Wicket pages (relative to "secure/") or the bookmarkable url for Wicket pages (relative to "wa/").
   */
  public String getUrl()
  {
    if (url == null) {
      // Late binding: may be this enum class was instantiated before WicketApplication was initialized.
      this.url = WicketApplication.getBookmarkableMountPath(this.pageClass);
    }
    return url;
  }

  public String[] getParams()
  {
    return params;
  }

  public boolean isNewWindow()
  {
    return newWindow;
  }

  public ProjectForgeGroup[] getVisibleForGroups()
  {
    return visibleForGroups;
  }

  public UserRightId getRequiredRightId()
  {
    return requiredRightId;
  }

  public UserRightValue[] getRequiredRightValues()
  {
    return requiredRightValues;
  }

  public boolean hasRight(final AccessChecker accessChecker, final PFUserDO loggedInUser)
  {
    if (requiredRightId == null || requiredRightValues == null) {
      // Should not occur, for security reasons deny at default.
      return false;
    }
    if (requiredRightValues.length == 0) {
      final UserRight right = UserRights.instance().getRight(requiredRightId);
      if (right instanceof UserRightAccessCheck< ? >) {
        Validate.notNull(loggedInUser);
        return (((UserRightAccessCheck< ? >) right).hasSelectAccess(loggedInUser) == true);
      } else {
        // Should not occur, for security reasons deny at default.
        return false;
      }
    }

    if (accessChecker.hasLoggedInUserRight(requiredRightId, false, requiredRightValues) == true) {
      return true;
    }
    return false;
  }

  @Override
  public String toString()
  {
    return id;
  }
}
TOP

Related Classes of org.projectforge.web.MenuItemDef

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.