/**
* 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 org.jtalks.common.model.dao.GroupDao;
import org.jtalks.common.model.entity.Group;
import org.jtalks.common.model.entity.Section;
import org.jtalks.common.model.permissions.BranchPermission;
import org.jtalks.common.model.permissions.JtalksPermission;
import org.jtalks.jcommune.model.dao.BranchDao;
import org.jtalks.jcommune.model.dao.SectionDao;
import org.jtalks.jcommune.model.dao.TopicDao;
import org.jtalks.jcommune.model.dto.GroupsPermissions;
import org.jtalks.jcommune.model.dto.PermissionChanges;
import org.jtalks.jcommune.model.entity.Branch;
import org.jtalks.jcommune.model.entity.Topic;
import org.jtalks.jcommune.plugin.api.service.PluginBranchService;
import org.jtalks.jcommune.service.BranchLastPostService;
import org.jtalks.jcommune.service.BranchService;
import org.jtalks.jcommune.service.TopicModificationService;
import org.jtalks.jcommune.plugin.api.exceptions.NotFoundException;
import org.jtalks.jcommune.service.security.AdministrationGroup;
import org.jtalks.jcommune.service.security.PermissionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import java.util.*;
/**
* The implementation of BranchService
*
* @author Vitaliy Kravchenko
* @author Max Malakhov
* @author masyan
*/
public class TransactionalBranchService extends AbstractTransactionalEntityService<Branch, BranchDao>
implements BranchService, PluginBranchService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private SectionDao sectionDao;
private GroupDao groupDao;
private TopicDao topicDao;
private TopicModificationService topicService;
private PermissionService permissionService;
private BranchLastPostService lastPostService;
/**
* Create an instance of entity based service
*
* @param branchDao data access object, which should be able do all CRUD operations.
* @param sectionDao used for checking branch existence.
* @param topicDao data access object for operations with topics
* @param topicService service to perform complex operations with topics
* @param permissionService service to perform permissions operations
*/
public TransactionalBranchService(
BranchDao branchDao,
SectionDao sectionDao,
TopicDao topicDao,
GroupDao groupDao,
TopicModificationService topicService,
PermissionService permissionService,
BranchLastPostService lastPostService) {
super(branchDao);
this.sectionDao = sectionDao;
this.topicDao = topicDao;
this.topicService = topicService;
this.permissionService = permissionService;
this.groupDao = groupDao;
this.lastPostService = lastPostService;
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#branchId, 'BRANCH', 'BranchPermission.VIEW_TOPICS') " +
"or hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public Branch getBranchOfComponent(long componentId, long branchId) throws NotFoundException {
return super.get(branchId);
}
/**
* {@inheritDoc}
*/
@Override
public List<Branch> getAllAvailableBranches(long currentTopicId) {
List<Section> allSections = sectionDao.getAll();
List<Branch> allBranches = new ArrayList<>();
for (Section section : allSections) {
allBranches.addAll((List) section.getBranches());
}
return getBranchesWithViewPermission(currentTopicId, allBranches);
}
/**
* {@inheritDoc}
*/
@Override
public List<Branch> getAvailableBranchesInSection(long sectionId, long currentTopicId) throws NotFoundException {
if (!sectionDao.isExist(sectionId)) {
throw new NotFoundException("Section with id: " + sectionId + " not found");
}
Section section = sectionDao.get(sectionId);
List<Branch> branches = (List) section.getBranches();
return getBranchesWithViewPermission(currentTopicId, branches);
}
private List<Branch> getBranchesWithViewPermission(Long topicId, List<Branch> branches) {
Topic topic = topicDao.get(topicId);
List<Branch> result = new ArrayList<>();
for (Branch branch : branches) {
if (permissionService.hasBranchPermission(branch.getId(), BranchPermission.VIEW_TOPICS)) {
result.add(branch);
}
}
result.remove(topic.getBranch());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public void fillStatisticInfo(List<org.jtalks.common.model.entity.Branch> branches) {
for (org.jtalks.common.model.entity.Branch commonBranch : branches) {
Branch jcommuneBranch = (Branch) commonBranch;
int postsCount = getDao().getCountPostsInBranch(jcommuneBranch);
jcommuneBranch.setPostsCount(postsCount);
int topicsCount = topicDao.countTopics(jcommuneBranch);
jcommuneBranch.setTopicsCount(topicsCount);
if (jcommuneBranch.getLastPost() == null) {
lastPostService.refreshLastPostInBranch(jcommuneBranch);
}
//TODO Was removed till milestone 2 due to performance issues
// JCUser user = userService.getCurrentUser();
// if (!user.isAnonymous()) {
// boolean isUnreadPosts = getDao().isUnreadPostsInBranch(jcommuneBranch, user);
// jcommuneBranch.setUnreadPosts(isUnreadPosts);
// }
}
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#id, 'BRANCH', 'BranchPermission.VIEW_TOPICS')")
public Branch get(Long id) throws NotFoundException {
return super.get(id);
}
/**
* {@inheritDoc}
*/
@Override
public Branch deleteAllTopics(long branchId) throws NotFoundException {
Branch branch = get(branchId);
// Create tmp list to avoid ConcurrentModificationException
List<Topic> loopList = new ArrayList<>(branch.getTopics());
for (Topic topic : loopList) {
topicService.deleteTopicSilent(topic.getId());
}
logger.info("All topics for branch \"{}\" were deleted. " +
"Branch id: {}", branch.getName(), branch.getId());
return branch;
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public void changeBranchInfo(long componentId, long branchId, String title, String description)
throws NotFoundException {
Branch branch = get(branchId);
branch.setName(title);
branch.setDescription(description);
getDao().saveOrUpdate(branch);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public void createNewBranch(long componentId, long sectionId, String title, String description) {
Section section = sectionDao.get(sectionId);
Branch branch = new Branch(title, description);
branch.setSection(section);
section.addOrUpdateBranch(branch);
sectionDao.saveOrUpdate(section);
//add default permission to view topics (for group Registered users)
Group registeredUsersGroup = groupDao.getGroupByName(AdministrationGroup.USER.getName());
Collection<Group> groups = Arrays.asList(registeredUsersGroup);
PermissionChanges permissionChanges = new PermissionChanges(BranchPermission.VIEW_TOPICS, groups,
Collections.<Group>emptyList());
permissionService.changeGrants(branch, permissionChanges);
}
/**
* {@inheritDoc}
*/
@Override
public void checkIfBranchExists(long branchId) throws NotFoundException {
super.get(branchId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public GroupsPermissions getPermissionsFor(long componentId, long branchId)
throws NotFoundException {
return permissionService.getPermissionsFor(get(branchId));
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public <T extends JtalksPermission> List<Group> getPermissionGroupsFor(long componentId, long branchId, boolean allowed, T permission)
throws NotFoundException {
GroupsPermissions allPermissions = permissionService.getPermissionsFor(get(branchId));
if (allowed) {
return allPermissions.getAllowed(permission);
}
return allPermissions.getRestricted(permission);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize("hasPermission(#componentId, 'COMPONENT', 'GeneralPermission.ADMIN')")
public void changeBranchPermissions(long componentId, long branchId, boolean allowed, PermissionChanges changes)
throws NotFoundException {
Branch branch = get(branchId);
if (allowed) {
permissionService.changeGrants(branch, changes);
} else {
permissionService.changeRestrictions(branch, changes);
}
}
}