ProjectRestEndpoint.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.rest.project;
import ch.colabproject.colab.api.controller.project.ProjectManager;
import ch.colabproject.colab.api.controller.team.TeamManager;
import ch.colabproject.colab.api.exceptions.ColabMergeException;
import ch.colabproject.colab.api.model.DuplicationParam;
import ch.colabproject.colab.api.model.card.AbstractCardType;
import ch.colabproject.colab.api.model.card.Card;
import ch.colabproject.colab.api.model.card.CardContent;
import ch.colabproject.colab.api.model.link.ActivityFlowLink;
import ch.colabproject.colab.api.model.project.CopyParam;
import ch.colabproject.colab.api.model.project.Project;
import ch.colabproject.colab.api.persistence.jpa.project.CopyParamDao;
import ch.colabproject.colab.api.persistence.jpa.project.ProjectDao;
import ch.colabproject.colab.api.rest.project.bean.ProjectCreationData;
import ch.colabproject.colab.api.rest.project.bean.ProjectStructure;
import ch.colabproject.colab.generator.model.annotations.AdminResource;
import ch.colabproject.colab.generator.model.annotations.AuthenticationRequired;
import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* REST Project controller
*
* @author maxence
*/
@Path("projects")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@AuthenticationRequired
public class ProjectRestEndpoint {
/** logger */
private static final Logger logger = LoggerFactory.getLogger(ProjectRestEndpoint.class);
/** Project business logic */
@Inject
private ProjectManager projectManager;
/** TeamMembers and roles management */
@Inject
private TeamManager teamManager;
/** Project persistence */
@Inject
private ProjectDao projectDao;
/** Copy parameters persistence */
@Inject
private CopyParamDao copyParamDao;
// *********************************************************************************************
// get
// *********************************************************************************************
/**
* Get project identified by the given id.
*
* @param id id of the project to fetch
*
* @return the project or null
*/
@GET
@Path("/{id: [0-9]+}")
public Project getProject(@PathParam("id") Long id) {
logger.debug("Get project #{}", id);
return projectDao.findProject(id);
}
/**
* Get all projects the current user is a team member of
*
* @return list of projects
*/
@GET
@Path("Mine")
public List<Project> getProjectsWhereTeamMember() {
logger.debug("Get projects where current user is a team member of");
return projectManager.findProjectsWhereTeamMember();
}
/**
* Get all global models
* @return list of global models
*/
@GET
@Path("Global")
public List<Project> getAllGlobalModels() {
logger.debug("Get all global projects");
return projectDao.findAllGlobalModels();
}
/**
* Get all projects the current user is an instance maker for
*
* @return list of matching projects
*/
@GET
@Path("MyInstanceableModels")
public List<Project> getInstanceableModels() {
logger.debug("Get all models linked by a instancemaker to the current user");
return projectManager.findInstanceableModelsForCurrentUser();
}
/**
* Retrieve the list of all projects. This is available to admin only
*
* @return all known project
*/
@GET
@AdminResource
public List<Project> getAllProjects() {
logger.debug("Get all projects");
return projectDao.findAllProject();
}
// *********************************************************************************************
// create
// *********************************************************************************************
/**
* Create a new project from scratch with the provided data and register current user as a
* member.
*
* @param creationData the data needed to fill the project
*
* @return id of the persisted new project
*/
@POST
@Path("createProject")
public Long createProject(ProjectCreationData creationData) {
logger.debug("Create a project with {}", creationData);
Project project = projectManager.createProject(creationData);
creationData.getGuestsEmail().stream().forEach(email -> {
teamManager.invite(project.getId(), email);
});
return project.getId();
}
/**
* Duplicate the given project
*
* @param baseProjectId the id of the project we want to duplicate
* @param name the name of the new project
* @param params the parameters to fine tune the duplication
*
* @return the id of the duplicated project
*
* @throws ColabMergeException if the name cannot be updated
*/
@POST
@Path("copyProject/{id: [0-9]+}/{name}")
public Long duplicateProject(@PathParam("id") Long baseProjectId,
@PathParam("name") String name, DuplicationParam params) throws ColabMergeException {
logger.debug("duplicate the project #{} with params {}", baseProjectId, params);
DuplicationParam effectiveParams = params;
if (effectiveParams == null) {
effectiveParams = DuplicationParam.buildDefaultForProjectDuplication();
}
// check forced parameters
if (effectiveParams.isMakeOnlyCardTypeReferences()) {
throw new IllegalArgumentException();
}
Project newProject = projectManager.duplicateProject(baseProjectId, effectiveParams);
newProject.setName(name);
projectDao.updateProject(newProject);
return newProject.getId();
}
// *********************************************************************************************
// update
// *********************************************************************************************
/**
* Save changes to database.
*
* @param project project to update
*
* @throws ColabMergeException if the merge is not possible
*/
@PUT
public void updateProject(Project project) throws ColabMergeException {
logger.debug("Update project {}", project);
projectDao.updateProject(project);
}
/**
* Save changes to database.
*
* @param copyParam the copy parameters to update
*
* @throws ColabMergeException if the merge is not possible
*/
@PUT
@Path("copyParam")
public void updateCopyParam(CopyParam copyParam) throws ColabMergeException {
logger.debug("Update copy param {}", copyParam);
copyParamDao.updateCopyParam(copyParam);
}
// *********************************************************************************************
// delete
// *********************************************************************************************
/**
* Put the given project in the bin. (= set DeletionStatus to BIN + set erasure
* tracking data)
*
* @param projectId the id of the project
*
* @throws HttpErrorMessage if project does not exist
*/
@PUT
@Path("{projectId: [0-9]+}/PutInBin")
public void putProjectInBin(@PathParam("projectId") Long projectId) {
logger.debug("put in bin project #{}", projectId);
projectManager.putProjectInBin(projectId);
}
/**
* Restore from the bin. The project won't contain any deletion or erasure data
* anymore.
* <p>
* It means that the project is back at its place.
*
* @param projectId the id of the project
*
* @throws HttpErrorMessage if project does not exist
*/
@PUT
@Path("{projectId: [0-9]+}/RestoreFromBin")
public void restoreProjectFromBin(@PathParam("projectId") Long projectId) {
logger.debug("restore from bin project #{}", projectId);
projectManager.restoreProjectFromBin(projectId);
}
/**
* Set the deletion status to TO_DELETE.
* <p>
* It means that the project is only visible in the bin panel.
*
* @param projectId the id of the project
*
* @throws HttpErrorMessage if project does not exist
*/
@PUT
@Path("{projectId: [0-9]+}/MarkAsToDeleteForever")
public void markProjectAsToDeleteForever(@PathParam("projectId") Long projectId) {
logger.debug("mark project #{} as to delete forever", projectId);
projectManager.markProjectAsToDeleteForever(projectId);
}
// *********************************************************************************************
// get project content
// *********************************************************************************************
/**
* Get the root card of the project
*
* @param projectId the id of the project
*
* @return the matching card
*/
@GET
@Path("{id: [0-9]+}/RootCard")
public Card getRootCardOfProject(@PathParam("id") Long projectId) {
logger.debug("get the root card of the project #{}", projectId);
return projectManager.getRootCard(projectId);
}
/**
* Get all card types belonging to a project
*
* @param projectId the id of the project
*
* @return list of card types
*/
@GET
@Path("{id: [0-9]+}/CardTypes")
public Set<AbstractCardType> getCardTypesOfProject(@PathParam("id") Long projectId) {
logger.debug("Get project #{} card types", projectId);
return projectManager.getCardTypes(projectId);
}
/**
* Get all cards belonging to a project
*
* @param projectId the id of the project
*
* @return list of cards
*/
@GET
@Path("{id: [0-9]+}/Cards")
public Set<Card> getCardsOfProject(@PathParam("id") Long projectId) {
logger.debug("Get project #{} cards", projectId);
return projectManager.getCards(projectId);
}
/**
* Get all cardContents belonging to a project
*
* @param projectId the id of the project
*
* @return list of cardContents
*/
@GET
@Path("{id: [0-9]+}/CardContents")
public Set<CardContent> getCardContentsOfProject(@PathParam("id") Long projectId) {
logger.debug("Get project #{} cardContents", projectId);
return projectManager.getCardContents(projectId);
}
/**
* Get all cards, cardContents and structure of a project in one shot.
*
* @param projectId the id of the project
*
* @return full structure of the project
*/
@GET
@Path("{id: [0-9]+}/structure")
public ProjectStructure getStructureOfProject(@PathParam("id") Long projectId) {
logger.debug("Get project #{} cardContents", projectId);
return projectManager.getStructure(projectId);
}
/**
* Get all activity flow links belonging to a project
*
* @param projectId the id of the project
*
* @return list of activity flow links
*/
@GET
@Path("{id: [0-9]+}/ActivityFlowLink")
public Set<ActivityFlowLink> getActivityFlowLinks(@PathParam("id") Long projectId) {
logger.debug("Get project #{} activityflowlinks", projectId);
return projectManager.getActivityFlowLinks(projectId);
}
/**
* Get the copy parameters of the project
*
* @param projectId the id of the project
*
* @return the related copy parameters
*/
@GET
@Path("{id: [0-9]+}/copyParams")
public CopyParam getCopyParam(@PathParam("id") Long projectId) {
CopyParam copyParam = projectManager.getCopyParam(projectId);
logger.debug("Got project #{} copy param : {}", projectId, copyParam);
return copyParam;
}
// *********************************************************************************************
//
// *********************************************************************************************
}