Salome HOME
- Back-arrow is added when the user selects the new product on the new study screen
[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.Iterator;
14 import java.util.List;
15 import java.util.ResourceBundle;
16
17 import org.splat.dal.bo.kernel.Relation;
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<Publication> relist = _me.getRelations(UsesRelation.class);
230
231                                 _uses = new ArrayList<DocumentFacade>(relist.size());
232                                 for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
233                                         Publication used = i.next();
234                                         long index = used.getIndex();
235                                         DocumentFacade facade = _owner._docpres.get(index);
236                                         if (facade == null) {
237                                                 facade = new DocumentFacade(_owner, used,
238                                                                 getProjectSettings(), getPublicationService(),
239                                                                 getApplicationSettings());
240                                                 _owner._docpres.put(index, facade);
241                                         }
242                                         _uses.add(facade);
243                                 }
244                         }
245                         if (_exports == null) {
246                                 updateExports();
247                         }
248                         if (_history == null) {
249                                 if (_mydoc.getPreviousVersion() != null
250                                                 || _state == ProgressState.inCHECK
251                                                 || _state == ProgressState.APPROVED) {
252                                         _history = new ArrayList<HistoryFacade>();
253                                 }
254                         }
255                         _display = State.open;
256                 }
257         }
258         
259         /**
260          * Update the list of export files.
261          */
262         private void updateExports() {
263                 List<Relation> relations = _mydoc
264                                 .getRelations(ConvertsRelation.class);
265
266                 _exports = new ArrayList<FileFacade>(relations.size());
267                 for (Relation rel : relations) {
268                         _exports.add(new FileFacade((ConvertsRelation)rel,
269                                         getApplicationSettings()));
270                 }
271         }
272
273         /**
274          * Close the presentation tree partially.
275          */
276         public void reduce() {
277                 if (_display == State.deepopen) {
278                         _display = State.open;
279                 }
280         }
281
282         /**
283          * Close the presentation tree.
284          */
285         public void reduceAll() {
286                 _display = State.closed;
287         }
288
289         // ==============================================================================================================================
290         // Getters
291         // ==============================================================================================================================
292
293         /**
294          * Get a list of attached files presentations.
295          * 
296          * @return list of FileFacades
297          */
298         public List<FileFacade> getAttachments() {
299                 return _exports;
300         }
301
302         /**
303          * {@inheritDoc}
304          * 
305          * @see org.splat.simer.HistoryFacade#getDate()
306          */
307         public String getDate() {
308                 return _date;
309         }
310
311         /**
312          * {@inheritDoc}
313          * 
314          * @see org.splat.simer.HistoryFacade#getDescription()
315          */
316         public String getDescription() {
317                 return _description;
318         }
319
320         /**
321          * Get a document edit icon file name according to the document state.
322          * 
323          * @return the icon file name
324          */
325         public String getEditIcon() {
326                 return "icon.ed" + _state + ICON_EXT;
327         }
328
329         /**
330          * {@inheritDoc}
331          * 
332          * @see org.splat.simer.HistoryFacade#getFileIcon()
333          */
334         public String getFileIcon() {
335                 return _icon;
336         }
337
338         /**
339          * Get the document history presentation.
340          * 
341          * @return the history facade
342          */
343         public List<HistoryFacade> getHistory() {
344                 return _history;
345         }
346
347         /**
348          * Get the document persistent id.
349          * 
350          * @return the document persistent id
351          */
352         public String getIndex() {
353                 return String.valueOf(_mydoc.getIndex());
354         }
355
356         /**
357          * Get the document contextual popup menu.
358          * 
359          * @return the document popup menu
360          */
361         public PopupMenu getPopup() { // Contextualizes the pop-up
362                 _popup
363                                 .setContext("document", new DocumentRights(_owner.getUser(),
364                                                 _me));
365                 return _popup; // callers must "use" the returned pop-up before getting another pop-up
366         }
367
368         /**
369          * Get the document presentation state: open, deep open, closed.
370          * 
371          * @return the document presentation state
372          * @see DocumentFacade.State
373          */
374         public String getPresentationState() {
375                 return _display.toString();
376         }
377
378         /**
379          * Get document progress state.
380          * 
381          * @return the document state
382          * @see ProgressState
383          */
384         public String getProgressState() {
385                 return _state.toString();
386         }
387
388         /**
389          * {@inheritDoc}
390          * 
391          * @see org.splat.simer.HistoryFacade#getSharingIcon()
392          */
393         public String getSharingIcon() {
394                 return _sharing;
395         }
396
397         /**
398          * {@inheritDoc}
399          * 
400          * @see org.splat.simer.HistoryFacade#getSize()
401          */
402         public String getSize() {
403                 return _size;
404         }
405
406         /**
407          * Get a document state icon file name according to the document state.
408          * 
409          * @return the icon file name
410          */
411         public String getStateIcon() {
412                 return "icon." + _state + ICON_EXT;
413         }
414
415         /**
416          * Get the document title.
417          * 
418          * @return the document title
419          */
420         public String getTitle() {
421                 return _mydoc.getTitle();
422         }
423
424         /**
425          * Get the URL of the document in the repository.
426          * 
427          * @return the document URL
428          */
429         public String getURL() {
430                 return _surl;
431         }
432
433         /**
434          * Get the list of used documents presentations.
435          * 
436          * @return list of DocumentFacades
437          */
438         public List<DocumentFacade> getUses() {
439                 return _uses;
440         }
441
442         /**
443          * {@inheritDoc}
444          * 
445          * @see org.splat.simer.HistoryFacade#getVersion()
446          */
447         public String getVersion() {
448                 return _version;
449         }
450
451         /**
452          * {@inheritDoc}
453          * 
454          * @see org.splat.simer.HistoryFacade#getVersioningIcon()
455          */
456         public String getVersioningIcon() {
457                 return _updated;
458         }
459
460         /**
461          * Check if this is a representation of the given document publication.
462          * 
463          * @param represented
464          *            the document publication
465          * @return true if this facades represents the given document publication
466          */
467         public boolean isFacadeOf(final Publication represented) {
468                 return _me.equals(represented);
469         }
470
471         // ==============================================================================================================================
472         // Protected services
473         // ==============================================================================================================================
474
475         /**
476          * Refresh the document presentation.
477          */
478         protected final void refresh() {
479                 ResourceBundle custom = ResourceBundle.getBundle("som",
480                                 getApplicationSettings().getCurrentLocale());
481                 DecimalFormat sizstring = new DecimalFormat(custom
482                                 .getString("size.format")); // Locale size display format
483                 SimpleDateFormat datstring = new SimpleDateFormat(custom
484                                 .getString("date.format"), getApplicationSettings()
485                                 .getCurrentLocale()); // Locale date display format
486                 String path = _mydoc.getSourceFile().getRelativePath();
487                 String[] mapping = ApplicationSettings.getViewersMapping();
488
489                 for (int i = 0; i < mapping.length; i++) {
490                         org.splat.dal.bo.som.File export = _mydoc
491                                         .getAttachedFile(mapping[i]);
492                         if (export != null) {
493                                 path = export.getRelativePath();
494                                 break;
495                         }
496                 }
497                 _surl = getApplicationSettings().getRepositoryURL() + path;
498                 _surl = _surl.replaceAll("'", "\\\\'");
499
500                 // Document state (overridable by the publication - see below)
501                 _state = _mydoc.getProgressState();
502                 _version = _mydoc.getVersion(); // May be null
503
504                 initIcons();
505
506                 // Document description
507                 VersionsRelation versions = (VersionsRelation) _mydoc
508                                 .getFirstRelation(VersionsRelation.class);
509                 if (versions != null) {
510                         _description = versions.getDescription();
511                 }
512                 // File details
513                         Revision.Format verstring = new Revision.Format(
514                                         getProjectSettings().getRevisionPattern());
515                         _version = verstring.format(_version);
516                 _size = sizstring.format(_mydoc.getSourceFile().asFile().length() / 1000);
517                 _date = datstring.format(_mydoc.getLastModificationDate());
518                 updateExports();
519                 // Refresh of the history in case of promotion
520                 if (_display == State.deepopen) {
521                         _history.clear();
522                         this.collectHistory(_mydoc);
523                 }
524                 initPopupMenu();
525         }
526
527         /**
528          * Initialize document presentation icons.
529          */
530         private final void initIcons() {
531                 // Icons definition
532                 String format = _mydoc.getFormat();
533                 if ("xml".equals(format)) {
534                         format = XMLDocument.getActualFormat(_mydoc.getSourceFile()
535                                         .asFile());
536                         if ("schema".equals(_mydoc.getType().getName())) {
537                                 format = "schema";
538                         }
539                 }
540
541                 _icon = "icon." + format + ICON_EXT;
542                 _sharing = "image.hold.gif";
543                 _updated = "image.hold.gif";
544                 File image = new File(ApplicationSettings.getApplicationSkinPath()
545                                 + _icon);
546                 if (!image.exists()) {
547                         _icon = "icon.any.png";
548                 }
549
550                 if (_me == null) { // Facade in the history folder
551                         if (_mydoc.isVersioned()) { // History of the last version
552                                 if (_mydoc.isPublished()) {
553                                         _sharing = "image.share.png"; // Not correct if published in a previous version of the study
554                                         _updated = "icon.hold.png";
555                                 }
556                         } else {
557                                 if (_state == ProgressState.inWORK) {
558                                         _icon = "icon." + _state.toString() + ICON_EXT;
559                                 } else {
560                                         _icon = "icon.inWORK.png";
561                                 }
562                         }
563                 } else {
564                         if (_me.getOwnerStudy().shares(_mydoc)) {
565                                 _sharing = "image.share.png";
566                                 _updated = "icon.hold.png";
567                         }
568                         if (_me.isOutdated()) {
569                                 _state = ProgressState.inWORK; // Overrides the document state
570                         }
571                 }
572         }
573
574         /**
575          * Initialize document's popup menu.
576          */
577         private final void initPopupMenu() {
578                 // Popup menus
579                 if (_me != null) { // There is a pop-up
580                         if (_state == ProgressState.EXTERN) {
581                                 _popup = getApplicationSettings().getPopupMenu("extern");
582                         } else if (_state == ProgressState.inWORK) {
583                                 _popup = getApplicationSettings().getPopupMenu("editable");
584                         } else if (_state == ProgressState.inDRAFT) {
585                                 _popup = getApplicationSettings().getPopupMenu("reviewable");
586                         } else if (_state == ProgressState.APPROVED) {
587                                 _popup = getApplicationSettings().getPopupMenu("approved");
588                         } else { // (state == ProgressState.inCHECK)
589                                 DocumentType aType = _me.value().getType(); // Only result documents need to be approved
590                                 Step aStep = getPublicationService().getInvolvedStep(_me);
591                                 if (aType.isResultOf(aStep.getStep())) {
592                                         _popup = getApplicationSettings()
593                                                         .getPopupMenu("approvable");
594                                 } else {
595                                         _popup = getApplicationSettings().getPopupMenu("notresult");
596                                 }
597                         }
598                 }
599         }
600
601         /**
602          * Turn on the versioning icon.
603          */
604         protected void setVersioned() {
605                 _updated = "image.modified.png";
606         }
607
608         // ==============================================================================================================================
609         // Private services
610         // ==============================================================================================================================
611
612         /**
613          * Collect the document's previous versions presentation.
614          * 
615          * @param given
616          *            the document to explore
617          */
618         private final void collectHistory(final Document given) {
619                 VersionsRelation versions = (VersionsRelation) given
620                                 .getFirstRelation(VersionsRelation.class);
621                 Timestamp[] stamp = given.getStamps(); // Stamps in ascending order of date
622
623                 for (int i = stamp.length - 1; i > -1; i--) {
624                         _history.add(new StampFacade(stamp[i], getApplicationSettings()
625                                         .getCurrentLocale()));
626                 }
627                 _history.add(new DocumentFacade(_owner, given, getProjectSettings(),
628                                 getPublicationService(), getApplicationSettings()));
629                 if (versions != null) {
630                         this.collectHistory(versions.getTo());
631                 }
632         }
633
634         /**
635          * Get project settings.
636          * 
637          * @return Project settings service
638          */
639         private ProjectSettingsService getProjectSettings() {
640                 return _projectSettings;
641         }
642
643         /**
644          * Set project settings service.
645          * 
646          * @param projectSettingsService
647          *            project settings service
648          */
649         public final void setProjectSettings(
650                         final ProjectSettingsService projectSettingsService) {
651                 _projectSettings = projectSettingsService;
652         }
653
654         /**
655          * Get the publicationService.
656          * 
657          * @return the publicationService
658          */
659         public PublicationService getPublicationService() {
660                 return _publicationService;
661         }
662
663         /**
664          * Set the publicationService.
665          * 
666          * @param publicationService
667          *            the publicationService to set
668          */
669         public final void setPublicationService(
670                         final PublicationService publicationService) {
671                 _publicationService = publicationService;
672         }
673
674         /**
675          * Get the applicationSettings.
676          * 
677          * @return the applicationSettings
678          */
679         public ApplicationSettings getApplicationSettings() {
680                 return _applicationSettings;
681         }
682
683         /**
684          * Set the applicationSettings.
685          * 
686          * @param applicationSettings
687          *            the applicationSettings to set
688          */
689         public final void setApplicationSettings(
690                         final ApplicationSettings applicationSettings) {
691                 _applicationSettings = applicationSettings;
692         }
693 }