package org.sigmah.server.handler;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program 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, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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/gpl-3.0.html>.
* #L%
*/
import java.util.Arrays;
import org.sigmah.server.dao.AmendmentDAO;
import org.sigmah.server.dao.ProjectDAO;
import org.sigmah.server.dispatch.impl.UserDispatch.UserExecutionContext;
import org.sigmah.server.domain.Amendment;
import org.sigmah.server.domain.Project;
import org.sigmah.server.handler.base.AbstractCommandHandler;
import org.sigmah.server.service.AmendmentService;
import org.sigmah.shared.command.AmendmentActionCommand;
import org.sigmah.shared.dispatch.CommandException;
import org.sigmah.shared.dto.ProjectDTO;
import org.sigmah.shared.dto.referential.AmendmentState;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import org.sigmah.server.handler.util.Handlers;
import org.sigmah.shared.dto.referential.AmendmentAction;
import org.sigmah.shared.dto.referential.GlobalPermissionEnum;
import org.sigmah.shared.security.UnauthorizedAccessException;
/**
* Handle actions made on amendments.
*
* @author Raphaƫl Calabro (rcalabro@ideia.fr)
* @author Maxime Lombard (mlombard@ideia.fr)
*/
public class AmendmentActionCommandHandler extends AbstractCommandHandler<AmendmentActionCommand, ProjectDTO> {
/**
* Injected {@link AmendmentService}.
*/
@Inject
private AmendmentService amendmentPolicy;
/**
* Injected {@link ProjectDAO}.
*/
@Inject
private ProjectDAO projectDAO;
/**
* Injected {@link AmendmentDAO}.
*/
@Inject
private AmendmentDAO amendmentDAO;
/**
* {@inheritDoc}
*/
@Override
public ProjectDTO execute(final AmendmentActionCommand cmd, final UserExecutionContext context) throws CommandException {
final Integer projectId = cmd.getProjectId();
final org.sigmah.shared.dto.referential.AmendmentAction action = cmd.getAction();
if (projectId == null || action == null) {
throw new CommandException("Invalid command arguments: " + action);
}
final Project project = projectDAO.findById(projectId);
if (Arrays.binarySearch(project.getAmendmentState().getActions(), action) == -1) {
throw new IllegalStateException("The action '"
+ action
+ "' cannot be applied on the project '"
+ project.getName()
+ "' (state "
+ project.getAmendmentState()
+ ')');
}
performAction(action, project, cmd.getName(), context);
return mapper().map(project, new ProjectDTO());
}
/**
* Perform the given action in a transaction.
*
* @param action Action to perform.
* @param project Project to modify.
* @param name Core version name.
* @param context Execution context.
* @throws org.sigmah.shared.dispatch.CommandException If the action could not be executed.
*/
@Transactional
protected void performAction(final AmendmentAction action, final Project project, final String name, final UserExecutionContext context) throws CommandException {
switch (action) {
case LOCK:
if (!Handlers.isGranted(context.getUser().getOrgUnitsWithProfiles(), project.getOrgUnit(), GlobalPermissionEnum.LOCK_PROJECT)) {
throw new UnauthorizedAccessException(GlobalPermissionEnum.LOCK_PROJECT + " permission is required to lock projects.");
}
project.setAmendmentState(AmendmentState.LOCKED);
break;
case UNLOCK:
if (!Handlers.isGranted(context.getUser().getOrgUnitsWithProfiles(), project.getOrgUnit(), GlobalPermissionEnum.LOCK_PROJECT)) {
throw new UnauthorizedAccessException(GlobalPermissionEnum.LOCK_PROJECT + " permission is required to unlock projects.");
}
project.setAmendmentState(AmendmentState.DRAFT);
break;
case VALIDATE:
// BUGFIX #738: verifying the user rights before validating.
if (!Handlers.isGranted(context.getUser().getOrgUnitsWithProfiles(), project.getOrgUnit(), GlobalPermissionEnum.VALID_AMENDEMENT)) {
throw new UnauthorizedAccessException(GlobalPermissionEnum.VALID_AMENDEMENT + " permission is required to validate projects.");
}
validateAmendment(project, context);
createAmendment(project, name);
break;
default:
throw new UnsupportedOperationException("Command not supported:" + action);
}
// Always persist updated project.
projectDAO.persist(project, context.getUser());
}
protected void createAmendment(final Project project, final String name) {
// Changes the project state to draft and save the current state as a new amendment.
final Amendment newAmendment = amendmentPolicy.createAmendment(project, name);
int version = project.getAmendmentVersion() + 1;
// Updating the project
project.setAmendmentVersion(version);
project.setAmendmentRevision(1);
project.setAmendmentState(AmendmentState.LOCKED);
project.getAmendments().add(newAmendment);
}
protected void validateAmendment(final Project project, final UserExecutionContext context) {
// Archive the active state (if one does exist) and activate the current one.
for (final Amendment amendment : project.getAmendments()) {
if (amendment.getState() == AmendmentState.ACTIVE) {
amendment.setState(AmendmentState.ARCHIVED);
amendmentDAO.persist(amendment, context.getUser());
}
}
project.setAmendmentState(AmendmentState.ACTIVE);
}
}