/** * Copyright (C) 2011 JTalks.org Team * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library 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 * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jtalks.jcommune.service.transactional; import com.google.common.collect.Sets; import org.jtalks.common.model.entity.Group; import org.jtalks.common.model.entity.User; import org.jtalks.common.service.exceptions.NotFoundException; import org.jtalks.common.service.transactional.AbstractTransactionalEntityService; import org.jtalks.common.validation.ValidationError; import org.jtalks.common.validation.ValidationException; import org.jtalks.jcommune.model.dao.GroupDao; import org.jtalks.jcommune.model.dao.UserDao; import org.jtalks.jcommune.model.dto.GroupAdministrationDto; import org.jtalks.jcommune.model.dto.PageRequest; import org.jtalks.jcommune.model.dto.SecurityGroupList; import org.jtalks.jcommune.model.dto.UserDto; import org.jtalks.jcommune.model.entity.JCUser; import org.jtalks.jcommune.model.entity.UserInfo; import org.jtalks.jcommune.service.GroupService; import org.jtalks.jcommune.service.exceptions.OperationIsNotAllowedException; import org.jtalks.jcommune.service.security.AdministrationGroup; import org.jtalks.jcommune.service.security.SecurityService; import org.jtalks.jcommune.service.security.acl.AclManager; import org.jtalks.jcommune.service.security.acl.sids.UserGroupSid; import org.jtalks.jcommune.service.security.acl.sids.UserSid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import ru.javatalks.utils.general.Assert; import java.util.List; /** * @author alexander afanasiev * @author stanislav bashkirtsev */ public class TransactionalGroupService extends AbstractTransactionalEntityService<Group, GroupDao> implements GroupService { private final AclManager manager; private final UserDao userDao; private final SecurityService securityService; private final Logger logger = LoggerFactory.getLogger(getClass()); /** * Create an instance of entity based service * * @param groupDao - data access object, which should be able do all CRUD * operations. * @param manager - ACL manager to operate with sids * @param userDao - to perform all CRUD operations with users * @param securityService - to get current user information. * */ public TransactionalGroupService(GroupDao groupDao, AclManager manager, UserDao userDao, SecurityService securityService) { this.dao = groupDao; this.manager = manager; this.userDao = userDao; this.securityService = securityService; } /** * {@inheritDoc} */ @Override public List<Group> getAll() { return dao.getAll(); } @Override public SecurityGroupList getSecurityGroups() { return new SecurityGroupList(dao.getAll()).withAnonymousGroup(); } /** * {@inheritDoc} */ @Override public List<Group> getByNameContains(String name) { return dao.getByNameContains(name); } /** * {@inheritDoc} */ @Override public List<Group> getByName(String name) { return dao.getByName(name); } @Override public Page<UserDto> getPagedGroupUsers(long id, PageRequest pageRequest) { int totalCount = dao.getGroupUserCount(id); pageRequest.adjustPageNumber(totalCount); return new PageImpl<>(dao.getGroupUsersPage(id, pageRequest), pageRequest, totalCount); } /** * {@inheritDoc} */ @Override public void deleteGroup(Group group) throws NotFoundException { Assert.throwIfNull(group, "group"); if (!isGroupEditable(group.getName())) { logger.warn("Attempt to delete pre-defined usergoup {}", group.getName()); throw new OperationIsNotAllowedException("Pre-defined usergoup " + group.getName() + " cannot be deleted"); } for (User user : group.getUsers()) { user.getGroups().remove(group); userDao.saveOrUpdate((JCUser) user); } dao.delete(group); UserInfo currentUser = securityService.getCurrentUserBasicInfo(); UserGroupSid sid = new UserGroupSid(group); UserSid sidHeier = new UserSid(currentUser); try { manager.deleteSid(sid, sidHeier); } catch (EmptyResultDataAccessException noSidError) { throw new NotFoundException(); } } /** * {@inheritDoc} */ @Override public void saveGroup(Group group) { Assert.throwIfNull(group, "group"); group.setName(group.getName().trim()); dao.saveOrUpdate(group); } /** * {@inheritDoc} */ @Override public void saveOrUpdate(GroupAdministrationDto dto) throws NotFoundException { assertGroupNameUnique(dto); Group group = dto.getId() != null ? dao.get(dto.getId()) : new Group(); if (group == null) { throw new NotFoundException("Group with id " + dto.getId() + " is not found"); } if (!isGroupEditable(group.getName())) { logger.warn("Attempt to edit pre-defined usergoup {}", group.getName()); throw new OperationIsNotAllowedException("Pre-defined usergoup " + group.getName() + " is not editable"); } dao.saveOrUpdate(dto.fillEntity(group)); } /** * {@inheritDoc} */ @Override public List<GroupAdministrationDto> getGroupNamesWithCountOfUsers() { List<GroupAdministrationDto> groupNamesWithCountOfUsers = dao.getGroupNamesWithCountOfUsers(); setEditableFlag(groupNamesWithCountOfUsers); return groupNamesWithCountOfUsers; } private void setEditableFlag(List<GroupAdministrationDto> groups) { for (GroupAdministrationDto dto : groups) { dto.setEditable(isGroupEditable(dto.getName())); } } private boolean isGroupEditable(String groupName) { return !AdministrationGroup.isPredefinedGroup(groupName); } /** * Checks group name for uniqueness. * @throws ValidationException if group name is already used */ private void assertGroupNameUnique(GroupAdministrationDto dto) { Group existingGroup = dao.getGroupByName(dto.getName()); if (!(existingGroup == null || (dto.getId() != null && existingGroup.getId() == dto.getId()))) { throw new ValidationException(Sets.newHashSet((new ValidationError("name", "group.already_exists")))); } } }