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.model.team;
8   
9   import static ch.colabproject.colab.api.model.team.TeamMember.TEAM_SEQUENCE_NAME;
10  import ch.colabproject.colab.api.exceptions.ColabMergeException;
11  import ch.colabproject.colab.api.model.ColabEntity;
12  import ch.colabproject.colab.api.model.WithWebsocketChannels;
13  import ch.colabproject.colab.api.model.common.DeletionStatus;
14  import ch.colabproject.colab.api.model.common.Tracking;
15  import ch.colabproject.colab.api.model.project.Project;
16  import ch.colabproject.colab.api.model.team.acl.Assignment;
17  import ch.colabproject.colab.api.model.tools.EntityHelper;
18  import ch.colabproject.colab.api.security.permissions.Conditions;
19  import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.ChannelsBuilder;
20  import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.EmptyChannelBuilder;
21  import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.ProjectContentChannelBuilder;
22  import java.util.ArrayList;
23  import java.util.List;
24  import javax.json.bind.annotation.JsonbTransient;
25  import javax.persistence.CascadeType;
26  import javax.persistence.Embedded;
27  import javax.persistence.Entity;
28  import javax.persistence.EnumType;
29  import javax.persistence.Enumerated;
30  import javax.persistence.FetchType;
31  import javax.persistence.GeneratedValue;
32  import javax.persistence.GenerationType;
33  import javax.persistence.Id;
34  import javax.persistence.Index;
35  import javax.persistence.ManyToMany;
36  import javax.persistence.ManyToOne;
37  import javax.persistence.OneToMany;
38  import javax.persistence.Table;
39  import javax.persistence.Transient;
40  import javax.validation.constraints.NotBlank;
41  import javax.validation.constraints.NotNull;
42  import javax.validation.constraints.Size;
43  
44  /**
45   * A role within the development team. A role is used to group several member sharing same skills or
46   * objective within the project.
47   *
48   * @author maxence
49   */
50  @Entity
51  @Table(
52      indexes = {
53          @Index(columnList = "project_id"), }
54  )
55  public class TeamRole implements ColabEntity, WithWebsocketChannels {
56  
57      private static final long serialVersionUID = 1L;
58  
59      // ---------------------------------------------------------------------------------------------
60      // fields
61      // ---------------------------------------------------------------------------------------------
62      /**
63       * TeamRole ID.
64       */
65      @Id
66      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = TEAM_SEQUENCE_NAME)
67      private Long id;
68  
69      /**
70       * creation + modification + erasure tracking data
71       */
72      @Embedded
73      private Tracking trackingData;
74  
75      /**
76       * Is it in a bin or ready to be definitely deleted. Null means active.
77       */
78      @Enumerated(EnumType.STRING)
79      private DeletionStatus deletionStatus;
80  
81      /**
82       * Name of the role. Can not be null or blank
83       */
84      @Size(max = 255)
85      @NotBlank
86      private String name;
87  
88      /**
89       * The project
90       */
91      @ManyToOne(fetch = FetchType.LAZY)
92      @NotNull
93      @JsonbTransient
94      private Project project;
95  
96      /**
97       * The project ID (serialization sugar)
98       */
99      @Transient
100     private Long projectId;
101 
102     /**
103      * List of members who are part of this role
104      */
105     @ManyToMany(mappedBy = "roles")
106     @JsonbTransient
107     private List<TeamMember> members = new ArrayList<>();
108 
109     /**
110      * List of assignments relative to this role
111      */
112     @OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
113     @JsonbTransient
114     private List<Assignment> assignments = new ArrayList<>();
115 
116     // ---------------------------------------------------------------------------------------------
117     // getters and setters
118     // ---------------------------------------------------------------------------------------------
119     /**
120      * @return the project ID
121      */
122     @Override
123     public Long getId() {
124         return id;
125     }
126 
127     /**
128      * Set id
129      *
130      * @param id id
131      */
132     public void setId(Long id) {
133         this.id = id;
134     }
135 
136     /**
137      * Get the tracking data
138      *
139      * @return tracking data
140      */
141     @Override
142     public Tracking getTrackingData() {
143         return trackingData;
144     }
145 
146     /**
147      * Set tracking data
148      *
149      * @param trackingData new tracking data
150      */
151     @Override
152     public void setTrackingData(Tracking trackingData) {
153         this.trackingData = trackingData;
154     }
155 
156     @Override
157     public DeletionStatus getDeletionStatus() {
158         return deletionStatus;
159     }
160 
161     @Override
162     public void setDeletionStatus(DeletionStatus status) {
163         this.deletionStatus = status;
164     }
165 
166     /**
167      * Get role name
168      *
169      * @return the name
170      */
171     public String getName() {
172         return name;
173     }
174 
175     /**
176      * Set the name
177      *
178      * @param name new role name
179      */
180     public void setName(String name) {
181         this.name = name;
182     }
183 
184     /**
185      * @return the project
186      */
187     public Project getProject() {
188         return project;
189     }
190 
191     /**
192      * @param project the project
193      */
194     public void setProject(Project project) {
195         this.project = project;
196     }
197 
198     /**
199      * get the project id. To be sent to client
200      *
201      * @return id of the project or null
202      */
203     public Long getProjectId() {
204         if (this.project != null) {
205             return this.project.getId();
206         } else {
207             return projectId;
208         }
209     }
210 
211     /**
212      * set the project id. For serialization only
213      *
214      * @param id the id of the project
215      */
216     public void setProjectId(Long id) {
217         this.projectId = id;
218     }
219 
220     /**
221      * Get members
222      *
223      * @return members
224      */
225     public List<TeamMember> getMembers() {
226         return members;
227     }
228 
229     /**
230      * Set the list of members
231      *
232      * @param members list of members
233      */
234     public void setMembers(List<TeamMember> members) {
235         this.members = members;
236     }
237 
238     /**
239      * Get the list of assignments
240      *
241      * @return assignments list
242      */
243     public List<Assignment> getAssignments() {
244         return assignments;
245     }
246 
247     /**
248      * Set the list of assignments
249      *
250      * @param assignments new list of assignments
251      */
252     public void setAssignments(List<Assignment> assignments) {
253         this.assignments = assignments;
254     }
255 
256     // ---------------------------------------------------------------------------------------------
257     // concerning the whole class
258     // ---------------------------------------------------------------------------------------------
259     @Override
260     public void mergeToUpdate(ColabEntity other) throws ColabMergeException {
261         if (other instanceof TeamRole) {
262             TeamRole o = (TeamRole) other;
263             this.setDeletionStatus(o.getDeletionStatus());
264             this.setName(o.getName());
265         } else {
266             throw new ColabMergeException(this, other);
267         }
268     }
269 
270     @Override
271     public ChannelsBuilder getChannelsBuilder() {
272         if (this.getProject() != null) {
273             return new ProjectContentChannelBuilder(project);
274         } else {
275             return new EmptyChannelBuilder();
276         }
277     }
278 
279     @Override
280     @JsonbTransient
281     public Conditions.Condition getReadCondition() {
282         if (this.project != null) {
283             return new Conditions.IsCurrentUserMemberOfProject(this.project);
284         } else {
285             // should not exist
286             return Conditions.alwaysTrue;
287         }
288     }
289 
290     @Override
291     @JsonbTransient
292     public Conditions.Condition getUpdateCondition() {
293         if (this.project != null) {
294             return new Conditions.IsCurrentUserInternalToProject(this.project);
295         } else {
296             // should not exist
297             return Conditions.alwaysTrue;
298         }
299     }
300 
301     @Override
302     public int hashCode() {
303         return EntityHelper.hashCode(this);
304     }
305 
306     @Override
307     @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
308     public boolean equals(Object obj) {
309         return EntityHelper.equals(this, obj);
310     }
311 
312     @Override
313     public String toString() {
314         return "Role{" + "id=" + id + ", deletion=" + getDeletionStatus()
315             + ", name=" + name + ", projectId=" + projectId + '}';
316     }
317 
318 }