1 package org.splat.dal.bo.som;
5 * @author Daniel Brunier-Coulin
6 * @copyright OPEN CASCADE 2012
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;
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;
28 * Document persistent class.
30 public class Document extends Entity {
33 private DocumentType type; // User expendable types
37 private ProgressState state;
39 private String version;
46 public static String suformat = "00"; // Format of the suffix number of document did and file name
48 // ==============================================================================================================================
50 // ==============================================================================================================================
53 * Fields initialization class.
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
89 public Properties copy() {
90 Properties copy = new Properties();
91 copy.type = this.type;
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;
106 // - Protected services
108 public User getAuthor() {
112 public String getDescription() {
116 public String getLocalPath() {
120 public String getReference() {
124 public ProjectSettingsService.Step getStep() {
128 public DocumentType getType() {
132 // - Property setters
134 public Properties setAuthor(final User user) {
139 public Properties setDate(final Date date) {
149 public Date getDate() {
153 public Properties setDescription(final String summary)
154 throws InvalidPropertyException {
155 if (summary.length() == 0) {
156 throw new InvalidPropertyException("description");
158 this.summary = summary;
163 * Copy base properties from the given original document for versioning.
166 * the original document
169 * @return document properties
171 public Properties setDocument(final Document base,
172 final ProjectSettingsService.Step aStep) {
176 format = base.getFormat();
177 state = ProgressState.inWORK; // For incrementing the version number at save time
178 version = base.version;
182 public Properties setExternReference(final String ref)
183 throws InvalidPropertyException {
184 if (ref.length() == 0) {
185 throw new InvalidPropertyException("reference");
187 if (ref.equals(new Revision().toString())) {
188 throw new InvalidPropertyException("reference"); // Internal version number
194 public Properties setFormat(final String format)
195 throws InvalidPropertyException {
196 if (format.length() == 0) {
197 throw new InvalidPropertyException("format");
199 this.format = format;
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");
213 public Properties setName(final String name)
214 throws InvalidPropertyException {
215 if (name.length() == 0) {
216 throw new InvalidPropertyException("name");
222 public String getName() {
226 public Properties setOwner(final ProjectElement owner) {
231 public ProjectElement getOwner() {
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");
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
255 public Properties setStep(final ProjectSettingsService.Step step) {
260 public Properties setType(final DocumentType type) {
265 // - Global validity check
267 public void checkValidity() throws MissedPropertyException,
268 InvalidPropertyException, MultiplyDefinedException {
270 throw new MissedPropertyException("type");
273 throw new MissedPropertyException("owner");
276 throw new MissedPropertyException("step");
278 if (author == null) {
279 throw new MissedPropertyException("author");
281 if (format == null) {
282 throw new MissedPropertyException("format");
284 if (owner instanceof Study && !step.appliesTo(Study.class)) {
285 throw new InvalidPropertyException("step");
287 if (!type.isContentInto(step)) {
288 throw new InvalidPropertyException("step");
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");
297 if (version != null) {
299 state = ProgressState.EXTERN;
309 public String getFormat() {
315 * Database fetch constructor.
317 protected Document() {
322 * Initialization constructor.
325 * @throws MissedPropertyException
326 * @throws InvalidPropertyException
327 * @throws MultiplyDefinedException
329 public Document(final Properties dprop) throws MissedPropertyException,
330 InvalidPropertyException, MultiplyDefinedException {
331 super(dprop); // Throws one of the above exception if not valid
332 myfile = new File(dprop.getLocalPath(), dprop.format, dprop.date); // The path is initialized below
334 step = dprop.step.getNumber();
336 version = dprop.version;
337 author = dprop.author;
340 lasdate = myfile.getDate(); // Today if not defined in the properties
344 state = ProgressState.inWORK; // Promoted when saving this document
345 version = new Revision().toString();
347 if (name == null) { // Newed document
348 this.name = "%n"; // Named later at publication
349 this.history = -1; // Marks the document as undefined for future assignment
353 // ==============================================================================================================================
354 // Public member functions
355 // ==============================================================================================================================
358 * Get the attached file of the given format.
362 * @return the attached file or null if not found
364 public File getAttachedFile(final String format) {
365 List<Relation> exports = getRelations(ConvertsRelation.class);
367 for (Relation rel : exports) {
368 File export = (File) rel.getTo();
369 if (export.getFormat().equals(format)) {
377 public User getAuthor() {
381 public Date getCreationDate() {
382 return myfile.getDate();
385 public Date getLastModificationDate() {
389 public void setLastModificationDate(final Date aDate) {
393 public String getFormat() {
394 return myfile.getFormat();
397 public Document getPreviousVersion() {
398 Relation previous = getFirstRelation(VersionsRelation.class);
399 if (previous == null) {
402 return (Document) previous.getTo();
406 public ProgressState getProgressState() {
411 * Returns the path where all physical files attached to this document are saved. This path is relative to the vault of the repository
412 * and include the file name, without extension, common to all physical files attached to this document.
414 * @return the path of the document
416 public String getRelativePath() {
417 String[] table = myfile.getRelativePath().split("\\x2E");
418 StringBuffer path = new StringBuffer(table[0]);
419 for (int i = 1; i < table.length - 1; i++) {
420 path.append('.').append(table[i]);
422 return path.toString();
426 * Returns the global unique reference of this document lineage. The document reference is common to all versions of the document
427 * (versioning a document does not change its reference). It is made of the owner study reference suffixed by a document identifier
428 * unique in the scope of the study.
430 * @return the document reference
432 public String getReference() {
436 public File getSourceFile() {
441 * Returns the stamps such as review and approval attached to this document, if exist. If several stamps exist, they are returned in
442 * ascending order of dates.
444 * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
446 public Timestamp[] getStamps() {
447 Vector<Timestamp> stamps = new Vector<Timestamp>();
449 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
451 Relation link = i.next();
452 if (link instanceof StampRelation) {
453 stamps.add(((StampRelation) link).getTo());
456 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
457 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
459 Arrays.sort(result, bydate);
464 * Returns the title of this document.
466 * @return the document title, or an empty string is this document is undefined.
467 * @see #isUndefined()
469 public String getTitle() {
470 // -------------------------
471 if (this.isUndefined()) {
479 * Set document title.
482 * document title to set
484 public void setTitle(final String aTitle) {
488 public DocumentType getType() {
493 * Returns the version number of this document. The version number, when exists, is either of the internal form (m.n.s) usable for
494 * building a Revision object, or any string in case of external document (document with EXTERN state).<br/> <br/> Note: document slots
495 * have a version number equal to "0.0.0".
497 * @return the version number of this document, or null if this is EXTERN.
498 * @see #isUndefined()
500 public String getVersion() {
505 * Returns true if this document is undefined. An undefined document is a meta-document created for reserving the persistent reference
506 * of a new document before saving (or importing) this later into the repository. The working copy of a such document may include this
511 * @see #initialize(Properties)
513 public boolean isUndefined() {
514 return (history == -1);
517 public boolean isInto(final Step container) {
518 return (step == container.getNumber());
521 public boolean isPublished() {
522 return (countag > 0);
525 public boolean isShared() {
526 return (countag + history > 1);
529 public boolean isVersioned() {
530 return (history > 0);
538 public int getStep() {
548 public void setStep(final int step) {
557 public String getDid() {
567 public void setDid(final String did) {
576 public File getFile() {
586 public void setFile(final File myfile) {
587 this.myfile = myfile;
593 * @return the history
595 public int getHistory() {
605 public void setHistory(final int history) {
606 this.history = history;
615 public void setVersion(final String version) {
616 this.version = version;
625 public void setProgressState(final ProgressState state) {
632 * @return the countag
634 public int getCountag() {
644 public void setCountag(final int countag) {
645 this.countag = countag;