Package org.projectforge.user

Source Code of org.projectforge.user.GroupDao

/////////////////////////////////////////////////////////////////////////////
//
// 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.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.Validate;
import org.hibernate.LockMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.projectforge.access.AccessException;
import org.projectforge.access.AccessType;
import org.projectforge.access.OperationType;
import org.projectforge.core.BaseDao;
import org.projectforge.core.BaseSearchFilter;
import org.projectforge.core.QueryFilter;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
*
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
public class GroupDao extends BaseDao<GroupDO>
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(GroupDao.class);

  private static final String[] ADDITIONAL_SEARCH_FIELDS = new String[] { "assignedUsers.username", "assignedUsers.firstname",
  "assignedUsers.lastname"};

  private UserDao userDao;

  //private final GroupsProvider groupsProvider = new GroupsProvider();

  public void setUserDao(final UserDao userDao)
  {
    this.userDao = userDao;
  }

  public GroupDao()
  {
    super(GroupDO.class);
    this.supportAfterUpdate = true;
  }

  public QueryFilter getDefaultFilter()
  {
    final QueryFilter queryFilter = new QueryFilter();
    return queryFilter;
  }

  @Override
  public List<GroupDO> getList(final BaseSearchFilter filter)
  {
    final GroupFilter myFilter;
    if (filter instanceof GroupFilter) {
      myFilter = (GroupFilter) filter;
    } else {
      myFilter = new GroupFilter(filter);
    }
    final QueryFilter queryFilter = new QueryFilter(myFilter);
    if (Login.getInstance().hasExternalUsermanagementSystem() == true) {
      // Check hasExternalUsermngmntSystem because otherwise the filter is may-be preset for an user and the user can't change the filter
      // (because the fields aren't visible).
      if (myFilter.getLocalGroup() != null) {
        queryFilter.add(Restrictions.eq("localGroup", myFilter.getLocalGroup()));
      }
    }
    queryFilter.addOrder(Order.asc("name"));
    return getList(queryFilter);
  }

  /**
   * Does a group with the given name already exists? Works also for existing users (if group name was modified).
   * @param username
   * @return
   */
  @SuppressWarnings("unchecked")
  public boolean doesGroupnameAlreadyExist(final GroupDO group)
  {
    Validate.notNull(group);
    List<GroupDO> list = null;
    if (group.getId() == null) {
      // New group
      list = getHibernateTemplate().find("from GroupDO g where g.name = ?", group.getName());
    } else {
      // group already exists. Check maybe changed name:
      list = getHibernateTemplate().find("from GroupDO g where g.name = ? and pk <> ?", new Object[] { group.getName(), group.getId()});
    }
    if (CollectionUtils.isNotEmpty(list) == true) {
      return true;
    }
    return false;
  }

  /**
   * Please note: Any existing assigned user in group object is ignored!
   * @param group
   * @param assignedUsers Full list of all users which have to assigned to this group.
   * @return
   */
  public void setAssignedUsers(final GroupDO group, final Collection<PFUserDO> assignedUsers) throws AccessException
  {
    final Set<PFUserDO> origAssignedUsers = group.getAssignedUsers();
    if (origAssignedUsers != null) {
      final Iterator<PFUserDO> it = origAssignedUsers.iterator();
      while (it.hasNext() == true) {
        final PFUserDO user = it.next();
        if (assignedUsers.contains(user) == false) {
          it.remove();
        }
      }
    }
    for (final PFUserDO user : assignedUsers) {
      final PFUserDO dbUser = userDao.internalGetById(user.getId());
      if (dbUser == null) {
        throw new RuntimeException("User '"
            + user.getId()
            + "' not found. Could not add this unknown user to new group: "
            + group.getName());
      }
      if (origAssignedUsers == null || origAssignedUsers.contains(dbUser) == false) {
        group.addUser(dbUser);
      }
    }
  }

  //  /**
  //   * Please note: Only the string group.nestedGroups will be modified (but not be saved)!
  //   * @param group
  //   * @param nestedGroups Full list of all nested groups which have to assigned to this group.
  //   * @return
  //   */
  //  public void setNestedGroups(final GroupDO group, final Collection<GroupDO> nestedGroups)
  //  {
  //    if (group.isNestedGroupsAllowed() == false && CollectionUtils.isNotEmpty(nestedGroups) == true) {
  //      log.warn("Couldn't set nested groups because given group doesn't allow nested groups: " + group);
  //      group.setNestedGroupIds(null);
  //      return;
  //    }
  //    group.setNestedGroupIds(groupsProvider.getGroupIds(nestedGroups));
  //  }
  //
  //  public Collection<GroupDO> getSortedNestedGroups(final GroupDO group)
  //  {
  //    if (group.isNestedGroupsAllowed() == false && StringUtils.isNotEmpty(group.getNestedGroupIds()) == true) {
  //      log.warn("Ignore nested groups because given group doesn't allow nested groups: " + group);
  //      group.setNestedGroupIds(null);
  //      return null;
  //    }
  //    return groupsProvider.getSortedGroups(group.getNestedGroupIds());
  //  }

  /**
   * Creates for every user an history entry if the user is part of this new group.
   * @param group
   * @see org.projectforge.core.BaseDao#afterSave(org.projectforge.core.ExtendedBaseDO)
   */
  @Override
  public void afterSave(final GroupDO group)
  {
    final Collection<GroupDO> groupList = new ArrayList<GroupDO>();
    groupList.add(group);
    if (group.getAssignedUsers() != null) {
      // Create history entry of PFUserDO for all assigned users:
      for (final PFUserDO user : group.getAssignedUsers()) {
        createHistoryEntry(user, null, groupList);
      }
    }
  }

  /**
   * Creates for every user an history if the user is assigned or unassigned from this updated group.
   * @param group
   * @param dbGroup
   * @see org.projectforge.core.BaseDao#afterUpdate(GroupDO, GroupDO)
   */
  @Override
  protected void afterUpdate(final GroupDO group, final GroupDO dbGroup)
  {
    final Set<PFUserDO> origAssignedUsers = dbGroup.getAssignedUsers();
    final Set<PFUserDO> assignedUsers = group.getAssignedUsers();
    final Collection<PFUserDO> assignedList = new ArrayList<PFUserDO>(); // List of new assigned users.
    final Collection<PFUserDO> unassignedList = new ArrayList<PFUserDO>(); // List of unassigned users.
    for (final PFUserDO user : group.getAssignedUsers()) {
      if (origAssignedUsers.contains(user) == false) {
        assignedList.add(user);
      }
    }
    for (final PFUserDO user : dbGroup.getAssignedUsers()) {
      if (assignedUsers.contains(user) == false) {
        unassignedList.add(user);
      }
    }
    final Collection<GroupDO> groupList = new ArrayList<GroupDO>();
    groupList.add(group);
    // Create history entry of PFUserDO for all new assigned users:
    for (final PFUserDO user : assignedList) {
      createHistoryEntry(user, null, groupList);
    }
    // Create history entry of PFUserDO for all unassigned users:
    for (final PFUserDO user : unassignedList) {
      createHistoryEntry(user, groupList, null);
    }
  }

  /**
   * Assigns groups to and unassigns groups from given user.
   * @param user
   * @param groupsToAssign Groups to assign (nullable).
   * @param groupsToUnassign Groups to unassign (nullable).
   * @throws AccessException
   */
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
  public void assignGroups(final PFUserDO user, final Set<GroupDO> groupsToAssign, final Set<GroupDO> groupsToUnassign)
      throws AccessException
      {
    getHibernateTemplate().refresh(user, LockMode.READ);
    final List<GroupDO> assignedGroups = new ArrayList<GroupDO>();
    if (groupsToAssign != null) {
      for (final GroupDO group : groupsToAssign) {
        final GroupDO dbGroup = getHibernateTemplate().get(clazz, group.getId(), LockMode.PESSIMISTIC_WRITE);
        Set<PFUserDO> assignedUsers = dbGroup.getAssignedUsers();
        if (assignedUsers == null) {
          assignedUsers = new HashSet<PFUserDO>();
          dbGroup.setAssignedUsers(assignedUsers);
        }
        if (assignedUsers.contains(user) == false) {
          log.info("Assigning user '" + user.getUsername() + "' to group '" + dbGroup.getName() + "'.");
          assignedUsers.add(user);
          assignedGroups.add(dbGroup);
          dbGroup.setLastUpdate(); // Needed, otherwise GroupDO is not detected for hibernate history!
        } else {
          log.info("User '" + user.getUsername() + "' already assigned to group '" + dbGroup.getName() + "'.");
        }
      }
    }
    final List<GroupDO> unassignedGroups = new ArrayList<GroupDO>();
    if (groupsToUnassign != null) {
      for (final GroupDO group : groupsToUnassign) {
        final GroupDO dbGroup = getHibernateTemplate().get(clazz, group.getId(), LockMode.PESSIMISTIC_WRITE);
        final Set<PFUserDO> assignedUsers = dbGroup.getAssignedUsers();
        if (assignedUsers != null && assignedUsers.contains(user) == true) {
          log.info("Unassigning user '" + user.getUsername() + "' from group '" + dbGroup.getName() + "'.");
          assignedUsers.remove(user);
          unassignedGroups.add(dbGroup);
          dbGroup.setLastUpdate(); // Needed, otherwise GroupDO is not detected for hibernate history!
        } else {
          log.info("User '" + user.getUsername() + "' is not assigned to group '" + dbGroup.getName() + "' (can't unassign).");
        }
      }
    }
    getSession().flush();
    createHistoryEntry(user, unassignedGroups, assignedGroups);
    userGroupCache.setExpired();
      }

  private void createHistoryEntry(final PFUserDO user, Collection<GroupDO> unassignedList, Collection<GroupDO> assignedList)
  {
    if (unassignedList != null && unassignedList.size() == 0) {
      unassignedList = null;
    }
    if (assignedList != null && assignedList.size() == 0) {
      assignedList = null;
    }
    if (unassignedList == null && assignedList == null) {
      return;
    }
    createHistoryEntry(user, user.getId(), "assignedGroups", Collection.class, unassignedList, assignedList);
  }

  /**
   * Internal load of all tasks without checking any access.
   * @return
   */
  @SuppressWarnings("unchecked")
  @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
  List<GroupDO> loadAll()
  {
    final List<GroupDO> list = getHibernateTemplate().find("from GroupDO t join");
    return list;
  }

  @Override
  protected void afterSaveOrModify(final GroupDO group)
  {
    userGroupCache.setExpired();
  }

  /**
   * @see org.projectforge.core.BaseDao#afterDelete(org.projectforge.core.ExtendedBaseDO)
   */
  @Override
  protected void afterDelete(final GroupDO obj)
  {
    userGroupCache.setExpired();
  }

  @Override
  protected String[] getAdditionalSearchFields()
  {
    return ADDITIONAL_SEARCH_FIELDS;
  }

  /**
   * return Always true, no generic select access needed for group objects.
   * @see org.projectforge.core.BaseDao#hasSelectAccess()
   */
  @Override
  public boolean hasSelectAccess(final PFUserDO user, final boolean throwException)
  {
    return true;
  }

  /**
   * @return false, if no admin user and the context user is not member of the group. Also deleted groups are only visible for admin users.
   * @see org.projectforge.core.BaseDao#hasSelectAccess(org.projectforge.core.BaseDO, boolean)
   */
  @Override
  public boolean hasSelectAccess(final PFUserDO user, final GroupDO obj, final boolean throwException)
  {
    Validate.notNull(obj);
    boolean result = accessChecker.isUserMemberOfAdminGroup(user)
        || accessChecker.isUserMemberOfGroup(user, ProjectForgeGroup.FINANCE_GROUP, ProjectForgeGroup.CONTROLLING_GROUP);
    if (result == false && obj.isDeleted() == false) {
      Validate.notNull(user);
      result = userGroupCache.isUserMemberOfGroup(user.getId(), obj.getId());
    }
    if (throwException == true && result == false) {
      throw new AccessException(AccessType.GROUP, OperationType.SELECT);
    }
    return result;
  }

  /**
   * @see org.projectforge.core.BaseDao#hasAccess(Object, OperationType)
   */
  @Override
  public boolean hasAccess(final PFUserDO user, final GroupDO obj, final GroupDO oldObj, final OperationType operationType,
      final boolean throwException)
  {
    return accessChecker.isUserMemberOfAdminGroup(user, throwException);
  }

  @Override
  public boolean hasHistoryAccess(final PFUserDO user, final boolean throwException)
  {
    return accessChecker.isUserMemberOfAdminGroup(user, throwException);
  }

  /**
   * @see org.projectforge.core.BaseDao#hasInsertAccess(org.projectforge.user.PFUserDO)
   */
  @Override
  public boolean hasInsertAccess(final PFUserDO user)
  {
    return accessChecker.isUserMemberOfAdminGroup(user);
  }

  @Override
  public GroupDO newInstance()
  {
    return new GroupDO();
  }


  public GroupDO getByName(final String name)
  {
    if (name == null) {
      return null;
    }
    @SuppressWarnings("unchecked")
    final List<GroupDO> list = getHibernateTemplate().find("from GroupDO u where u.name = ?", name);
    if (CollectionUtils.isEmpty(list) == true) {
      return null;
    }
    return list.get(0);
  }
}
TOP

Related Classes of org.projectforge.user.GroupDao

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.