/////////////////////////////////////////////////////////////////////////////
//
// 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.user;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* Right depending on the member-ship of at least one group.
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
public class UserGroupsRight extends UserRight implements Serializable
{
private static final long serialVersionUID = 5686379506538006417L;
protected ProjectForgeGroup[] dependsOnGroups;
/**
* Optional available values for single groups for reducing the rights. E. g. some groups have only READ_ONLY access.
*/
protected Map<ProjectForgeGroup, UserRightValue[]> availableGroupRightValues;
/**
* @param id
* @param dependsOnGroups At least one of these groups is required for enabling this right (visibility)
*/
public UserGroupsRight(final UserRightId id, final UserRightCategory category, final UserRightValue[] values,
final ProjectForgeGroup... dependsOnGroups)
{
super(id, category);
this.dependsOnGroups = dependsOnGroups;
this.values = values;
}
/**
* @return false if the logged in user is not a member of the dependent groups, otherwise super.isAvailable(...).
* @see org.projectforge.user.UserRight#isAvailable(org.projectforge.access.AccessChecker)
*/
@Override
public boolean isAvailable(final UserGroupCache userGroupCache, final PFUserDO user)
{
if (userGroupCache.isUserMemberOfGroup(user, dependsOnGroups) == true) {
return super.isAvailable(userGroupCache, user);
}
return false;
}
/**
* Checks first {@link #isAvailable(UserGroupCache, PFUserDO)}. Checks then if the right value is available for one of the user groups. If
* no right value found for all of the user's groups then return false.
* @see org.projectforge.user.UserRight#isAvailable(org.projectforge.user.UserGroupCache, org.projectforge.user.PFUserDO,
* org.projectforge.user.UserRightValue)
*/
@Override
public boolean isAvailable(final UserGroupCache userGroupCache, final PFUserDO user, final UserRightValue value)
{
if (availableGroupRightValues == null) {
return isAvailable(userGroupCache, user);
}
if (isAvailable(userGroupCache, user) == false) {
return false;
}
for (final ProjectForgeGroup group : dependsOnGroups) {
final UserRightValue[] vals = availableGroupRightValues.get(group);
if (vals != null) {
for (final UserRightValue val : vals) {
if (val == value) {
if (userGroupCache.isUserMemberOfGroup(user, group) == true) {
return true;
}
}
}
} else {
// All right values are available for this group:
if (userGroupCache.isUserMemberOfGroup(user, group) == true) {
return true;
}
}
}
return false;
}
/**
* If the user is a member of one group for which only one value is available and this single value matches the given value then true is
* returned. This is use-full if the user is member of a group for which all members should have access automatically independent on the
* user's setting.
* @see org.projectforge.user.UserRight#matches(org.projectforge.user.UserGroupCache, org.projectforge.user.PFUserDO,
* org.projectforge.user.UserRightValue)
*/
@Override
public boolean matches(final UserGroupCache userGroupCache, final PFUserDO user, final UserRightValue value)
{
if (availableGroupRightValues == null) {
return false;
}
for (final ProjectForgeGroup group : dependsOnGroups) {
if (userGroupCache.isUserMemberOfGroup(user, group) == false) {
continue;
}
final UserRightValue[] vals = availableGroupRightValues.get(group);
if (vals != null && vals.length == 1 && vals[0] == value) {
return true;
}
}
for (Entry<ProjectForgeGroup, UserRightValue[]> entry : this.availableGroupRightValues.entrySet()) {
// Check all group right values.
final ProjectForgeGroup group = entry.getKey();
if (userGroupCache.isUserMemberOfGroup(user, group) == false) {
// User is not member of this group, skip this group.
continue;
}
final UserRightValue[] vals = availableGroupRightValues.get(group);
if (vals != null && vals.length == 1 && vals[0] == value) {
// For this group only one value is set so this value is automatically available for the user.
return true;
}
}
return false;
}
/**
* Convenience method for allowing only READONLY right value for the ProjectForgeGroup.CONTROLLING_GROUP.
* @return
*/
public UserGroupsRight setReadOnlyForControlling()
{
setAvailableGroupRightValues(ProjectForgeGroup.CONTROLLING_GROUP, UserRightValue.READONLY);
return this;
}
/**
* Use this for reducing the availability of right values for groups. If not set for one group then all right values are available.
* @param group The group for setting the available right values.
* @param values The available right values.
* @return
*/
public UserGroupsRight setAvailableGroupRightValues(final ProjectForgeGroup group, final UserRightValue... values)
{
synchronized (this) {
if (availableGroupRightValues == null) {
availableGroupRightValues = new HashMap<ProjectForgeGroup, UserRightValue[]>();
}
}
availableGroupRightValues.put(group, values);
return this;
}
}