Salome HOME
Update copyrights 2014.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / som / DocumentRights.java
1 package org.splat.som;
2
3 /**
4  * Class providing services for checking the rights related to operations on a given document. These rights are partially driven by the
5  * validation cycle associated to documents.
6  * 
7  * @see ValidationCycle
8  * @author Daniel Brunier-Coulin
9  * @copyright OPEN CASCADE 2012-2014
10  */
11 // TODO: Review this rights in the following contexts:
12 // - Document shared by several scenarios
13 // - Document out-dated following a modification of a document it uses
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 import org.splat.service.ServiceLocatorImpl;
28 import org.splat.service.StudyService;
29
30 /**
31  * The class defining user rights to the document.
32  */
33 public class DocumentRights {
34
35         /**
36          * The connected user.
37          */
38         private transient final User _user;
39         /**
40          * The document publication.
41          */
42         private transient Publication _operand;
43         /**
44          * The document validation cycle.
45          */
46         private transient final ValidationCycle _cycle;
47         /**
48          * True if the user is author of the document.
49          */
50         private final transient boolean _isauthor;
51
52         // ==============================================================================================================================
53         // Constructors
54         // ==============================================================================================================================
55
56         /**
57          * The constructor.
58          * 
59          * @param user
60          *            the current user
61          * @param tag
62          *            the document publication
63          */
64         public DocumentRights(final User user, final Publication tag) {
65                 this._user = user;
66                 this._operand = tag;
67                 // RKV this.cycle = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
68                 this._cycle = getStudyService().getValidationCycleOf(
69                                 _operand.getOwnerStudy(), _operand.value().getType());
70                 this._isauthor = _operand.value().getAuthor().equals(user);
71                 // TODO: all contributors of the given document (when supported) must also behave as author
72         }
73
74         /**
75          * The constructor in the case when the user is an author of the document.
76          * 
77          * @param tag
78          *            the document publication
79          */
80         protected DocumentRights(final Publication tag) {
81                 this._operand = tag;
82                 this._user = _operand.value().getAuthor();
83                 this._operand = tag;
84                 this._cycle = getStudyService().getValidationCycleOf(
85                                 _operand.getOwnerStudy(), _operand.value().getType());
86                 this._isauthor = true; // In order to ignore the author state in the context of any user
87                 // TODO: all contributors of the given document (when supported) must also behave as author
88         }
89
90         // ==============================================================================================================================
91         // Public member functions
92         // ==============================================================================================================================
93
94         /**
95          * Checks if the user has right to accept the modifications of documents depending on the selected document. This operation applies to
96          * out-dated documents following a modification of documents they use. Only the author of the document has such right.
97          * 
98          * @return true if the user has right to accept the modifications of dependencies of the document.
99          * @see Publication#accept()
100          */
101         public boolean canAccept() {
102                 return _isauthor && ServiceLocatorImpl.getInstance()
103                                 .getPublicationService().canBeActualized(_operand);
104         }
105
106         /**
107          * Checks if the user has right to approve the selected document. Only the approver of the type of selected document has such right,
108          * providing that the document is candidate for approval and all document dependencies have already been approved.
109          * 
110          * @return true if the user has right to approve the document.
111          * @see Publication#approve()
112          * @see ValidationCycle
113          */
114         public boolean canApprove() {
115                 User approver = _cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
116                 boolean res = (_operand.getOwnerStudy().getAuthor().equals(_user) ||
117                                         _user.equals(approver))
118                                 && (_operand.getProgressState() == ProgressState.inCHECK)
119                                 && !_operand.isOutdated();
120                 if (res) {
121                         List<Relation> use = _operand.value().getRelations(
122                                         UsesRelation.class);
123                         for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
124                                 Document depend = (Document) i.next().getTo();
125                                 ProgressState state = depend.getProgressState();
126                                 if (state == ProgressState.EXTERN) {
127                                         continue; // External documents do not follow this progress state
128                                 }
129                                 if (state != ProgressState.APPROVED) {
130                                         res = false;
131                                         break;
132                                 }
133                         }
134                 }
135                 return res;
136         }
137
138         /**
139          * Checks if the user has right to attach a file to the selected document. Both, the author, during the elaboration of the document, and
140          * the reviewer of the document, during the review process, have such right.
141          * 
142          * @return true if the user has right to attach a file to the document.
143          * @see Publication#attach(String)
144          * @see Publication#attach(String, String)
145          */
146         public boolean canAttach() {
147                 User manager = _operand.getOwnerStudy().getAuthor();
148                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
149                 ProgressState state = _operand.value().getProgressState();
150
151                 return _isauthor
152                                 || ((state != ProgressState.inWORK) && (_user.equals(manager) || _user
153                                                 .equals(reviewer)));
154         }
155
156         /**
157          * Checks if the user has right to demote the selected document. A document can be demoted providing that it is In-Draft or In-Check and
158          * all documents using it have previously been demoted. In-Draft documents can be demoted by default by both, the author of the document
159          * and the responsible of study, while documents in approval process can be demoted by their approver only.
160          * 
161          * @return true if the user has right to demote the document.
162          * @see #canInvalidate()
163          * @see #canPromote()
164          * @see Publication#demote()
165          * @see ValidationCycle
166          */
167         public boolean canDemote() {
168                 User manager = _operand.getOwnerStudy().getAuthor();
169                 User publisher = _cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
170                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
171                 User approver = _cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
172                 ProgressState mystate = _operand.value().getProgressState();
173
174                 boolean res = _operand.getOwnerStudy().getAuthor().equals(_user) ||
175                                 (mystate == ProgressState.inDRAFT
176                                 && (_user.equals(publisher) || _user.equals(reviewer)
177                                                 || _user.equals(manager) || (reviewer == null)
178                                                 && _user.equals(approver)) || mystate == ProgressState.inCHECK
179                                 && (_user.equals(approver) || _user.equals(reviewer) || (reviewer == null)
180                                                 && (_isauthor || _user.equals(publisher) || _user.equals(manager))));
181
182                 if (res) {
183                         List<Relation> use = _operand.value().getRelations(
184                                         UsedByRelation.class);
185                         for (Relation rel : use) {
186                                 Document depend = (Document) rel.getTo();
187                                 ProgressState state = depend.getProgressState();
188                                 if (((mystate == ProgressState.inDRAFT) || (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT)))
189                                                 && state != ProgressState.inWORK) {
190                                         res = false;
191                                         break;
192                                 }
193                         }
194                 }
195                 return res;
196         }
197
198         /**
199          * Checks if the user has right to check-out the selected document for editing. In-Work documents can be checked-out by both, the author
200          * of the document and the responsible of study, while documents In-Draft can be checked-out by the reviewer only.
201          * 
202          * @return true if the user has right to edit the document.
203          */
204         public boolean canEdit() {
205                 User manager = _operand.getOwnerStudy().getAuthor();
206                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
207                 ProgressState state = _operand.value().getProgressState();
208
209                 // TODO: Should be restricted by the application if no editor available
210                 if (state == ProgressState.inWORK) {
211                         if (_isauthor || _user.equals(manager)) {
212                                 return true;
213                         }
214                 } else if (state == ProgressState.inDRAFT) {
215                         if (_user.equals(reviewer)) {
216                                 return true;
217                         }
218                 }
219                 return false;
220         }
221
222         /**
223          * Checks if the user has right to promote the selected document. A document can be promoted providing that it is In-Work and all its
224          * dependencies have previously been promoted. By default, both the author of the document and the responsible of study has right to
225          * promote such document. Otherwise, only the user involved in the Promotion step of validation cycle of the selected document has such
226          * right.
227          * 
228          * @return true if the user has right to promote the document.
229          * @see #canDemote()
230          * @see Publication#promote()
231          * @see ValidationCycle
232          */
233         public boolean canPromote() {
234                 User manager = _operand.getOwnerStudy().getAuthor();
235                 User publisher = _cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
236
237                 if(_operand.isOutdated()) {
238                         return false;
239                 }
240                 if (_operand.getProgressState() != ProgressState.inWORK) {
241                         if (_operand.getProgressState() == ProgressState.inDRAFT) {
242                                 return canReview();
243                         }
244                         return false;
245                 }
246                 if(!_operand.getOwnerStudy().getAuthor().equals(_user)) {
247                         if (publisher == null) {
248                                 if (!_isauthor && !_user.equals(manager)) {
249                                         return false;
250                                 }
251                         } else {
252                                 if (!_user.equals(publisher)) {
253                                         return false;
254                                 }
255                         }
256                 }
257                 List<Relation> use = _operand.value().getRelations(UsesRelation.class);
258                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
259                         Document depend = (Document) i.next().getTo();
260                         ProgressState state = depend.getProgressState();
261                         if (state == ProgressState.EXTERN) {
262                                 continue; // External documents do not follow this progress state
263                         }
264                         if (state == ProgressState.inWORK) {
265                                 return false;
266                         }
267                 }
268                 return true;
269         }
270
271         /**
272          * Checks if the user has right to remove the history of the selected document, if exists. Only the responsible of the study have such
273          * right.
274          * 
275          * @return true if the user has right to purge the document.
276          */
277         public boolean canPurge() {
278                 User manager = _operand.getOwnerStudy().getAuthor();
279                 Document doc = _operand.value();
280
281                 if (!_user.equals(manager)) {
282                         return false;
283                 }
284                 if (doc.isShared()) {
285                         return false;
286                 }
287                 if (doc.getFirstRelation(VersionsRelation.class) == null) {
288                         return false;
289                 }
290                 return true;
291         }
292
293         /**
294          * Checks if the user has right to remove the selected document from the study. Both, the author of the document and the responsible of
295          * the study, have such right, providing that: - the document is neither in review or in approval process - the document is not used by
296          * any other document
297          * 
298          * @return true if the user has right to remove the document.
299          * @see Step#removeDocument(Publication)
300          */
301         public boolean canRemove() {
302                 User manager = _operand.getOwnerStudy().getAuthor();
303                 ProgressState state = _operand.getProgressState();
304
305                 if (!_isauthor && !_user.equals(manager)) {
306                         return false;
307                 }
308                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
309                         return false;
310                 }
311
312                 List<Relation> using = _operand.value().getRelations(
313                                 UsedByRelation.class);
314                 return using.isEmpty();
315         }
316
317         /**
318          * Checks if the user has right to rename the selected document. Only the author of the document has such right, providing that the
319          * document is neither in review nor in approval process.
320          * 
321          * @return true if the user has right to rename the document.
322          * @see Publication#rename(String)
323          */
324         public boolean canRename() {
325                 ProgressState state = _operand.getProgressState();
326
327                 if (!_isauthor) {
328                         return false; // In case of external document, the author is the one who has imported the document.
329                 }
330                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
331                         return false;
332                 }
333                 return (!_operand.value().isShared());
334         }
335
336         /**
337          * Checks if the user has right to replace the source file of the selected document. Both, the author of the document and the
338          * responsible of study has such right, providing that the document is neither in review nor in approval process.
339          * 
340          * @return true if the user has right to replace the document.
341          */
342         public boolean canReplace() {
343                 User manager = _operand.getOwnerStudy().getAuthor();
344                 ProgressState state = _operand.getProgressState();
345
346                 if (!_isauthor && !_user.equals(manager)) {
347                         return false; // Supposed to work also in case of external document.
348                 }
349                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
350                         return false;
351                 }
352                 return !_operand.value().isShared();
353         }
354
355         /**
356          * Checks if the user has right to validate the selected document. Only the reviewer of the type of selected document has such right,
357          * providing that the document is being reviewed and all document dependencies have already been validated.
358          * 
359          * @return true if the user has right to validate the document
360          * @see #canUnvalidate()
361          * @see Publication#review()
362          * @see ValidationCycle
363          */
364         public boolean canReview() {
365                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
366
367                 if (!_user.equals(reviewer) && !_operand.getOwnerStudy().getAuthor().equals(_user)
368                                 || _operand.isOutdated()) {
369                         return false;
370                 }
371                 if (_operand.getProgressState() != ProgressState.inDRAFT) {
372                         return false;
373                 }
374
375                 List<Relation> use = _operand.value().getRelations(UsesRelation.class);
376                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
377                         Document depend = (Document) i.next().getTo();
378                         ProgressState state = depend.getProgressState();
379                         if (state == ProgressState.EXTERN) {
380                                 continue; // External documents do not follow this progress state
381                         }
382                         if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) {
383                                 return false;
384                         }
385                 }
386                 return true;
387         }
388
389         /**
390          * Checks if the user has right to undo the validation operation of the selected document. Both, the author and the reviewer of a
391          * validated document, have such right.
392          * 
393          * @return true if the user has right to undo the validation operation
394          * @see #canDemote()
395          * @see #canReview()
396          * @see Publication#invalidate()
397          * @see ValidationCycle
398          */
399         public boolean canInvalidate() {
400                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
401                 ProgressState mystate = _operand.value().getProgressState();
402
403                 if (mystate != ProgressState.inCHECK) {
404                         return false;
405                 }
406                 if (!_isauthor && !_user.equals(reviewer) && !_operand.getOwnerStudy().getAuthor().equals(_user)) {
407                         return false;
408                 }
409
410                 List<Relation> use = _operand.value()
411                                 .getRelations(UsedByRelation.class);
412                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
413                         Document depend = (Document) i.next().getTo();
414                         ProgressState state = depend.getProgressState();
415                         if (mystate == ProgressState.inDRAFT
416                                         && state != ProgressState.inWORK) {
417                                 return false;
418                         }
419                         if (mystate == ProgressState.inCHECK
420                                         && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) {
421                                 return false;
422                         }
423                 }
424                 return true;
425         }
426
427         /**
428          * Checks if the user has right to version the selected document. In-Work documents can be versioned by both, the author of the document
429          * and the responsible of study, while documents In-Draft can be versioned by the reviewer only. Additionally, Approved documents can
430          * also be versioned by their author in order to enter in a new modification validation cycle.
431          * 
432          * @return true if the user has right to version the document.
433          * @see Step#versionDocument(Publication)
434          * @see Step#versionDocument(Publication, Document.Properties)
435          * @see Step#versionDocument(Publication, String)
436          */
437         public boolean canVersion() {
438                 User manager = _operand.getOwnerStudy().getAuthor();
439                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
440                 ProgressState state = _operand.value().getProgressState();
441
442                 if (state == ProgressState.inWORK) {
443                         if (_isauthor || _user.equals(manager)) {
444                                 return true;
445                         }
446                 } else if (state == ProgressState.inDRAFT) {
447                         if (_user.equals(reviewer)) {
448                                 return true;
449                         }
450                 } else if (state == ProgressState.APPROVED) {
451                         if (_isauthor) {
452                                 return true;
453                         }
454
455                 } else if (state == ProgressState.EXTERN) {
456                         if (_isauthor || _user.equals(manager)) {
457                                 return true;
458                         }
459                 }
460
461                 return false;
462         }
463
464         // ==============================================================================================================================
465         // Getter
466         // ==============================================================================================================================
467
468         /**
469          * Returns the document subject of checks according to this user rights.
470          * 
471          * @return the document subject of checks.
472          */
473         public Document getOperand() {
474                 return _operand.value();
475         }
476
477         /**
478          * Get the study service.
479          * 
480          * @return the study service
481          */
482         private StudyService getStudyService() {
483                 return ServiceLocatorImpl.getInstance().getStudyService();
484         }
485 }