Salome HOME
9e9d7242092e5d7c87b5ebeb29374b75eee4ff0a
[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
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 = (_user.equals(approver))
117                                 && (_operand.getProgressState() == ProgressState.inCHECK)
118                                 && !_operand.isOutdated();
119                 if (res) {
120                         List<Relation> use = _operand.value().getRelations(
121                                         UsesRelation.class);
122                         for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
123                                 Document depend = (Document) i.next().getTo();
124                                 ProgressState state = depend.getProgressState();
125                                 if (state == ProgressState.EXTERN) {
126                                         continue; // External documents do not follow this progress state
127                                 }
128                                 if (state != ProgressState.APPROVED) {
129                                         res = false;
130                                         break;
131                                 }
132                         }
133                 }
134                 return res;
135         }
136
137         /**
138          * Checks if the user has right to attach a file to the selected document. Both, the author, during the elaboration of the document, and
139          * the reviewer of the document, during the review process, have such right.
140          * 
141          * @return true if the user has right to attach a file to the document.
142          * @see Publication#attach(String)
143          * @see Publication#attach(String, String)
144          */
145         public boolean canAttach() {
146                 User manager = _operand.getOwnerStudy().getAuthor();
147                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
148                 ProgressState state = _operand.value().getProgressState();
149
150                 return _isauthor
151                                 || ((state != ProgressState.inWORK) && (_user.equals(manager) || _user
152                                                 .equals(reviewer)));
153         }
154
155         /**
156          * 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
157          * all documents using it have previously been demoted. In-Draft documents can be demoted by default by both, the author of the document
158          * and the responsible of study, while documents in approval process can be demoted by their approver only.
159          * 
160          * @return true if the user has right to demote the document.
161          * @see #canInvalidate()
162          * @see #canPromote()
163          * @see Publication#demote()
164          * @see ValidationCycle
165          */
166         public boolean canDemote() {
167                 User manager = _operand.getOwnerStudy().getAuthor();
168                 User publisher = _cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
169                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
170                 User approver = _cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
171                 ProgressState mystate = _operand.value().getProgressState();
172
173                 boolean res = (mystate == ProgressState.inDRAFT
174                                 && (_user.equals(publisher) || _user.equals(reviewer)
175                                                 || _user.equals(manager) || (reviewer == null)
176                                                 && _user.equals(approver)) || mystate == ProgressState.inCHECK
177                                 && (_user.equals(approver) || _user.equals(reviewer) || (reviewer == null)
178                                                 && (_isauthor || _user.equals(publisher) || _user.equals(manager))));
179
180                 if (res) {
181                         List<Relation> use = _operand.value().getRelations(
182                                         UsedByRelation.class);
183                         for (Relation rel : use) {
184                                 Document depend = (Document) rel.getTo();
185                                 ProgressState state = depend.getProgressState();
186                                 if (((mystate == ProgressState.inDRAFT) || (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT)))
187                                                 && state != ProgressState.inWORK) {
188                                         res = false;
189                                         break;
190                                 }
191                         }
192                 }
193                 return res;
194         }
195
196         /**
197          * 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
198          * of the document and the responsible of study, while documents In-Draft can be checked-out by the reviewer only.
199          * 
200          * @return true if the user has right to edit the document.
201          */
202         public boolean canEdit() {
203                 User manager = _operand.getOwnerStudy().getAuthor();
204                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
205                 ProgressState state = _operand.value().getProgressState();
206
207                 // TODO: Should be restricted by the application if no editor available
208                 if (state == ProgressState.inWORK) {
209                         if (_isauthor || _user.equals(manager)) {
210                                 return true;
211                         }
212                 } else if (state == ProgressState.inDRAFT) {
213                         if (_user.equals(reviewer)) {
214                                 return true;
215                         }
216                 }
217                 return false;
218         }
219
220         /**
221          * 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
222          * dependencies have previously been promoted. By default, both the author of the document and the responsible of study has right to
223          * promote such document. Otherwise, only the user involved in the Promotion step of validation cycle of the selected document has such
224          * right.
225          * 
226          * @return true if the user has right to promote the document.
227          * @see #canDemote()
228          * @see Publication#promote()
229          * @see ValidationCycle
230          */
231         public boolean canPromote() {
232                 User manager = _operand.getOwnerStudy().getAuthor();
233                 User publisher = _cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
234
235                 if(_operand.isOutdated()) {
236                         return false;
237                 }
238                 if (_operand.getProgressState() != ProgressState.inWORK) {
239                         if (_operand.getProgressState() == ProgressState.inDRAFT) {
240                                 return canReview();
241                         }
242                         return false;
243                 }
244                 if (publisher == null) {
245                         if (!_isauthor && !_user.equals(manager)) {
246                                 return false;
247                         }
248                 } else {
249                         if (!_user.equals(publisher)) {
250                                 return false;
251                         }
252                 }
253                 List<Relation> use = _operand.value().getRelations(UsesRelation.class);
254                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
255                         Document depend = (Document) i.next().getTo();
256                         ProgressState state = depend.getProgressState();
257                         if (state == ProgressState.EXTERN) {
258                                 continue; // External documents do not follow this progress state
259                         }
260                         if (state == ProgressState.inWORK) {
261                                 return false;
262                         }
263                 }
264                 return true;
265         }
266
267         /**
268          * Checks if the user has right to remove the history of the selected document, if exists. Only the responsible of the study have such
269          * right.
270          * 
271          * @return true if the user has right to purge the document.
272          */
273         public boolean canPurge() {
274                 User manager = _operand.getOwnerStudy().getAuthor();
275                 Document doc = _operand.value();
276
277                 if (!_user.equals(manager)) {
278                         return false;
279                 }
280                 if (doc.isShared()) {
281                         return false;
282                 }
283                 if (doc.getFirstRelation(VersionsRelation.class) == null) {
284                         return false;
285                 }
286                 return true;
287         }
288
289         /**
290          * Checks if the user has right to remove the selected document from the study. Both, the author of the document and the responsible of
291          * the study, have such right, providing that: - the document is neither in review or in approval process - the document is not used by
292          * any other document
293          * 
294          * @return true if the user has right to remove the document.
295          * @see Step#removeDocument(Publication)
296          */
297         public boolean canRemove() {
298                 User manager = _operand.getOwnerStudy().getAuthor();
299                 ProgressState state = _operand.getProgressState();
300
301                 if (!_isauthor && !_user.equals(manager)) {
302                         return false;
303                 }
304                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
305                         return false;
306                 }
307
308                 List<Relation> using = _operand.value().getRelations(
309                                 UsedByRelation.class);
310                 return using.isEmpty();
311         }
312
313         /**
314          * Checks if the user has right to rename the selected document. Only the author of the document has such right, providing that the
315          * document is neither in review nor in approval process.
316          * 
317          * @return true if the user has right to rename the document.
318          * @see Publication#rename(String)
319          */
320         public boolean canRename() {
321                 ProgressState state = _operand.getProgressState();
322
323                 if (!_isauthor) {
324                         return false; // In case of external document, the author is the one who has imported the document.
325                 }
326                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
327                         return false;
328                 }
329                 return (!_operand.value().isShared());
330         }
331
332         /**
333          * Checks if the user has right to replace the source file of the selected document. Both, the author of the document and the
334          * responsible of study has such right, providing that the document is neither in review nor in approval process.
335          * 
336          * @return true if the user has right to replace the document.
337          */
338         public boolean canReplace() {
339                 User manager = _operand.getOwnerStudy().getAuthor();
340                 ProgressState state = _operand.getProgressState();
341
342                 if (!_isauthor && !_user.equals(manager)) {
343                         return false; // Supposed to work also in case of external document.
344                 }
345                 if (state != ProgressState.inWORK && state != ProgressState.EXTERN) {
346                         return false;
347                 }
348                 return !_operand.value().isShared();
349         }
350
351         /**
352          * Checks if the user has right to validate the selected document. Only the reviewer of the type of selected document has such right,
353          * providing that the document is being reviewed and all document dependencies have already been validated.
354          * 
355          * @return true if the user has right to validate the document
356          * @see #canUnvalidate()
357          * @see Publication#review()
358          * @see ValidationCycle
359          */
360         public boolean canReview() {
361                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
362
363                 if (!_user.equals(reviewer) || _operand.isOutdated()) {
364                         return false;
365                 }
366                 if (_operand.getProgressState() != ProgressState.inDRAFT) {
367                         return false;
368                 }
369
370                 List<Relation> use = _operand.value().getRelations(UsesRelation.class);
371                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
372                         Document depend = (Document) i.next().getTo();
373                         ProgressState state = depend.getProgressState();
374                         if (state == ProgressState.EXTERN) {
375                                 continue; // External documents do not follow this progress state
376                         }
377                         if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) {
378                                 return false;
379                         }
380                 }
381                 return true;
382         }
383
384         /**
385          * Checks if the user has right to undo the validation operation of the selected document. Both, the author and the reviewer of a
386          * validated document, have such right.
387          * 
388          * @return true if the user has right to undo the validation operation
389          * @see #canDemote()
390          * @see #canReview()
391          * @see Publication#invalidate()
392          * @see ValidationCycle
393          */
394         public boolean canInvalidate() {
395                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
396                 ProgressState mystate = _operand.value().getProgressState();
397
398                 if (mystate != ProgressState.inCHECK) {
399                         return false;
400                 }
401                 if (!_isauthor && !_user.equals(reviewer)) {
402                         return false;
403                 }
404
405                 List<Relation> use = _operand.value()
406                                 .getRelations(UsedByRelation.class);
407                 for (Iterator<Relation> i = use.iterator(); i.hasNext();) {
408                         Document depend = (Document) i.next().getTo();
409                         ProgressState state = depend.getProgressState();
410                         if (mystate == ProgressState.inDRAFT
411                                         && state != ProgressState.inWORK) {
412                                 return false;
413                         }
414                         if (mystate == ProgressState.inCHECK
415                                         && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) {
416                                 return false;
417                         }
418                 }
419                 return true;
420         }
421
422         /**
423          * Checks if the user has right to version the selected document. In-Work documents can be versioned by both, the author of the document
424          * and the responsible of study, while documents In-Draft can be versioned by the reviewer only. Additionally, Approved documents can
425          * also be versioned by their author in order to enter in a new modification validation cycle.
426          * 
427          * @return true if the user has right to version the document.
428          * @see Step#versionDocument(Publication)
429          * @see Step#versionDocument(Publication, Document.Properties)
430          * @see Step#versionDocument(Publication, String)
431          */
432         public boolean canVersion() {
433                 User manager = _operand.getOwnerStudy().getAuthor();
434                 User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
435                 ProgressState state = _operand.value().getProgressState();
436
437                 if (state == ProgressState.inWORK) {
438                         if (_isauthor || _user.equals(manager)) {
439                                 return true;
440                         }
441                 } else if (state == ProgressState.inDRAFT) {
442                         if (_user.equals(reviewer)) {
443                                 return true;
444                         }
445                 } else if (state == ProgressState.APPROVED) {
446                         if (_isauthor) {
447                                 return true;
448                         }
449
450                 } else if (state == ProgressState.EXTERN) {
451                         if (_isauthor || _user.equals(manager)) {
452                                 return true;
453                         }
454                 }
455
456                 return false;
457         }
458
459         // ==============================================================================================================================
460         // Getter
461         // ==============================================================================================================================
462
463         /**
464          * Returns the document subject of checks according to this user rights.
465          * 
466          * @return the document subject of checks.
467          */
468         public Document getOperand() {
469                 return _operand.value();
470         }
471
472         /**
473          * Get the study service.
474          * 
475          * @return the study service
476          */
477         private StudyService getStudyService() {
478                 return ServiceLocatorImpl.getInstance().getStudyService();
479         }
480 }