Salome HOME
aa9b6ddaaa031542e36cdf696eedadae92a4d608
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / dal / bo / som / Document.java
1 package org.splat.dal.bo.som;
2
3 /**
4  * 
5  * @author    Daniel Brunier-Coulin
6  * @copyright OPEN CASCADE 2012
7  */
8
9 import java.util.Arrays;
10 import java.util.Date;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Vector;
14
15 import org.splat.dal.bo.kernel.Entity;
16 import org.splat.dal.bo.kernel.Persistent;
17 import org.splat.dal.bo.kernel.Relation;
18 import org.splat.dal.bo.kernel.User;
19 import org.splat.dal.bo.som.Timestamp.ComparatorByDate;
20 import org.splat.kernel.InvalidPropertyException;
21 import org.splat.kernel.MissedPropertyException;
22 import org.splat.kernel.MultiplyDefinedException;
23 import org.splat.service.technical.ProjectSettingsService;
24 import org.splat.som.Revision;
25 import org.splat.som.Step;
26
27 /**
28  * Document persistent class.
29  */
30 public class Document extends Entity {
31
32         // Persistent fields
33         private DocumentType type; // User expendable types
34         private File myfile;
35         private String did;
36         private int step;
37         private ProgressState state;
38         private String name;
39         private String version;
40         private int countag;
41         private int history;
42         private User author;
43         private Date lasdate;
44
45         // Transient fields
46         public static String suformat = "00"; // Format of the suffix number of document did and file name
47
48         // ==============================================================================================================================
49         // Construction
50         // ==============================================================================================================================
51
52         /**
53          * Fields initialization class.
54          */
55         public static class Properties extends Persistent.Properties {
56                 // ------------------------------------------------------------
57                 private DocumentType type = null;
58                 private String did = null; // Only for searching from a given reference
59                 private ProjectElement owner = null; // Only for constructing a document
60                 private ProjectSettingsService.Step step = null;
61                 private ProgressState state = null;
62                 private String name = null;
63                 protected String format = null;
64                 private String version = null;
65                 private User author = null;
66                 protected Date date = null;
67                 private String summary = null; // Only for versioning a document
68                 private String path = null; // Only for searching from a given path
69
70                 // - Public services
71
72                 @Override
73                 public void clear() {
74                         super.clear();
75                         type = null;
76                         did = null;
77                         owner = null;
78                         step = null;
79                         state = null;
80                         name = null;
81                         format = null;
82                         version = null;
83                         author = null;
84                         date = null;
85                         summary = null;
86                         path = null;
87                 }
88
89                 public Properties copy() {
90                         Properties copy = new Properties();
91                         copy.type = this.type;
92                         copy.did = this.did;
93                         copy.owner = this.owner;
94                         copy.step = this.step;
95                         copy.state = this.state;
96                         copy.name = this.name;
97                         copy.format = this.format;
98                         copy.version = this.version;
99                         copy.author = this.author;
100                         copy.date = this.date;
101                         copy.summary = this.summary;
102                         copy.path = this.path;
103                         return copy;
104                 }
105
106                 // - Protected services
107
108                 public User getAuthor() {
109                         return author;
110                 }
111
112                 public String getDescription() {
113                         return summary;
114                 }
115
116                 public String getLocalPath() {
117                         return path;
118                 }
119
120                 public String getReference() {
121                         return did;
122                 }
123
124                 public ProjectSettingsService.Step getStep() {
125                         return step;
126                 }
127
128                 public DocumentType getType() {
129                         return type;
130                 }
131
132                 // - Property setters
133
134                 public Properties setAuthor(final User user) {
135                         this.author = user;
136                         return this;
137                 }
138
139                 public Properties setDate(final Date date) {
140                         this.date = date;
141                         return this;
142                 }
143
144                 /**
145                  * Get the date.
146                  * 
147                  * @return the date
148                  */
149                 public Date getDate() {
150                         return date;
151                 }
152
153                 public Properties setDescription(final String summary)
154                                 throws InvalidPropertyException {
155                         if (summary.length() == 0) {
156                                 throw new InvalidPropertyException("description");
157                         }
158                         this.summary = summary;
159                         return this;
160                 }
161
162                 /**
163                  * Copy base properties from the given original document for versioning.
164                  * 
165                  * @param base
166                  *            the original document
167                  * @param aStep
168                  *            study step
169                  * @return document properties
170                  */
171                 public Properties setDocument(final Document base,
172                                 final ProjectSettingsService.Step aStep) {
173                         type = base.type;
174                         step = aStep;
175                         name = base.name;
176                         format = base.getFormat();
177                         state = ProgressState.inWORK; // For incrementing the version number at save time
178                         version = base.version;
179                         return this;
180                 }
181
182                 public Properties setExternReference(final String ref)
183                                 throws InvalidPropertyException {
184                         if (ref.length() == 0) {
185                                 throw new InvalidPropertyException("reference");
186                         }
187                         if (ref.equals(new Revision().toString())) {
188                                 throw new InvalidPropertyException("reference"); // Internal version number
189                         }
190                         this.version = ref;
191                         return this;
192                 }
193
194                 public Properties setFormat(final String format)
195                                 throws InvalidPropertyException {
196                         if (format.length() == 0) {
197                                 throw new InvalidPropertyException("format");
198                         }
199                         this.format = format;
200                         return this;
201                 }
202
203                 // Required only for passing search arguments
204                 public Properties setLocalPath(final String path)
205                                 throws InvalidPropertyException {
206                         if (path.length() == 0) {
207                                 throw new InvalidPropertyException("path");
208                         }
209                         this.path = path;
210                         return this;
211                 }
212
213                 public Properties setName(final String name)
214                                 throws InvalidPropertyException {
215                         if (name.length() == 0) {
216                                 throw new InvalidPropertyException("name");
217                         }
218                         this.name = name;
219                         return this;
220                 }
221
222                 public String getName() {
223                         return this.name;
224                 }
225
226                 public Properties setOwner(final ProjectElement owner) {
227                         this.owner = owner;
228                         return this;
229                 }
230
231                 public ProjectElement getOwner() {
232                         return this.owner;
233                 }
234
235                 // Required only for passing search arguments
236                 public Properties setReference(final String did)
237                                 throws InvalidPropertyException {
238                         if (did.length() == 0) {
239                                 throw new InvalidPropertyException("reference");
240                         }
241                         this.did = did;
242                         return this;
243                 }
244
245                 public Properties setState(final ProgressState state)
246                                 throws InvalidPropertyException {
247                         if (state == ProgressState.inPROGRESS
248                                         || state == ProgressState.TEMPLATE) {
249                                 throw new InvalidPropertyException("state"); // Non document states
250                         }
251                         this.state = state;
252                         return this;
253                 }
254
255                 public Properties setStep(final ProjectSettingsService.Step step) {
256                         this.step = step;
257                         return this;
258                 }
259
260                 public Properties setType(final DocumentType type) {
261                         this.type = type;
262                         return this;
263                 }
264
265                 // - Global validity check
266
267                 public void checkValidity() throws MissedPropertyException,
268                                 InvalidPropertyException, MultiplyDefinedException {
269                         if (type == null) {
270                                 throw new MissedPropertyException("type");
271                         }
272                         if (owner == null) {
273                                 throw new MissedPropertyException("owner");
274                         }
275                         if (step == null) {
276                                 throw new MissedPropertyException("step");
277                         }
278                         if (author == null) {
279                                 throw new MissedPropertyException("author");
280                         }
281                         if (format == null) {
282                                 throw new MissedPropertyException("format");
283                         }
284                         if (owner instanceof Study && !step.appliesTo(Study.class)) {
285                                 throw new InvalidPropertyException("step");
286                         }
287                         if (!type.isContentInto(step)) {
288                                 throw new InvalidPropertyException("step");
289                         }
290                         if (state != null && state != ProgressState.EXTERN) {
291                                 // inDRAFT, inCHECK or APPROVED + version = imposed version (future use)
292                                 // inWORK + version = base version incremented at save time (used for versioning)
293                                 if (version == null) {
294                                         throw new InvalidPropertyException("state");
295                                 }
296                         }
297                         if (version != null) {
298                                 if (state == null) {
299                                         state = ProgressState.EXTERN;
300                                 }
301                         }
302                 }
303
304                 /**
305                  * Get the format.
306                  * @return the format
307                  */
308                 public String getFormat() {
309                         return format;
310                 }
311         }
312
313         /**
314          * Database fetch constructor.
315          */
316         protected Document() {
317                 super();
318         }
319
320         /**
321          * Initialization constructor.
322          * @param dprop
323          * @throws MissedPropertyException
324          * @throws InvalidPropertyException
325          * @throws MultiplyDefinedException
326          */
327         public Document(final Properties dprop) throws MissedPropertyException,
328                         InvalidPropertyException, MultiplyDefinedException {
329                 super(dprop); // Throws one of the above exception if not valid
330                 myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
331                 type = dprop.type;
332                 step = dprop.step.getNumber();
333                 name = dprop.name;
334                 version = dprop.version;
335                 author = dprop.author;
336                 countag = 0;
337                 history = 0;
338                 lasdate = myfile.getDate(); // Today if not defined in the properties
339
340                 state = dprop.state;
341                 if (state == null) {
342                         state = ProgressState.inWORK; // Promoted when saving this document
343                         version = new Revision().toString();
344                 }
345                 if (name == null) { // Newed document
346                         this.name = "%n"; // Named later at publication
347                         this.history = -1; // Marks the document as undefined for future assignment
348                 }
349         }
350
351         // ==============================================================================================================================
352         // Public member functions
353         // ==============================================================================================================================
354
355         public File getAttachedFile(final String format) {
356                 List<Relation> exports = getRelations(ConvertsRelation.class);
357
358                 for (Iterator<Relation> i = exports.iterator(); i.hasNext();) {
359                         File export = (File) i.next().getTo();
360                         if (export.getFormat().equals(format)) {
361                                 return export;
362                         }
363                 }
364                 return null;
365         }
366
367         public User getAuthor() {
368                 return author;
369         }
370
371         public Date getCreationDate() {
372                 return myfile.getDate();
373         }
374
375         public Date getLastModificationDate() {
376                 return lasdate;
377         }
378
379         public void setLastModificationDate(final Date aDate) {
380                 lasdate = aDate;
381         }
382
383         public String getFormat() {
384                 return myfile.getFormat();
385         }
386
387         public Document getPreviousVersion() {
388                 Relation previous = getFirstRelation(VersionsRelation.class);
389                 if (previous == null) {
390                         return null;
391                 } else {
392                         return (Document) previous.getTo();
393                 }
394         }
395
396         public ProgressState getProgressState() {
397                 return state;
398         }
399
400         /**
401          * Returns the path where all physical files attached to this document are saved. This path is relative to the vault of the repository
402          * and include the file name, without extension, common to all physical files attached to this document.
403          * 
404          * @return the path of the document
405          */
406         public String getRelativePath() {
407                 String[] table = myfile.getRelativePath().split("\\x2E");
408                 StringBuffer path = new StringBuffer(table[0]);
409                 for (int i = 1; i < table.length - 1; i++) {
410                         path.append('.').append(table[i]);
411                 }
412                 return path.toString();
413         }
414
415         /**
416          * Returns the global unique reference of this document lineage. The document reference is common to all versions of the document
417          * (versioning a document does not change its reference). It is made of the owner study reference suffixed by a document identifier
418          * unique in the scope of the study.
419          * 
420          * @return the document reference
421          */
422         public String getReference() {
423                 return did;
424         }
425
426         public File getSourceFile() {
427                 return myfile;
428         }
429
430         /**
431          * Returns the stamps such as review and approval attached to this document, if exist. If several stamps exist, they are returned in
432          * ascending order of dates.
433          * 
434          * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
435          */
436         public Timestamp[] getStamps() {
437                 Vector<Timestamp> stamps = new Vector<Timestamp>();
438
439                 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
440                                 .hasNext();) {
441                         Relation link = i.next();
442                         if (link instanceof StampRelation) {
443                                 stamps.add(((StampRelation) link).getTo());
444                         }
445                 }
446                 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
447                 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
448
449                 Arrays.sort(result, bydate);
450                 return result;
451         }
452
453         /**
454          * Returns the title of this document.
455          * 
456          * @return the document title, or an empty string is this document is undefined.
457          * @see #isUndefined()
458          */
459         public String getTitle() {
460                 // -------------------------
461                 if (this.isUndefined()) {
462                         return "";
463                 } else {
464                         return name;
465                 }
466         }
467
468         /**
469          * Set document title.
470          * 
471          * @param aTitle
472          *            document title to set
473          */
474         public void setTitle(final String aTitle) {
475                 this.name = aTitle;
476         }
477
478         public DocumentType getType() {
479                 return type;
480         }
481
482         /**
483          * Returns the version number of this document. The version number, when exists, is either of the internal form (m.n.s) usable for
484          * building a Revision object, or any string in case of external document (document with EXTERN state).<br/> <br/> Note: document slots
485          * have a version number equal to "0.0.0".
486          * 
487          * @return the version number of this document, or null if this is EXTERN.
488          * @see #isUndefined()
489          */
490         public String getVersion() {
491                 return version;
492         }
493
494         /**
495          * Returns true if this document is undefined. An undefined document is a meta-document created for reserving the persistent reference
496          * of a new document before saving (or importing) this later into the repository. The working copy of a such document may include this
497          * reference.
498          * 
499          * @see #getTitle()
500          * @see #getVersion()
501          * @see #initialize(Properties)
502          */
503         public boolean isUndefined() {
504                 return (history == -1);
505         }
506
507         public boolean isInto(final Step container) {
508                 return (step == container.getNumber());
509         }
510
511         public boolean isPublished() {
512                 return (countag > 0);
513         }
514
515         public boolean isShared() {
516                 return (countag + history > 1);
517         }
518
519         public boolean isVersioned() {
520                 return (history > 0);
521         }
522
523         /**
524          * Get the step.
525          * 
526          * @return the step
527          */
528         public int getStep() {
529                 return step;
530         }
531
532         /**
533          * Set the step.
534          * 
535          * @param step
536          *            the step to set
537          */
538         public void setStep(final int step) {
539                 this.step = step;
540         }
541
542         /**
543          * Get the did.
544          * 
545          * @return the did
546          */
547         public String getDid() {
548                 return did;
549         }
550
551         /**
552          * Set the did.
553          * 
554          * @param did
555          *            the did to set
556          */
557         public void setDid(final String did) {
558                 this.did = did;
559         }
560
561         /**
562          * Get the myfile.
563          * 
564          * @return the myfile
565          */
566         public File getFile() {
567                 return myfile;
568         }
569
570         /**
571          * Set the myfile.
572          * 
573          * @param myfile
574          *            the myfile to set
575          */
576         public void setFile(final File myfile) {
577                 this.myfile = myfile;
578         }
579
580         /**
581          * Get the history.
582          * 
583          * @return the history
584          */
585         public int getHistory() {
586                 return history;
587         }
588
589         /**
590          * Set the history.
591          * 
592          * @param history
593          *            the history to set
594          */
595         public void setHistory(final int history) {
596                 this.history = history;
597         }
598
599         /**
600          * Set the version.
601          * 
602          * @param version
603          *            the version to set
604          */
605         public void setVersion(final String version) {
606                 this.version = version;
607         }
608
609         /**
610          * Set the state.
611          * 
612          * @param state
613          *            the state to set
614          */
615         public void setProgressState(final ProgressState state) {
616                 this.state = state;
617         }
618
619         /**
620          * Get the countag.
621          * 
622          * @return the countag
623          */
624         public int getCountag() {
625                 return countag;
626         }
627
628         /**
629          * Set the countag.
630          * 
631          * @param countag
632          *            the countag to set
633          */
634         public void setCountag(final int countag) {
635                 this.countag = countag;
636         }
637 }