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