View Javadoc
1   /*
2    * The coLAB project
3    * Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
4    *
5    * Licensed under the MIT License
6    */
7   package ch.colabproject.colab.api.rest.card;
8   
9   import ch.colabproject.colab.api.controller.card.CardManager;
10  import ch.colabproject.colab.api.controller.card.grid.GridPosition;
11  import ch.colabproject.colab.api.exceptions.ColabMergeException;
12  import ch.colabproject.colab.api.model.card.Card;
13  import ch.colabproject.colab.api.model.card.CardContent;
14  import ch.colabproject.colab.api.model.link.ActivityFlowLink;
15  import ch.colabproject.colab.api.model.link.StickyNoteLink;
16  import ch.colabproject.colab.api.model.team.acl.Assignment;
17  import ch.colabproject.colab.api.persistence.jpa.card.CardDao;
18  import ch.colabproject.colab.generator.model.annotations.AuthenticationRequired;
19  import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
20  import java.util.List;
21  import jakarta.inject.Inject;
22  import jakarta.ws.rs.Consumes;
23  import jakarta.ws.rs.GET;
24  import jakarta.ws.rs.POST;
25  import jakarta.ws.rs.PUT;
26  import jakarta.ws.rs.Path;
27  import jakarta.ws.rs.PathParam;
28  import jakarta.ws.rs.Produces;
29  import jakarta.ws.rs.core.MediaType;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  
34  /**
35   * REST card controller
36   *
37   * @author sandra
38   */
39  @Path("cards")
40  @Consumes(MediaType.APPLICATION_JSON)
41  @Produces(MediaType.APPLICATION_JSON)
42  @AuthenticationRequired
43  public class CardRestEndpoint {
44  
45      /** logger */
46      private static final Logger logger = LoggerFactory.getLogger(CardRestEndpoint.class);
47  
48      /**
49       * The card persistence manager
50       */
51      @Inject
52      private CardDao cardDao;
53  
54      /**
55       * The card-related logic
56       */
57      @Inject
58      private CardManager cardManager;
59  
60      /**
61       * Get card identified by the given id
62       *
63       * @param id id of the card to fetch
64       *
65       * @return the card or null
66       */
67      @GET
68      @Path("{id: [0-9]+}")
69      public Card getCard(@PathParam("id") Long id) {
70          logger.debug("get card #{}", id);
71          return cardDao.findCard(id);
72      }
73  
74      /**
75       * Create and persist a new card
76       *
77       * @param parentId id of the new card's parent
78       *
79       * @return the persisted new card
80       */
81      @POST
82      @Path("create/{parentId: [0-9]+}")
83      public Card createNewCardWithoutType(@PathParam("parentId") Long parentId) {
84          logger.debug("create a new card for the parent #{} without type", parentId);
85          return cardManager.createNewCard(parentId, null);
86      }
87  
88      /**
89       * Create and persist a new card
90       *
91       * @param parentId   id of the new card's parent
92       * @param cardTypeId id of the card type of the new card
93       *
94       * @return the persisted new card
95       */
96      @POST
97      @Path("create/{parentId: [0-9]+}/{cardTypeId: [0-9]+}")
98      public Card createNewCard(@PathParam("parentId") Long parentId,
99              @PathParam("cardTypeId") Long cardTypeId) {
100         logger.debug("create a new card for the parent #{} and the type #{}", parentId,
101                 cardTypeId);
102         return cardManager.createNewCard(parentId, cardTypeId);
103     }
104 
105     /**
106      * Save changes to database. Only fields which are editable by users will be
107      * impacted.
108      *
109      * @param card card to update
110      *
111      * @throws ColabMergeException if the merge is not possible
112      */
113     @PUT
114     public void updateCard(Card card) throws ColabMergeException {
115         logger.debug("update card {}", card);
116         cardDao.updateCard(card);
117     }
118 
119     /**
120      * Change the position of the card (stay in the same parent)
121      * <p>
122      * Recompute the position of all the sister cards
123      *
124      * @param cardId   the id of the card
125      * @param position the new position of the card
126      */
127     @PUT
128     @Path("{cardId: [0-9]+}/changePosition")
129     public void changeCardPosition(@PathParam("cardId") Long cardId, GridPosition position) {
130         cardManager.changeCardPosition(cardId, position);
131     }
132 
133     /**
134      * Move a card to a new parent
135      *
136      * @param cardId      the id of the card to move
137      * @param newParentId the id of the new parent
138      *
139      * @throws HttpErrorMessage if card or parent does not exist or if parent is a
140      *                          child of the card
141      */
142     @PUT
143     @Path("{cardId: [0-9]+}/MoveTo/{newParentId: [0-9]+}")
144     public void moveCard(
145             @PathParam("cardId") Long cardId,
146             @PathParam("newParentId") Long newParentId) {
147         cardManager.moveCard(cardId, newParentId);
148     }
149 
150     /**
151      * Move a card into the parent of its parent
152      *
153      * @param cardId the id of the card
154      *
155      * @throws HttpErrorMessage if card or parent of parent does not exist
156      */
157     @PUT
158     @Path("{cardId: [0-9]+}/MoveAbove")
159     public void moveCardAbove(@PathParam("cardId") Long cardId) {
160         cardManager.moveCardAbove(cardId);
161     }
162 
163     /**
164      * Put the given card in the bin. (= set DeletionStatus to BIN + set erasure
165      * tracking data)
166      *
167      * @param cardId the id of the card
168      *
169      * @throws HttpErrorMessage if card does not exist
170      */
171     @PUT
172     @Path("{cardId: [0-9]+}/PutInBin")
173     public void putCardInBin(@PathParam("cardId") Long cardId) {
174         logger.debug("put in bin card #{}", cardId);
175         cardManager.putCardInBin(cardId);
176     }
177 
178     /**
179      * Restore from the bin. The object won't contain any deletion or erasure data
180      * anymore.
181      * <p>
182      * It means that the object is back at its place (as much as possible).
183      * <p>
184      * If the parent card is deleted, the card is moved at the root of the project.
185      *
186      * @param cardId the id of the card
187      *
188      * @throws HttpErrorMessage if card does not exist
189      */
190     @PUT
191     @Path("{cardId: [0-9]+}/RestoreFromBin")
192     public void restoreCardFromBin(@PathParam("cardId") Long cardId) {
193         logger.debug("restore from bin card #{}", cardId);
194         cardManager.restoreCardFromBin(cardId);
195     }
196 
197     /**
198      * Set the deletion status to TO_DELETE.
199      * <p>
200      * It means that the object is only visible in the bin panel.
201      *
202      * @param cardId the id of the card
203      *
204      * @throws HttpErrorMessage if card does not exist
205      */
206     @PUT
207     @Path("{cardId: [0-9]+}/FlagAsToDeleteForever")
208     public void flagCardAsToDeleteForever(@PathParam("cardId") Long cardId) {
209         logger.debug("flag card #{} as to delete forever", cardId);
210         cardManager.flagCardAsToDeleteForever(cardId);
211     }
212 
213     /**
214      * Get all card content variants of a card
215      *
216      * @param cardId Card id of the searched content variants
217      *
218      * @return list of card contents
219      */
220     @GET
221     @Path("{id: [0-9]+}/CardContents")
222     public List<CardContent> getContentVariantsOfCard(@PathParam("id") Long cardId) {
223         logger.debug("Get card #{} content variants", cardId);
224         return cardManager.getContentVariants(cardId);
225     }
226 
227     /**
228      * Get all sticky note links of which the card is the destination
229      *
230      * @param cardId Card id of the searched links
231      *
232      * @return list of links
233      */
234     @GET
235     @Path("{id: [0-9]+}/StickyNoteLinksDestinationCard")
236     public List<StickyNoteLink> getStickyNoteLinksAsDest(@PathParam("id") Long cardId) {
237         logger.debug("Get sticky note links to card #{} as destination", cardId);
238         return cardManager.getStickyNoteLinkAsDest(cardId);
239     }
240 
241     /**
242      * Get all sticky note links of which the card is the source
243      *
244      * @param cardId Card id of the searched links
245      *
246      * @return list of links
247      */
248     @GET
249     @Path("{id: [0-9]+}/StickyNoteLinksSrcCard")
250     public List<StickyNoteLink> getStickyNoteLinksAsSrc(@PathParam("id") Long cardId) {
251         logger.debug("Get sticky note links to card #{} as source", cardId);
252         return cardManager.getStickyNoteLinkAsSrcCard(cardId);
253     }
254 
255     /**
256      * Get all activity flow links of which the card is the previous one
257      *
258      * @param cardId Card id of the searched links
259      *
260      * @return list of links
261      */
262     @GET
263     @Path("{id: [0-9]+}/ActivityFlowLinksPreviousCard")
264     public List<ActivityFlowLink> getActivityFlowLinksAsPrevious(@PathParam("id") Long cardId) {
265         logger.debug("Get activity flow links to card #{} as previous", cardId);
266         return cardManager.getActivityFlowLinkAsPrevious(cardId);
267     }
268 
269     /**
270      * Get all activity flow links of which the card is the next one
271      *
272      * @param cardId Card id of the searched links
273      *
274      * @return list of links
275      */
276     @GET
277     @Path("{id: [0-9]+}/ActivityFlowLinksNextCard")
278     public List<ActivityFlowLink> getActivityFlowLinksAsNext(@PathParam("id") Long cardId) {
279         logger.debug("Get activity flow links to card #{} as next", cardId);
280         return cardManager.getActivityFlowLinkAsNext(cardId);
281     }
282 
283     /**
284      * Retrieve the list of assignments for the given card
285      *
286      * @param cardId id of the card
287      *
288      * @return list of assignments
289      */
290     @GET
291     @Path("{cardId: [0-9]+}/assignments")
292     public List<Assignment> getAssignments(@PathParam("cardId") Long cardId) {
293         logger.debug("Get Card #{} assignments list", cardId);
294         return cardManager.getAssignments(cardId);
295     }
296 
297     /**
298      * @param cardId the card id
299      */
300     @POST
301     @Path("createCardType/{cardId: [0-9]+}")
302     public void createCardType(@PathParam("cardId") Long cardId) {
303 
304         cardManager.createCardType(cardId);
305     }
306 
307     /**
308      * Remove the card type of the card. For now, it can be done only if there is no
309      * resource in the
310      * card type.
311      *
312      * @param cardId the card id
313      */
314     @POST
315     @Path("removeCardType/{cardId: [0-9]+}")
316     public void removeCardType(@PathParam("cardId") Long cardId) {
317 
318         cardManager.removeCardType(cardId);
319     }
320 }