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