Salome HOME
Update copyrights 2014.
[tools/siman.git] / Workspace / Siman / src / org / splat / simer / DocumentFacade.java
1 package org.splat.simer;
2
3 /**
4  * 
5  * @author    Daniel Brunier-Coulin
6  * @copyright OPEN CASCADE 2012-2014
7  */
8
9 import java.io.File;
10 import java.text.DecimalFormat;
11 import java.text.SimpleDateFormat;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.ResourceBundle;
15
16 import org.splat.dal.bo.kernel.Relation;
17 import org.splat.dal.bo.kernel.User;
18 import org.splat.dal.bo.som.ConvertsRelation;
19 import org.splat.dal.bo.som.Document;
20 import org.splat.dal.bo.som.DocumentType;
21 import org.splat.dal.bo.som.ProgressState;
22 import org.splat.dal.bo.som.Publication;
23 import org.splat.dal.bo.som.Timestamp;
24 import org.splat.dal.bo.som.UsesRelation;
25 import org.splat.dal.bo.som.VersionsRelation;
26 import org.splat.manox.XMLDocument;
27 import org.splat.service.PublicationService;
28 import org.splat.service.technical.ProjectSettingsService;
29 import org.splat.som.DocumentRights;
30 import org.splat.som.Revision;
31 import org.splat.som.Step;
32 import org.splat.wapp.PopupMenu;
33
34 /**
35  * Document wrapper class for presentation layer.
36  */
37 public class DocumentFacade implements HistoryFacade {
38
39         /**
40          * Icon extension.
41          */
42         static private final String ICON_EXT = ".png";
43         /**
44          * Document's owner.
45          */
46         private final transient AbstractOpenObject _owner;
47         /**
48          * Wrapped document publication.
49          */
50         private final transient Publication _me;
51         /**
52          * Published document.
53          */
54         private final transient Document _mydoc;
55         /**
56          * Document state.
57          */
58         private transient ProgressState _state;
59         /**
60          * My document version in customized format.
61          */
62         private transient String _version;
63         /**
64          * Presentation state: open, deep open, closed.
65          * 
66          * @see DocumentFacade.State
67          */
68         private transient State _display;
69         /**
70          * URL of the source file.
71          */
72         private transient String _surl;
73         /**
74          * Corresponding icon.
75          */
76         private transient String _icon;
77         /**
78          * Icon qualifying sharing between scenarios of a same study.
79          */
80         private transient String _sharing;
81         /**
82          * Icon qualifying versioning from the previous study version.
83          */
84         private transient String _updated;
85         /**
86          * Document size.
87          */
88         private transient String _size;
89         /**
90          * Document last modification date.
91          */
92         private transient String _date;
93         /**
94          * Document's description.
95          */
96         private transient String _description;
97         /**
98          * List of used documents presentations.
99          */
100         private transient List<DocumentFacade> _uses;
101         /**
102          * List of attached files presentations.
103          */
104         private transient List<FileFacade> _exports;
105         /**
106          * List of the document's history nodes.
107          */
108         private transient List<HistoryFacade> _history;
109         /**
110          * Document's popup menu.
111          */
112         private transient PopupMenu _popup;
113         /**
114          * Injected project settings service.
115          */
116         private ProjectSettingsService _projectSettings;
117         /**
118          * Injected publication service.
119          */
120         private PublicationService _publicationService;
121         /**
122          * Injected application settings.
123          */
124         private ApplicationSettings _applicationSettings;
125
126         /**
127          * Document presentation state enumeration.
128          */
129         private enum State {
130                 /**
131                  * Closed presentation state.
132                  */
133                 closed,
134                 /**
135                  * Open presentation state (history and attached files nodes are visible).
136                  */
137                 open,
138                 /**
139                  * Deeply open presentation.
140                  */
141                 deepopen
142         }
143
144         // ==============================================================================================================================
145         // Constructors
146         // ==============================================================================================================================
147
148         /**
149          * Constructor.
150          * 
151          * @param opened
152          *            document owner
153          * @param represented
154          *            document presentation
155          * @param projectSettings
156          *            project settings service
157          * @param publicationService
158          *            publication service
159          * @param applicationSettings
160          *            application settings
161          */
162         public DocumentFacade(final AbstractOpenObject opened,
163                         final Publication represented,
164                         final ProjectSettingsService projectSettings,
165                         final PublicationService publicationService,
166                         final ApplicationSettings applicationSettings) {
167                 setProjectSettings(projectSettings);
168                 setPublicationService(publicationService);
169                 setApplicationSettings(applicationSettings);
170                 _owner = opened;
171                 _me = represented;
172                 _mydoc = _me.value();
173                 _state = _mydoc.getProgressState();
174                 _display = State.closed;
175
176                 refresh(); // Initializes the presentation of my document //NOPMD:RKV: to be reviewed
177         }
178
179         /**
180          * Constructs the facade of a document presented in the history folder.
181          * 
182          * @param opened
183          *            document owner
184          * @param represented
185          *            document presentation
186          * @param projectSettings
187          *            project settings service
188          * @param publicationService
189          *            publication service
190          * @param applicationSettings
191          *            application settings
192          */
193         private DocumentFacade(final AbstractOpenObject opened,
194                         final Document represented,
195                         final ProjectSettingsService projectSettings,
196                         final PublicationService publicationService,
197                         final ApplicationSettings applicationSettings) {
198                 setProjectSettings(projectSettings);
199                 setPublicationService(publicationService);
200                 setApplicationSettings(applicationSettings);
201                 _owner = opened;
202                 _me = null; // Marks the history context
203                 _mydoc = represented;
204                 _state = _mydoc.getProgressState(); // In reality, HISTORY
205                 _display = State.open; // Because the given document is a history document
206                 _description = ResourceBundle.getBundle("som",
207                                 applicationSettings.getCurrentLocale()).getString(
208                                 "history.creation")
209                                 + " " + _mydoc.getAuthor().toString();
210
211                 this.refresh(); // Initializes the presentation of my document
212         }
213
214         // ==============================================================================================================================
215         // Public member functions
216         // ==============================================================================================================================
217
218         /**
219          * Open the presentation subtree.
220          */
221         public void develop() {
222                 if (_display == State.open) { // Opening the history of document, if exist
223                         if (_history.isEmpty()) {
224                                 collectHistory(_mydoc);
225                         }
226                         _display = State.deepopen;
227                 } else { // Opening the document
228                         if (_uses == null) {
229                                 List<Relation> relist = _me.value().getRelations(UsesRelation.class);
230
231                                 _uses = new ArrayList<DocumentFacade>(relist.size());
232                                 for (Relation relation : relist) {
233                                         Document used = ((UsesRelation)relation).getTo();
234                                         
235                                         DocumentFacade facade = null;
236                                         
237                                         Publication publication = _me.getOwner().getPublication(used);
238                                         if(publication == null) {
239                                                 publication = _me.getOwnerStudy().getPublication(used);
240                                         }
241                                         if(publication != null) {
242                                                 facade = _owner._docpres.get(publication.getIndex());
243                                         }
244                                         
245                                         if (facade == null) {
246                                                 facade = new DocumentFacade(_owner, used,
247                                                                 getProjectSettings(), getPublicationService(),
248                                                                 getApplicationSettings());
249                                         }
250                                         _uses.add(facade);
251                                 }
252                         }
253                         if (_exports == null) {
254                                 updateExports();
255                         }
256                         if (_history == null) {
257                                 if (_mydoc.getPreviousVersion() != null
258                                                 || _state == ProgressState.inCHECK
259                                                 || _state == ProgressState.APPROVED) {
260                                         _history = new ArrayList<HistoryFacade>();
261                                 }
262                         }
263                         _display = State.open;
264                 }
265         }
266         
267         /**
268          * Update the list of export files.
269          */
270         private void updateExports() {
271                 List<Relation> relations = _mydoc
272                                 .getRelations(ConvertsRelation.class);
273
274                 _exports = new ArrayList<FileFacade>(relations.size());
275                 for (Relation rel : relations) {
276                         _exports.add(new FileFacade((ConvertsRelation)rel,
277                                         getApplicationSettings()));
278                 }
279         }
280
281         /**
282          * Close the presentation tree partially.
283          */
284         public void reduce() {
285                 if (_display == State.deepopen) {
286                         _display = State.open;
287                 }
288         }
289
290         /**
291          * Close the presentation tree.
292          */
293         public void reduceAll() {
294                 _display = State.closed;
295         }
296
297         // ==============================================================================================================================
298         // Getters
299         // ==============================================================================================================================
300
301         /**
302          * Get a list of attached files presentations.
303          * 
304          * @return list of FileFacades
305          */
306         public List<FileFacade> getAttachments() {
307                 return _exports;
308         }
309
310         /**
311          * {@inheritDoc}
312          * 
313          * @see org.splat.simer.HistoryFacade#getDate()
314          */
315         public String getDate() {
316                 return _date;
317         }
318
319         /**
320          * {@inheritDoc}
321          * 
322          * @see org.splat.simer.HistoryFacade#getDescription()
323          */
324         public String getDescription() {
325                 return _description;
326         }
327
328         /**
329          * Get a document edit icon file name according to the document state.
330          * 
331          * @return the icon file name
332          */
333         public String getEditIcon() {
334                 return "icon.ed" + _state + ICON_EXT;
335         }
336
337         /**
338          * {@inheritDoc}
339          * 
340          * @see org.splat.simer.HistoryFacade#getFileIcon()
341          */
342         public String getFileIcon() {
343                 return _icon;
344         }
345
346         /**
347          * Get the document history presentation.
348          * 
349          * @return the history facade
350          */
351         public List<HistoryFacade> getHistory() {
352                 return _history;
353         }
354
355         /**
356          * Get the document persistent id.
357          * 
358          * @return the document persistent id
359          */
360         public String getIndex() {
361                 return String.valueOf(_mydoc.getIndex());
362         }
363
364         /**
365          * Get the document contextual popup menu.
366          * 
367          * @return the document popup menu
368          */
369         public PopupMenu getPopup() { // Contextualizes the pop-up
370                 _popup
371                                 .setContext("document", new DocumentRights(_owner.getUser(),
372                                                 _me));
373                 return _popup; // callers must "use" the returned pop-up before getting another pop-up
374         }
375
376         /**
377          * Get the document presentation state: open, deep open, closed.
378          * 
379          * @return the document presentation state
380          * @see DocumentFacade.State
381          */
382         public String getPresentationState() {
383                 return _display.toString();
384         }
385
386         /**
387          * Get document progress state.
388          * 
389          * @return the document state
390          * @see ProgressState
391          */
392         public String getProgressState() {
393                 return _state.toString();
394         }
395
396         /**
397          * {@inheritDoc}
398          * 
399          * @see org.splat.simer.HistoryFacade#getSharingIcon()
400          */
401         public String getSharingIcon() {
402                 return _sharing;
403         }
404
405         /**
406          * {@inheritDoc}
407          * 
408          * @see org.splat.simer.HistoryFacade#getSize()
409          */
410         public String getSize() {
411                 return _size;
412         }
413
414         /**
415          * Get a document state icon file name according to the document state.
416          * 
417          * @return the icon file name
418          */
419         public String getStateIcon() {
420                 return "icon." + _state + ICON_EXT;
421         }
422
423         /**
424          * Get the document title.
425          * 
426          * @return the document title
427          */
428         public String getTitle() {
429                 return _mydoc.getTitle();
430         }
431
432         /**
433          * Get the URL of the document in the repository.
434          * 
435          * @return the document URL
436          */
437         public String getURL() {
438                 return _surl;
439         }
440
441         /**
442          * Get the list of used documents presentations.
443          * 
444          * @return list of DocumentFacades
445          */
446         public List<DocumentFacade> getUses() {
447                 return _uses;
448         }
449
450         /**
451          * {@inheritDoc}
452          * 
453          * @see org.splat.simer.HistoryFacade#getVersion()
454          */
455         public String getVersion() {
456                 return _version;
457         }
458
459         /**
460          * {@inheritDoc}
461          * 
462          * @see org.splat.simer.HistoryFacade#getVersioningIcon()
463          */
464         public String getVersioningIcon() {
465                 return _updated;
466         }
467
468         /**
469          * Check if this is a representation of the given document publication.
470          * 
471          * @param represented
472          *            the document publication
473          * @return true if this facades represents the given document publication
474          */
475         public boolean isFacadeOf(final Publication represented) {
476                 return _me.equals(represented);
477         }
478
479         // ==============================================================================================================================
480         // Protected services
481         // ==============================================================================================================================
482
483         /**
484          * Refresh the document presentation.
485          */
486         protected final void refresh() {
487                 ResourceBundle custom = ResourceBundle.getBundle("som",
488                                 getApplicationSettings().getCurrentLocale());
489                 DecimalFormat sizstring = new DecimalFormat(custom
490                                 .getString("size.format")); // Locale size display format
491                 SimpleDateFormat datstring = new SimpleDateFormat(custom
492                                 .getString("date.format"), getApplicationSettings()
493                                 .getCurrentLocale()); // Locale date display format
494                 String path = _mydoc.getSourceFile().getRelativePath();
495                 String[] mapping = ApplicationSettings.getViewersMapping();
496
497                 for (int i = 0; i < mapping.length; i++) {
498                         org.splat.dal.bo.som.File export = _mydoc
499                                         .getAttachedFile(mapping[i]);
500                         if (export != null) {
501                                 path = export.getRelativePath();
502                                 break;
503                         }
504                 }
505                 _surl = getApplicationSettings().getRepositoryURL() + path;
506                 _surl = _surl.replaceAll("'", "\\\\'");
507
508                 // Document state (overridable by the publication - see below)
509                 _state = _mydoc.getProgressState();
510                 _version = _mydoc.getVersion(); // May be null
511
512                 initIcons();
513
514                 // Document description
515                 VersionsRelation versions = (VersionsRelation) _mydoc
516                                 .getFirstRelation(VersionsRelation.class);
517                 if (versions != null) {
518                         _description = versions.getDescription();
519                 }
520                 // File details
521                         Revision.Format verstring = new Revision.Format(
522                                         getProjectSettings().getRevisionPattern());
523                         _version = verstring.format(_version);
524                 _size = sizstring.format(_mydoc.getSourceFile().asFile().length() / 1000);
525                 _date = datstring.format(_mydoc.getLastModificationDate());
526                 updateExports();
527                 // Refresh of the history in case of promotion
528                 if (_display == State.deepopen) {
529                         _history.clear();
530                         this.collectHistory(_mydoc);
531                 }
532                 initPopupMenu();
533         }
534
535         /**
536          * Initialize document presentation icons.
537          */
538         private final void initIcons() {
539                 // Icons definition
540                 String format = _mydoc.getFormat();
541                 if ("xml".equals(format)) {
542                         format = XMLDocument.getActualFormat(_mydoc.getSourceFile()
543                                         .asFile());
544                         if ("schema".equals(_mydoc.getType().getName())) {
545                                 format = "schema";
546                         }
547                 }
548
549                 _icon = "icon." + format + ICON_EXT;
550                 _sharing = "image.hold.gif";
551                 _updated = "image.hold.gif";
552                 File image = new File(ApplicationSettings.getApplicationSkinPath()
553                                 + _icon);
554                 if (!image.exists()) {
555                         _icon = "icon.any.png";
556                 }
557
558                 if (_me == null) { // Facade in the history folder
559                         if (_mydoc.isVersioned()) { // History of the last version
560                                 if (_mydoc.isPublished()) {
561                                         _sharing = "image.share.png"; // Not correct if published in a previous version of the study
562                                         _updated = "icon.hold.png";
563                                 }
564                         } else {
565                                 if (_state == ProgressState.inWORK) {
566                                         _icon = "icon." + _state.toString() + ICON_EXT;
567                                 } else {
568                                         _icon = "icon.inWORK.png";
569                                 }
570                         }
571                 } else {
572                         if (_me.getOwnerStudy().shares(_mydoc)) {
573                                 _sharing = "image.share.png";
574                                 _updated = "icon.hold.png";
575                         }
576                         //if (_me.isOutdated()) {
577                         //      _state = ProgressState.inWORK; // Overrides the document state
578                         //}
579                 }
580         }
581
582         /**
583          * Initialize document's popup menu.
584          */
585         private final void initPopupMenu() {
586                 // Popup menus
587                 if (_me != null) { // There is a pop-up
588                         if (_state == ProgressState.EXTERN) {
589                                 _popup = getApplicationSettings().getPopupMenu("extern");
590                         } else if (_state == ProgressState.inWORK) {
591                                 _popup = getApplicationSettings().getPopupMenu("editable");
592                         } else if (_state == ProgressState.inDRAFT) {
593                                 if(_owner.getUser().equals(_me.value().getAuthor())) { //connected usr is the author of the document
594                                         _popup = getApplicationSettings().getPopupMenu("reviewable");
595                                 } else {
596                                         _popup = getApplicationSettings().getPopupMenu("reviewableNonAuthor");
597                                 }
598                         } else if (_state == ProgressState.APPROVED) {
599                                 _popup = getApplicationSettings().getPopupMenu("approved");
600                         } else { // (state == ProgressState.inCHECK)
601                                 DocumentType aType = _me.value().getType(); // Only result documents need to be approved
602                                 Step aStep = getPublicationService().getInvolvedStep(_me);
603                                 if (aType.isResultOf(aStep.getStep())) {
604                                         if(_owner.getUser().equals(_me.value().getAuthor())) {
605                                                 _popup = getApplicationSettings().getPopupMenu("approvable");
606                                         } else {
607                                                 _popup = getApplicationSettings().getPopupMenu("approvableNonAuthor");
608                                         }
609                                 } else {
610                                         if(_owner.getUser().equals(_me.value().getAuthor())) { //connected usr is the author of the document
611                                                 _popup = getApplicationSettings().getPopupMenu("notresult");
612                                         } else {
613                                                 _popup = getApplicationSettings().getPopupMenu("notresultNonAuthor");
614                                         }
615                                 }
616                         }
617                 }
618         }
619
620         /**
621          * Turn on the versioning icon.
622          */
623         protected void setVersioned() {
624                 _updated = "image.modified.png";
625         }
626
627         // ==============================================================================================================================
628         // Private services
629         // ==============================================================================================================================
630
631         /**
632          * Collect the document's previous versions presentation.
633          * 
634          * @param given
635          *            the document to explore
636          */
637         private final void collectHistory(final Document given) {
638                 VersionsRelation versions = (VersionsRelation) given
639                                 .getFirstRelation(VersionsRelation.class);
640                 Timestamp[] stamp = given.getStamps(); // Stamps in ascending order of date
641
642                 for (int i = stamp.length - 1; i > -1; i--) {
643                         _history.add(new StampFacade(stamp[i], getApplicationSettings()
644                                         .getCurrentLocale()));
645                 }
646                 _history.add(new DocumentFacade(_owner, given, getProjectSettings(),
647                                 getPublicationService(), getApplicationSettings()));
648                 if (versions != null) {
649                         this.collectHistory(versions.getTo());
650                 }
651         }
652
653         /**
654          * Get project settings.
655          * 
656          * @return Project settings service
657          */
658         private ProjectSettingsService getProjectSettings() {
659                 return _projectSettings;
660         }
661
662         /**
663          * Set project settings service.
664          * 
665          * @param projectSettingsService
666          *            project settings service
667          */
668         public final void setProjectSettings(
669                         final ProjectSettingsService projectSettingsService) {
670                 _projectSettings = projectSettingsService;
671         }
672
673         /**
674          * Get the publicationService.
675          * 
676          * @return the publicationService
677          */
678         public PublicationService getPublicationService() {
679                 return _publicationService;
680         }
681
682         /**
683          * Set the publicationService.
684          * 
685          * @param publicationService
686          *            the publicationService to set
687          */
688         public final void setPublicationService(
689                         final PublicationService publicationService) {
690                 _publicationService = publicationService;
691         }
692
693         /**
694          * Get the applicationSettings.
695          * 
696          * @return the applicationSettings
697          */
698         public ApplicationSettings getApplicationSettings() {
699                 return _applicationSettings;
700         }
701
702         /**
703          * Set the applicationSettings.
704          * 
705          * @param applicationSettings
706          *            the applicationSettings to set
707          */
708         public final void setApplicationSettings(
709                         final ApplicationSettings applicationSettings) {
710                 _applicationSettings = applicationSettings;
711         }
712 }