Salome HOME
Siman codebase is refactored. Spring beans are introduced in the context.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / som / DocumentRights.java
1 package org.splat.som;
2 /**
3  * Class providing services for checking the rights related to operations on a given document.
4  * These rights are partially driven by the validation cycle associated to documents.
5  * 
6  * @see ValidationCycle
7  * @author    Daniel Brunier-Coulin
8  * @copyright OPEN CASCADE 2012
9  */
10 //TODO: Review this rights in the following contexts:
11 //      - Document shared by several scenarios
12 //      - Document out-dated following a modification of a document it uses
13
14 import java.util.Iterator;
15 import java.util.List;
16
17 import org.splat.dal.bo.kernel.Relation;
18 import org.splat.dal.bo.kernel.User;
19 import org.splat.dal.bo.som.Document;
20 import org.splat.dal.bo.som.ProgressState;
21 import org.splat.dal.bo.som.Publication;
22 import org.splat.dal.bo.som.UsedByRelation;
23 import org.splat.dal.bo.som.UsesRelation;
24 import org.splat.dal.bo.som.ValidationCycle;
25 import org.splat.dal.bo.som.ValidationStep;
26 import org.splat.dal.bo.som.VersionsRelation;
27
28
29 public class DocumentRights {
30
31     private User             user;
32     private Publication      operand;
33     private ValidationCycle  cycle;
34     private boolean          isauthor;     // True if the user is author of the document
35
36 //  ==============================================================================================================================
37 //  Constructors
38 //  ==============================================================================================================================
39
40     public DocumentRights (User user, Publication tag) {
41 //  --------------------------------------------------
42       this.user     = user;
43       this.operand  = tag;
44       this.cycle    = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
45       this.isauthor = operand.value().getAuthor().equals(user);
46 //TODO: all contributors of the given document (when supported) must also behave as author
47     }
48     protected DocumentRights (Publication tag) {
49 //  ------------------------------------------
50       this.user     = operand.value().getAuthor();
51       this.operand  = tag;
52       this.cycle    = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
53       this.isauthor = true;           // In order to ignore the author state in the context of any user
54 //TODO: all contributors of the given document (when supported) must also behave as author
55     }
56
57 //  ==============================================================================================================================
58 //  Public member functions
59 //  ==============================================================================================================================
60
61 /**
62  * Checks if the user has right to accept the modifications of documents depending on the selected document.
63  * This operation applies to out-dated documents following a modification of documents they use.
64  * Only the author of the document has such right.
65  * 
66  * @return true if the user has right to accept the modifications of dependencies of the document.
67  * @see    Publication#accept()
68  */
69     public boolean canAccept () {
70 //  ---------------------------
71       if (!isauthor) return false;
72       return operand.isOutdated();
73     }
74
75 /**
76  * Checks if the user has right to approve the selected document.
77  * Only the approver of the type of selected document has such right, providing that the document is candidate for approval and
78  * all document dependencies have already been approved.
79  * 
80  * @return true if the user has right to approve the document.
81  * @see    Publication#approve()
82  * @see    ValidationCycle
83  */
84     public boolean canApprove () {
85 //  ----------------------------
86       User  approver = cycle.getActor(ValidationStep.APPROVAL);             // May be null if not approvable
87
88       if (!user.equals(approver)) return false;
89       if (operand.getProgressState() != ProgressState.inCHECK) return false;
90       
91       List<Relation>            use = operand.value().getRelations(UsesRelation.class);
92       for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
93         Document      depend = (Document)i.next().getTo();
94         ProgressState state  = depend.getProgressState();
95         if (state == ProgressState.EXTERN)   continue;                      // External documents do not follow this progress state
96         if (state != ProgressState.APPROVED) return false;
97       }
98       return true;
99     }
100
101 /**
102  * Checks if the user has right to attach a file to the selected document.
103  * Both, the author, during the elaboration of the document, and the reviewer of the document, during the review process,
104  * have such right.
105  * 
106  * @return true if the user has right to attach a file to the document.
107  * @see    Publication#attach(String)
108  * @see    Publication#attach(String, String)
109  */
110     public boolean canAttach () {
111 //  ---------------------------
112       User           manager  = operand.getOwnerStudy().getAuthor();
113       User           reviewer = cycle.getActor(ValidationStep.REVIEW);      // May be null if not reviewable
114       ProgressState  state    = operand.value().getProgressState();
115
116       if (state == ProgressState.inWORK) return (isauthor);
117       else                               return (isauthor || user.equals(manager) || user.equals(reviewer));
118     }
119
120 /**
121  * Checks if the user has right to demote the selected document.
122  * A document can be demoted providing that it is In-Draft or In-Check and all documents using it have previously been demoted.
123  * In-Draft documents can be demoted by default by both, the author of the document and the responsible of study, while
124  * documents in approval process can be demoted by their approver only.
125  * 
126  * @return true if the user has right to demote the document.
127  * @see    #canInvalidate()
128  * @see    #canPromote()
129  * @see    Publication#demote()
130  * @see    ValidationCycle
131  */
132     public boolean canDemote () {
133 //  ---------------------------
134       User           manager   = operand.getOwnerStudy().getAuthor();
135       User           publisher = cycle.getActor(ValidationStep.PROMOTION);  // Null if the default users are involved
136       User           approver  = cycle.getActor(ValidationStep.APPROVAL);   // May be null if not approvable
137       ProgressState  mystate   = operand.value().getProgressState();
138
139       if (mystate == ProgressState.inDRAFT) {
140         if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
141         } else                   if (!user.equals(publisher))            return false;
142       } else
143       if (mystate == ProgressState.inCHECK) {
144         if (!user.equals(approver))                                      return false;
145       } else                                                             return false;
146       
147       List<Relation>            use = operand.value().getRelations(UsedByRelation.class);
148       for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
149         Document      depend = (Document)i.next().getTo();
150         ProgressState state  = depend.getProgressState();
151         if (mystate == ProgressState.inDRAFT &&  state != ProgressState.inWORK)  return false;
152         if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
153       }
154       return true;
155     }
156
157 /**
158  * Checks if the user has right to check-out the selected document for editing.
159  * In-Work documents can be checked-out by both, the author of the document and the responsible of study, while
160  * documents In-Draft can be checked-out by the reviewer only.
161  * 
162  * @return true if the user has right to edit the document.
163  */
164     public boolean canEdit () {
165 //  -------------------------
166       User           manager  = operand.getOwnerStudy().getAuthor();
167       User           reviewer = cycle.getActor(ValidationStep.REVIEW);      // May be null if not reviewable
168       ProgressState  state    = operand.value().getProgressState();
169
170 //TODO: Should be restricted by the application if no editor available
171       if (state == ProgressState.inWORK) {
172         if (isauthor || user.equals(manager)) return true;
173       } else
174       if (state == ProgressState.inDRAFT) {
175         if (user.equals(reviewer))            return true;
176       }
177       return false;
178     }
179
180 /**
181  * Checks if the user has right to promote the selected document.
182  * A document can be promoted providing that it is In-Work and all its dependencies have previously been promoted.
183  * By default, both the author of the document and the responsible of study has right to promote such document. Otherwise,
184  * only the user involved in the Promotion step of validation cycle of the selected document has such right.
185  * 
186  * @return true if the user has right to promote the document.
187  * @see    #canDemote()
188  * @see    Publication#promote()
189  * @see    ValidationCycle
190  */
191     public boolean canPromote () {
192 //  ----------------------------
193       User manager   = operand.getOwnerStudy().getAuthor();
194       User publisher = cycle.getActor(ValidationStep.PROMOTION);            // Null if the default users are involved
195
196       if (operand.getProgressState() != ProgressState.inWORK)          return false;
197       if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
198       } else {                 if (!user.equals(publisher))            return false;
199       }
200       List<Relation>            use = operand.value().getRelations(UsesRelation.class);
201       for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
202         Document      depend = (Document)i.next().getTo();
203         ProgressState state  = depend.getProgressState();
204         if (state == ProgressState.EXTERN) continue;                        // External documents do not follow this progress state
205         if (state == ProgressState.inWORK) return false;
206       }
207       return true;
208     }
209
210 /**
211  * Checks if the user has right to remove the history of the selected document, if exists.
212  * Only the responsible of the study have such right.
213  * 
214  * @return true if the user has right to purge the document.
215  */
216     public boolean canPurge () {
217 //  --------------------------
218       User      manager = operand.getOwnerStudy().getAuthor();
219       Document  doc     = operand.value();
220       
221       if (!user.equals(manager))                                return false;
222       if (doc.isShared())                                       return false;
223       if (doc.getFirstRelation(VersionsRelation.class) == null) return false;
224       return true;
225     }
226
227 /**
228  * Checks if the user has right to remove the selected document from the study.
229  * Both, the author of the document and the responsible of the study, have such right, providing that:
230  * - the document is neither in review or in approval process
231  * - the document is not used by any other document
232  * 
233  * @return true if the user has right to remove the document.
234  * @see    Step#removeDocument(Publication)
235  */
236     public boolean canRemove () {
237 //  ---------------------------
238       User          manager = operand.getOwnerStudy().getAuthor();
239       ProgressState state   = operand.getProgressState();
240
241       if (!isauthor && !user.equals(manager))                             return false;
242       if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
243
244       List<Publication> using = operand.getRelations(UsedByRelation.class);
245       return (using.size() == 0);
246     }
247
248 /**
249  * Checks if the user has right to rename the selected document.
250  * Only the author of the document has such right, providing that the document is neither in review nor in approval process.
251  * 
252  * @return true if the user has right to rename the document.
253  * @see    Publication#rename(String)
254  */
255     public boolean canRename () {
256 //  ---------------------------
257       ProgressState state = operand.getProgressState();
258
259       if (!isauthor) return false;     // In case of external document, the author is the one who has imported the document.
260       if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
261       return (!operand.value().isShared());
262     }
263
264 /**
265  * Checks if the user has right to replace the source file of the selected document.
266  * Both, the author of the document and the responsible of study has such right, providing that the document is neither in review
267  * nor in approval process.
268  * 
269  * @return true if the user has right to replace the document.
270  */
271     public boolean canReplace () {
272 //  ----------------------------
273       User          manager = operand.getOwnerStudy().getAuthor();
274       ProgressState state   = operand.getProgressState();
275
276       if (!isauthor && !user.equals(manager)) return false;                 // Supposed to work also in case of external document.
277       if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
278       return !operand.value().isShared();
279     }
280
281 /**
282  * Checks if the user has right to validate the selected document.
283  * Only the reviewer of the type of selected document has such right, providing that the document is being reviewed and
284  * all document dependencies have already been validated.
285  * 
286  * @return true if the user has right to validate the document
287  * @see    #canUnvalidate()
288  * @see    Publication#review()
289  * @see    ValidationCycle
290  */
291     public boolean canReview () {
292 //  ---------------------------
293       User  reviewer = cycle.getActor(ValidationStep.REVIEW);               // May be null if not reviewable
294
295       if (!user.equals(reviewer))                              return false;
296       if (operand.getProgressState() != ProgressState.inDRAFT) return false;
297       
298       List<Relation>            use = operand.value().getRelations(UsesRelation.class);
299       for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
300         Document      depend = (Document)i.next().getTo();
301         ProgressState state  = depend.getProgressState();
302         if (state == ProgressState.EXTERN) continue;                        // External documents do not follow this progress state
303         if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) return false;
304       }
305       return true;
306     }
307
308 /**
309  * Checks if the user has right to undo the validation operation of the selected document.
310  * Both, the author and the reviewer of a validated document, have such right.
311  * 
312  * @return true if the user has right to undo the validation operation
313  * @see    #canDemote()
314  * @see    #canReview()
315  * @see    Publication#invalidate()
316  * @see    ValidationCycle
317  */
318     public boolean canInvalidate () {
319 //  -------------------------------
320       User           reviewer = cycle.getActor(ValidationStep.REVIEW);      // May be null if not reviewable
321       ProgressState  mystate  = operand.value().getProgressState();
322
323       if (mystate != ProgressState.inCHECK)    return false;
324       if (!isauthor && !user.equals(reviewer)) return false;
325         
326       List<Relation>            use = operand.value().getRelations(UsedByRelation.class);
327       for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
328         Document      depend = (Document)i.next().getTo();
329         ProgressState state  = depend.getProgressState();
330         if (mystate == ProgressState.inDRAFT &&  state != ProgressState.inWORK)  return false;
331         if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
332       }
333       return true;
334     }
335
336 /**
337  * Checks if the user has right to version the selected document.
338  * In-Work documents can be versioned by both, the author of the document and the responsible of study, while
339  * documents In-Draft can be versioned by the reviewer only.
340  * Additionally, Approved documents can also be versioned by their author in order to enter in a new modification validation cycle.
341  * 
342  * @return true if the user has right to version the document.
343  * @see    Step#versionDocument(Publication)
344  * @see    Step#versionDocument(Publication, Document.Properties)
345  * @see    Step#versionDocument(Publication, String)
346  */
347     public boolean canVersion () {
348 //  ----------------------------
349       User           manager  = operand.getOwnerStudy().getAuthor();
350       User           reviewer = cycle.getActor(ValidationStep.REVIEW);      // May be null if not reviewable
351       ProgressState  state    = operand.value().getProgressState();
352
353       if (state == ProgressState.inWORK) {
354         if (isauthor || user.equals(manager)) return true;
355       } else
356       if (state == ProgressState.inDRAFT) {
357         if (user.equals(reviewer))            return true;
358       } else
359       if (state == ProgressState.APPROVED) {
360         if (isauthor)                         return true;
361       }
362       return false;
363  }
364
365 //  ==============================================================================================================================
366 //  Getter
367 //  ==============================================================================================================================
368
369 /**
370  * Returns the document subject of checks according to this user rights.
371  * 
372  * @return the document subject of checks.
373  */
374     public Document getOperand () {
375 //  -----------------------------
376       return operand.value();
377     }
378 }