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