/** * 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 ch.lambdaj.function.closure.Closure1; import org.jtalks.common.model.dao.Crud; import org.jtalks.common.model.dao.GroupDao; import org.jtalks.common.model.permissions.GeneralPermission; import org.jtalks.jcommune.model.entity.Poll; import org.jtalks.jcommune.model.entity.PollItem; import org.jtalks.jcommune.service.PollService; import org.jtalks.jcommune.service.UserService; import org.jtalks.jcommune.service.security.AdministrationGroup; import org.jtalks.jcommune.service.security.SecurityService; import org.springframework.security.access.prepost.PreAuthorize; import java.util.List; import java.util.ListIterator; import static ch.lambdaj.Lambda.*; /** * The implementation of the {@link PollService}. * * @author Anuar Nurmakanov * @author Alexandre Teterin * @see org.jtalks.jcommune.model.entity.Poll */ public class TransactionalPollService extends AbstractTransactionalEntityService<Poll, Crud<Poll>> implements PollService { private Crud<PollItem> pollOptionDao; private GroupDao groupDao; private SecurityService securityService; private UserService userService; /** * Create an instance of service for operations with a poll. * * @param pollDao data access object, which should be able do * all CRUD operations with {@link org.jtalks.jcommune.model.entity.Poll}. * @param groupDao this dao returns user group for permission granting * @param pollOptionDao data access object, which should be able do * all CRUD operations with {@link org.jtalks.jcommune.model.entity.PollItem}. * @param securityService the service for security operations * @param userService to fetch the user currently logged in */ public TransactionalPollService(Crud<Poll> pollDao, GroupDao groupDao, Crud<PollItem> pollOptionDao, SecurityService securityService, UserService userService) { super(pollDao); this.pollOptionDao = pollOptionDao; this.groupDao = groupDao; this.securityService = securityService; this.userService = userService; } /** * {@inheritDoc} */ @Override @PreAuthorize("hasPermission(#pollId, 'POLL', 'GeneralPermission.WRITE')") public Poll vote(Long pollId, List<Long> selectedOptionsIds) { Poll poll = getDao().get(pollId); if (poll.isActive()) { prohibitRevote(poll); for (PollItem option : poll.getPollItems()) { if (selectedOptionsIds.contains(option.getId())) { option.increaseVotesCount(); pollOptionDao.saveOrUpdate(option); } } } return poll; } /** * {@inheritDoc} */ @Override public void createPoll(Poll poll) { this.getDao().saveOrUpdate(poll); Closure1<PollItem> closure = closure(PollItem.class); of(pollOptionDao).saveOrUpdate(var(PollItem.class)); closure.each(poll.getPollItems()); securityService.createAclBuilder().grant(GeneralPermission.WRITE) .to(groupDao.getGroupByName(AdministrationGroup.USER.getName())) .on(poll).flush(); } /** * {@inheritDoc} */ @Override public void mergePollItems(Poll poll, List<PollItem> newItems) { List<PollItem> existing = poll.getPollItems(); ListIterator<PollItem> updated = newItems.listIterator(); while (updated.hasNext()) { PollItem item = updated.next(); for (PollItem old : existing) { if (item.getName().equals(old.getName())) { updated.set(old); } } } existing.clear(); existing.addAll(newItems); } /** * Prohibit the re-vote. In this poll a user will no longer be able to participate. * * @param poll a poll, in which the user will no longer be able to participate */ private void prohibitRevote(final Poll poll) { securityService.createAclBuilder().restrict(GeneralPermission.WRITE). to(userService.getCurrentUser()).on(poll).flush(); } }