1 package org.splat.simer;
5 * @author Daniel Brunier-Coulin
6 * @copyright OPEN CASCADE 2012
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;
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;
35 * Document wrapper class for presentation layer.
37 public class DocumentFacade implements HistoryFacade {
42 static private final String ICON_EXT = ".png";
46 private final transient AbstractOpenObject _owner;
48 * Wrapped document publication.
50 private final transient Publication _me;
54 private final transient Document _mydoc;
58 private transient ProgressState _state;
60 * My document version in customized format.
62 private transient String _version;
64 * Presentation state: open, deep open, closed.
66 * @see DocumentFacade.State
68 private transient State _display;
70 * URL of the source file.
72 private transient String _surl;
76 private transient String _icon;
78 * Icon qualifying sharing between scenarios of a same study.
80 private transient String _sharing;
82 * Icon qualifying versioning from the previous study version.
84 private transient String _updated;
88 private transient String _size;
90 * Document last modification date.
92 private transient String _date;
94 * Document's description.
96 private transient String _description;
98 * List of used documents presentations.
100 private transient List<DocumentFacade> _uses;
102 * List of attached files presentations.
104 private transient List<FileFacade> _exports;
106 * List of the document's history nodes.
108 private transient List<HistoryFacade> _history;
110 * Document's popup menu.
112 private transient PopupMenu _popup;
114 * Injected project settings service.
116 private ProjectSettingsService _projectSettings;
118 * Injected publication service.
120 private PublicationService _publicationService;
122 * Injected application settings.
124 private ApplicationSettings _applicationSettings;
127 * Document presentation state enumeration.
131 * Closed presentation state.
135 * Open presentation state (history and attached files nodes are visible).
139 * Deeply open presentation.
144 // ==============================================================================================================================
146 // ==============================================================================================================================
154 * document presentation
155 * @param projectSettings
156 * project settings service
157 * @param publicationService
158 * publication service
159 * @param applicationSettings
160 * application settings
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);
172 _mydoc = _me.value();
173 _state = _mydoc.getProgressState();
174 _display = State.closed;
176 refresh(); // Initializes the presentation of my document //NOPMD:RKV: to be reviewed
180 * Constructs the facade of a document presented in the history folder.
185 * document presentation
186 * @param projectSettings
187 * project settings service
188 * @param publicationService
189 * publication service
190 * @param applicationSettings
191 * application settings
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);
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(
209 + " " + _mydoc.getAuthor().toString();
211 this.refresh(); // Initializes the presentation of my document
214 // ==============================================================================================================================
215 // Public member functions
216 // ==============================================================================================================================
219 * Open the presentation subtree.
221 public void develop() {
222 if (_display == State.open) { // Opening the history of document, if exist
223 if (_history.isEmpty()) {
224 collectHistory(_mydoc);
226 _display = State.deepopen;
227 } else { // Opening the document
229 List<Publication> relist = _me.getRelations(UsesRelation.class);
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);
245 if (_exports == null) {
246 List<Relation> relation = _mydoc
247 .getRelations(ConvertsRelation.class);
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()));
256 if (_history == null) {
257 if (_mydoc.getPreviousVersion() != null
258 || _state == ProgressState.inCHECK
259 || _state == ProgressState.APPROVED) {
260 _history = new ArrayList<HistoryFacade>();
263 _display = State.open;
268 * Close the presentation tree partially.
270 public void reduce() {
271 if (_display == State.deepopen) {
272 _display = State.open;
277 * Close the presentation tree.
279 public void reduceAll() {
280 _display = State.closed;
283 // ==============================================================================================================================
285 // ==============================================================================================================================
288 * Get a list of attached files presentations.
290 * @return list of FileFacades
292 public List<FileFacade> getAttachments() {
299 * @see org.splat.simer.HistoryFacade#getDate()
301 public String getDate() {
308 * @see org.splat.simer.HistoryFacade#getDescription()
310 public String getDescription() {
315 * Get a document edit icon file name according to the document state.
317 * @return the icon file name
319 public String getEditIcon() {
320 return "icon.ed" + _state + ICON_EXT;
326 * @see org.splat.simer.HistoryFacade#getFileIcon()
328 public String getFileIcon() {
333 * Get the document history presentation.
335 * @return the history facade
337 public List<HistoryFacade> getHistory() {
342 * Get the document persistent id.
344 * @return the document persistent id
346 public String getIndex() {
347 return String.valueOf(_mydoc.getIndex());
351 * Get the document contextual popup menu.
353 * @return the document popup menu
355 public PopupMenu getPopup() { // Contextualizes the pop-up
357 .setContext("document", new DocumentRights(_owner.getUser(),
359 return _popup; // callers must "use" the returned pop-up before getting another pop-up
363 * Get the document presentation state: open, deep open, closed.
365 * @return the document presentation state
366 * @see DocumentFacade.State
368 public String getPresentationState() {
369 return _display.toString();
373 * Get document progress state.
375 * @return the document state
378 public String getProgressState() {
379 return _state.toString();
385 * @see org.splat.simer.HistoryFacade#getSharingIcon()
387 public String getSharingIcon() {
394 * @see org.splat.simer.HistoryFacade#getSize()
396 public String getSize() {
401 * Get a document state icon file name according to the document state.
403 * @return the icon file name
405 public String getStateIcon() {
406 return "icon." + _state + ICON_EXT;
410 * Get the document title.
412 * @return the document title
414 public String getTitle() {
415 return _mydoc.getTitle();
419 * Get the URL of the document in the repository.
421 * @return the document URL
423 public String getURL() {
428 * Get the list of used documents presentations.
430 * @return list of DocumentFacades
432 public List<DocumentFacade> getUses() {
439 * @see org.splat.simer.HistoryFacade#getVersion()
441 public String getVersion() {
448 * @see org.splat.simer.HistoryFacade#getVersioningIcon()
450 public String getVersioningIcon() {
455 * Check if this is a representation of the given document publication.
458 * the document publication
459 * @return true if this facades represents the given document publication
461 public boolean isFacadeOf(final Publication represented) {
462 return _me.equals(represented);
465 // ==============================================================================================================================
466 // Protected services
467 // ==============================================================================================================================
470 * Refresh the document presentation.
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();
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();
491 _surl = getApplicationSettings().getRepositoryURL() + path;
492 _surl = _surl.replaceAll("'", "\\\\'");
494 // Document state (overridable by the publication - see below)
495 _state = _mydoc.getProgressState();
496 _version = _mydoc.getVersion(); // May be null
500 // Document description
501 VersionsRelation versions = (VersionsRelation) _mydoc
502 .getFirstRelation(VersionsRelation.class);
503 if (versions != null) {
504 _description = versions.getDescription();
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());
513 // Refresh of the history in case of promotion
514 if (_display == State.deepopen) {
516 this.collectHistory(_mydoc);
522 * Initialize document presentation icons.
524 private final void initIcons() {
526 String format = _mydoc.getFormat();
527 if ("xml".equals(format)) {
528 format = XMLDocument.getActualFormat(_mydoc.getSourceFile()
530 if ("schema".equals(_mydoc.getType().getName())) {
535 _icon = "icon." + format + ICON_EXT;
536 _sharing = "image.hold.gif";
537 _updated = "image.hold.gif";
538 File image = new File(ApplicationSettings.getApplicationSkinPath()
540 if (!image.exists()) {
541 _icon = "icon.any.png";
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";
551 if (_state == ProgressState.inWORK) {
552 _icon = "icon." + _state.toString() + ICON_EXT;
554 _icon = "icon.inWORK.png";
558 if (_me.getOwnerStudy().shares(_mydoc)) {
559 _sharing = "image.share.png";
560 _updated = "icon.hold.png";
562 if (_me.isOutdated()) {
563 _state = ProgressState.inWORK; // Overrides the document state
569 * Initialize document's popup menu.
571 private final void initPopupMenu() {
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");
589 _popup = getApplicationSettings().getPopupMenu("notresult");
596 * Turn on the versioning icon.
598 protected void setVersioned() {
599 _updated = "image.modified.png";
602 // ==============================================================================================================================
604 // ==============================================================================================================================
607 * Collect the document's previous versions presentation.
610 * the document to explore
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
617 for (int i = stamp.length - 1; i > -1; i--) {
618 _history.add(new StampFacade(stamp[i], getApplicationSettings()
619 .getCurrentLocale()));
621 _history.add(new DocumentFacade(_owner, given, getProjectSettings(),
622 getPublicationService(), getApplicationSettings()));
623 if (versions != null) {
624 this.collectHistory(versions.getTo());
629 * Get project settings.
631 * @return Project settings service
633 private ProjectSettingsService getProjectSettings() {
634 return _projectSettings;
638 * Set project settings service.
640 * @param projectSettingsService
641 * project settings service
643 public final void setProjectSettings(
644 final ProjectSettingsService projectSettingsService) {
645 _projectSettings = projectSettingsService;
649 * Get the publicationService.
651 * @return the publicationService
653 public PublicationService getPublicationService() {
654 return _publicationService;
658 * Set the publicationService.
660 * @param publicationService
661 * the publicationService to set
663 public final void setPublicationService(
664 final PublicationService publicationService) {
665 _publicationService = publicationService;
669 * Get the applicationSettings.
671 * @return the applicationSettings
673 public ApplicationSettings getApplicationSettings() {
674 return _applicationSettings;
678 * Set the applicationSettings.
680 * @param applicationSettings
681 * the applicationSettings to set
683 public final void setApplicationSettings(
684 final ApplicationSettings applicationSettings) {
685 _applicationSettings = applicationSettings;