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