org.squashtest.tm.web.internal.controller.users.TeamController.java Source code

Java tutorial

Introduction

Here is the source code for org.squashtest.tm.web.internal.controller.users.TeamController.java

Source

/**
 *     This file is part of the Squashtest platform.
 *     Copyright (C) 2010 - 2016 Henix, henix.fr
 *
 *     See the NOTICE file distributed with this work for additional
 *     information regarding copyright ownership.
 *
 *     This 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 3 of the License, or
 *     (at your option) any later version.
 *
 *     this software 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 software.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.squashtest.tm.web.internal.controller.users;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.inject.Inject;
import javax.validation.Valid;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.squashtest.tm.core.foundation.collection.DefaultFiltering;
import org.squashtest.tm.core.foundation.collection.DefaultPagingAndSorting;
import org.squashtest.tm.core.foundation.collection.Filtering;
import org.squashtest.tm.core.foundation.collection.PagedCollectionHolder;
import org.squashtest.tm.core.foundation.collection.PagingAndSorting;
import org.squashtest.tm.domain.audit.AuditableMixin;
import org.squashtest.tm.domain.project.ProjectPermission;
import org.squashtest.tm.domain.users.Team;
import org.squashtest.tm.domain.users.User;
import org.squashtest.tm.service.security.PermissionEvaluationService;
import org.squashtest.tm.service.user.TeamModificationService;
import org.squashtest.tm.web.internal.controller.RequestParams;
import org.squashtest.tm.web.internal.controller.administration.UserModel;
import org.squashtest.tm.web.internal.controller.project.ProjectModel;
import org.squashtest.tm.web.internal.http.ContentTypes;
import org.squashtest.tm.web.internal.i18n.InternationalizationHelper;
import org.squashtest.tm.web.internal.model.datatable.DataTableDrawParameters;
import org.squashtest.tm.web.internal.model.datatable.DataTableFiltering;
import org.squashtest.tm.web.internal.model.datatable.DataTableModel;
import org.squashtest.tm.web.internal.model.datatable.DataTableModelBuilder;
import org.squashtest.tm.web.internal.model.datatable.DataTableModelConstants;
import org.squashtest.tm.web.internal.model.datatable.DataTableSorting;
import org.squashtest.tm.web.internal.model.jquery.RenameModel;
import org.squashtest.tm.web.internal.model.json.JsonGeneralInfo;
import org.squashtest.tm.web.internal.model.viewmapper.DatatableMapper;
import org.squashtest.tm.web.internal.model.viewmapper.NameBasedMapper;

/**
 * @author mpagnon
 * 
 */
@Controller
@RequestMapping("/administration/teams")
public class TeamController extends PartyControllerSupport {
    /**
     * 
     */
    private static final String TEAM_ID = "teamId";

    @Inject
    private TeamModificationService service;

    @Inject
    private PermissionEvaluationService permissionEvaluationService;

    private static final String TEAM_ID_URL = "/{teamId}";

    private DatatableMapper<String> teamsMapper = new NameBasedMapper(9)
            .mapAttribute(DataTableModelConstants.DEFAULT_ENTITY_NAME_KEY, "name", Team.class)
            .mapAttribute("description", "description", Team.class)
            .mapAttribute("nb-associated-users", "members.size", Team.class)
            .mapAttribute("created-on", "audit.createdOn", Team.class)
            .mapAttribute("created-by", "audit.createdBy", Team.class)
            .mapAttribute("last-mod-on", "audit.lastModifiedOn", Team.class)
            .mapAttribute("last-mod-by", "audit.lastModifiedBy", Team.class);

    private DatatableMapper<String> membersMapper = new NameBasedMapper(1).map("user-name", "firstName");

    private DatatableMapper<String> permissionMapper = new NameBasedMapper(2)
            .mapAttribute(DataTableModelConstants.PROJECT_NAME_KEY, "project.name", ProjectPermission.class)
            .mapAttribute("permission-name", "permissionGroup.qualifiedName", ProjectPermission.class);

    private static final Logger LOGGER = LoggerFactory.getLogger(TeamController.class);

    /**
     * Creates a new Team
     * 
     * @param team
     *            : the given {@link Team} filled with a name and a description
     */
    @RequestMapping(value = "/new", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    @ResponseBody
    public void createNew(@Valid @ModelAttribute("add-team") Team team) {
        LOGGER.info(ToStringBuilder.reflectionToString(team));
        service.persist(team);
    }

    /**
     * Return the DataTableModel to display the table of all teams.
     * 
     * @param params
     *            the {@link DataTableDrawParameters} for the teams table
     * @return the {@link DataTableModel} with organized {@link Team} infos.
     */
    @RequestMapping(method = RequestMethod.GET, params = RequestParams.S_ECHO_PARAM)
    @ResponseBody
    public DataTableModel getTableModel(final DataTableDrawParameters params, final Locale locale) {

        PagingAndSorting paging = new DataTableSorting(params, teamsMapper);
        Filtering filtering = new DataTableFiltering(params);

        PagedCollectionHolder<List<Team>> holder = service.findAllFiltered(paging, filtering);

        return new TeamsDataTableModelHelper(locale, messageSource).buildDataModel(holder, params.getsEcho());
    }

    /**
     * Will delete the given team along with it's permissions. will not delete it's associated users
     * 
     * @param teamId
     */
    @RequestMapping(value = TEAM_ID_URL, method = RequestMethod.DELETE)
    @ResponseBody
    public void deleteTeam(@PathVariable List<Long> teamId) {
        service.deleteTeam(teamId);
    }

    /**
     * Will return a view for the team of the given id
     * 
     * @param teamId
     */
    @RequestMapping(value = TEAM_ID_URL, method = RequestMethod.GET)
    public String showTeamModificationPage(@PathVariable Long teamId, Model model) {
        if (!permissionEvaluationService.hasRole("ROLE_ADMIN")) {
            throw new AccessDeniedException("Access is denied");
        }
        Team team = service.findById(teamId);
        List<?> permissionModel = createPermissionTableModel(teamId, new DefaultPagingAndSorting(),
                DefaultFiltering.NO_FILTERING, "").getAaData();

        List<?> userModel = createMembersTableModel(teamId, new DefaultPagingAndSorting(),
                DefaultFiltering.NO_FILTERING, "").getAaData();

        List<PermissionGroupModel> pgm = getPermissionGroupModels(teamId);
        List<ProjectModel> pm = getProjectModels(teamId);

        model.addAttribute("team", team);
        model.addAttribute("users", userModel);
        model.addAttribute("permissionList", pgm);
        model.addAttribute("myprojectList", pm);
        model.addAttribute("permissions", permissionModel);

        return "team-modification.html";
    }

    @RequestMapping(value = TEAM_ID_URL, method = RequestMethod.POST, params = "id=team-description")
    @ResponseBody
    public String changeDescription(@PathVariable Long teamId, @RequestParam String value) {
        service.changeDescription(teamId, value);
        return value;
    }

    @RequestMapping(value = TEAM_ID_URL + "/name", method = RequestMethod.POST)
    @ResponseBody
    public RenameModel changeName(@PathVariable Long teamId, @RequestParam String value) {
        service.changeName(teamId, value);
        return new RenameModel(value);
    }

    @RequestMapping(value = TEAM_ID_URL
            + "/general", method = RequestMethod.GET, produces = ContentTypes.APPLICATION_JSON)
    @ResponseBody
    public JsonGeneralInfo refreshGeneralInfos(@PathVariable(TEAM_ID) long teamId) {
        Team team = service.findById(teamId);
        return new JsonGeneralInfo((AuditableMixin) team);

    }

    // ************************************ team members section ************************

    @RequestMapping(value = TEAM_ID_URL
            + "/members", method = RequestMethod.GET, params = RequestParams.S_ECHO_PARAM)
    @ResponseBody
    public DataTableModel getMembersTableModel(DataTableDrawParameters params, @PathVariable(TEAM_ID) long teamId) {
        PagingAndSorting paging = new DataTableSorting(params, membersMapper);
        Filtering filtering = new DataTableFiltering(params);
        return createMembersTableModel(teamId, paging, filtering, params.getsEcho());
    }

    @RequestMapping(value = TEAM_ID_URL + "/members/{memberIds}", method = RequestMethod.DELETE)
    @ResponseBody
    public void removeMember(@PathVariable(TEAM_ID) long teamId, @PathVariable("memberIds") List<Long> memberIds) {
        service.removeMembers(teamId, memberIds);
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = TEAM_ID_URL + "/non-members", headers = "Accept=application/json")
    @ResponseBody
    public Collection<UserModel> getNonMembers(@PathVariable(TEAM_ID) long teamId) {
        List<User> nonMembers = service.findAllNonMemberUsers(teamId);
        return CollectionUtils.collect(nonMembers, new UserModelCreator());
    }

    @RequestMapping(value = TEAM_ID_URL + "/members/{logins}", method = RequestMethod.PUT)
    @ResponseBody
    public void addMembers(@PathVariable(TEAM_ID) long teamId, @PathVariable("logins") List<String> userlogins) {
        service.addMembers(teamId, userlogins);
    }

    // **************************** team permission section ************************

    @RequestMapping(value = TEAM_ID_URL + "/add-permission", method = RequestMethod.POST)
    @ResponseBody
    public void addNewPermission(@RequestParam("project") long projectId, @PathVariable long teamId,
            @RequestParam String permission) {
        permissionService.addNewPermissionToProject(teamId, projectId, permission);
    }

    @RequestMapping(value = TEAM_ID_URL + "/remove-permission", method = RequestMethod.POST)
    @ResponseBody
    public void removePermission(@RequestParam("project") long projectId, @PathVariable long teamId) {
        permissionService.removeProjectPermission(teamId, projectId);
    }

    @RequestMapping(value = TEAM_ID_URL
            + "/permissions", method = RequestMethod.GET, params = RequestParams.S_ECHO_PARAM)
    @ResponseBody
    public DataTableModel getPermissionTableModel(DataTableDrawParameters params,
            @PathVariable(TEAM_ID) long teamId) {
        PagingAndSorting paging = new DataTableSorting(params, permissionMapper);
        Filtering filtering = new DataTableFiltering(params);
        return createPermissionTableModel(teamId, paging, filtering, params.getsEcho());
    }

    // ******************************* private *************************************

    private DataTableModel createMembersTableModel(long teamId, PagingAndSorting paging, Filtering filtering,
            String secho) {
        PagedCollectionHolder<List<User>> holder = service.findAllTeamMembers(teamId, paging, filtering);
        return new MembersTableModelHelper().buildDataModel(holder, secho);
    }

    @RequestMapping(value = TEAM_ID_URL + "/permission-popup", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getPermissionPopup(@PathVariable long teamId) {
        return createPermissionPopupModel(teamId);
    }

    // ************************* private classes ***********************

    private static final class UserModelCreator implements Transformer {
        @Override
        public Object transform(Object user) {
            return new UserModel((User) user);
        }
    }

    private static final class TeamsDataTableModelHelper extends DataTableModelBuilder<Team> {
        private InternationalizationHelper messageSource;
        private Locale locale;

        private TeamsDataTableModelHelper(Locale locale, InternationalizationHelper messageSource) {
            this.locale = locale;
            this.messageSource = messageSource;
        }

        @Override
        public Map<String, Object> buildItemData(Team item) {
            final AuditableMixin auditable = (AuditableMixin) item;
            Map<String, Object> res = new HashMap<>();
            res.put(DataTableModelConstants.DEFAULT_ENTITY_ID_KEY, item.getId());
            res.put(DataTableModelConstants.DEFAULT_ENTITY_INDEX_KEY, getCurrentIndex());
            res.put(DataTableModelConstants.DEFAULT_ENTITY_NAME_KEY, item.getName());
            res.put("description", item.getDescription());
            res.put("nb-associated-users", item.getMembers().size());
            res.put(DataTableModelConstants.DEFAULT_CREATED_ON_KEY,
                    messageSource.localizeDate(auditable.getCreatedOn(), locale));
            res.put(DataTableModelConstants.DEFAULT_CREATED_BY_KEY, auditable.getCreatedBy());
            res.put("last-mod-on", messageSource.localizeDate(auditable.getLastModifiedOn(), locale));
            res.put("last-mod-by", auditable.getLastModifiedBy());
            res.put(DataTableModelConstants.DEFAULT_EMPTY_DELETE_HOLDER_KEY, " ");
            return res;
        }
    }

    private static final class MembersTableModelHelper extends DataTableModelBuilder<User> {
        private MembersTableModelHelper() {
            super();
        }

        @Override
        protected Map<?, ?> buildItemData(User item) {
            Map<String, Object> res = new HashMap<>();
            res.put("user-id", item.getId());
            res.put("user-active", item.getActive());
            res.put("user-index", getCurrentIndex());
            res.put("user-name", item.getFirstName() + " " + item.getLastName() + " (" + item.getLogin() + ")");
            res.put("empty-delete-holder", null);
            return res;
        }
    }
}