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) {
148 public Date getDate() {
152 public Properties setDescription(final String summary)
153 throws InvalidPropertyException {
154 if (summary.length() == 0) {
155 throw new InvalidPropertyException("description");
157 this.summary = summary;
161 public Properties setDocument(final Document base, final ProjectSettingsService.Step aStep) {
165 format = base.getFormat();
166 state = ProgressState.inWORK; // For incrementing the version number at save time
167 version = base.version;
171 public Properties setExternReference(final String ref)
172 throws InvalidPropertyException {
173 if (ref.length() == 0) {
174 throw new InvalidPropertyException("reference");
176 if (ref.equals(new Revision().toString())) {
177 throw new InvalidPropertyException("reference"); // Internal version number
183 public Properties setFormat(final String format)
184 throws InvalidPropertyException {
185 if (format.length() == 0) {
186 throw new InvalidPropertyException("format");
188 this.format = format;
192 // Required only for passing search arguments
193 public Properties setLocalPath(final String path)
194 throws InvalidPropertyException {
195 if (path.length() == 0) {
196 throw new InvalidPropertyException("path");
202 public Properties setName(final String name) throws InvalidPropertyException {
203 if (name.length() == 0) {
204 throw new InvalidPropertyException("name");
210 public String getName() {
214 public Properties setOwner(final ProjectElement owner) {
219 public ProjectElement getOwner() {
222 // Required only for passing search arguments
223 public Properties setReference(final String did)
224 throws InvalidPropertyException {
225 if (did.length() == 0) {
226 throw new InvalidPropertyException("reference");
232 public Properties setState(final ProgressState state)
233 throws InvalidPropertyException {
234 if (state == ProgressState.inPROGRESS
235 || state == ProgressState.TEMPLATE) {
236 throw new InvalidPropertyException("state"); // Non document states
242 public Properties setStep(final ProjectSettingsService.Step step) {
247 public Properties setType(final DocumentType type) {
252 // - Global validity check
254 public void checkValidity() throws MissedPropertyException,
255 InvalidPropertyException, MultiplyDefinedException {
257 throw new MissedPropertyException("type");
260 throw new MissedPropertyException("owner");
263 throw new MissedPropertyException("step");
265 if (author == null) {
266 throw new MissedPropertyException("author");
268 if (format == null) {
269 throw new MissedPropertyException("format");
271 if (owner instanceof Study && !step.appliesTo(Study.class)) {
272 throw new InvalidPropertyException("step");
274 if (!type.isContentInto(step)) {
275 throw new InvalidPropertyException("step");
277 if (state != null && state != ProgressState.EXTERN) {
278 // inDRAFT, inCHECK or APPROVED + version = imposed version (future use)
279 // inWORK + version = base version incremented at save time (used for versioning)
280 if (version == null) {
281 throw new InvalidPropertyException("state");
284 if (version != null) {
286 state = ProgressState.EXTERN;
292 protected Document() {
293 // Database fetch constructor
296 // Internal constructor
297 public Document(final Properties dprop) throws MissedPropertyException,
298 InvalidPropertyException, MultiplyDefinedException {
299 // -------------------------------------
300 super(dprop); // Throws one of the above exception if not valid
301 myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
303 step = dprop.step.getNumber();
305 version = dprop.version;
306 author = dprop.author;
309 lasdate = myfile.getDate(); // Today if not defined in the properties
313 state = ProgressState.inWORK; // Promoted when saving this document
314 version = new Revision().toString();
316 if (name == null) { // Newed document
317 this.name = "%n"; // Named later at publication
318 this.history = -1; // Marks the document as undefined for future assignment
322 // ==============================================================================================================================
323 // Public member functions
324 // ==============================================================================================================================
326 public File getAttachedFile(final String format) {
327 // -------------------------------------------
328 List<Relation> exports = getRelations(ConvertsRelation.class);
330 for (Iterator<Relation> i = exports.iterator(); i.hasNext();) {
331 File export = (File) i.next().getTo();
332 if (export.getFormat().equals(format)) {
339 public User getAuthor() {
340 // ------------------------
344 public Date getCreationDate() {
345 // ------------------------------
346 return myfile.getDate();
349 public Date getLastModificationDate() {
350 // --------------------------------------
354 public void setLastModificationDate(final Date aDate) {
358 public String getFormat() {
359 // --------------------------
360 return myfile.getFormat();
363 public Document getPreviousVersion() {
364 // -------------------------------------
365 Relation previous = getFirstRelation(VersionsRelation.class);
366 if (previous == null) {
369 return (Document) previous.getTo();
373 public ProgressState getProgressState() {
374 // ----------------------------------------
379 * Returns the path where all physical files attached to this document are saved. This path is relative to the vault of the repository
380 * and include the file name, without extension, common to all physical files attached to this document.
382 * @return the path of the document
384 public String getRelativePath() {
385 // --------------------------------
386 String[] table = myfile.getRelativePath().split("\\x2E");
387 StringBuffer path = new StringBuffer(table[0]);
388 for (int i = 1; i < table.length - 1; i++) {
389 path.append('.').append(table[i]);
391 return path.toString();
395 * Returns the global unique reference of this document lineage. The document reference is common to all versions of the document
396 * (versioning a document does not change its reference). It is made of the owner study reference suffixed by a document identifier
397 * unique in the scope of the study.
399 * @return the document reference
401 public String getReference() {
402 // -----------------------------
406 public File getSourceFile() {
407 // ----------------------------
412 * Returns the stamps such as review and approval attached to this document, if exist. If several stamps exist, they are returned in
413 * ascending order of dates.
415 * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
417 public Timestamp[] getStamps() {
418 // -------------------------------
419 Vector<Timestamp> stamps = new Vector<Timestamp>();
421 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
423 Relation link = i.next();
424 if (link instanceof StampRelation) {
425 stamps.add(((StampRelation) link).getTo());
428 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
429 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
431 Arrays.sort(result, bydate);
436 * Returns the title of this document.
438 * @return the document title, or an empty string is this document is undefined.
439 * @see #isUndefined()
441 public String getTitle() {
442 // -------------------------
443 if (this.isUndefined()) {
451 * Set document title.
452 * @param aTitle document title to set
454 public void setTitle(final String aTitle) {
458 public DocumentType getType() {
459 // ------------------------------
464 * Returns the version number of this document. The version number, when exists, is either of the internal form (m.n.s) usable for
465 * building a Revision object, or any string in case of external document (document with EXTERN state).<br/> <br/> Note: document slots
466 * have a version number equal to "0.0.0".
468 * @return the version number of this document, or null if this is EXTERN.
469 * @see #isUndefined()
471 public String getVersion() {
472 // ---------------------------
477 * Returns true if this document is undefined. An undefined document is a meta-document created for reserving the persistent reference
478 * of a new document before saving (or importing) this later into the repository. The working copy of a such document may include this
483 * @see #initialize(Properties)
485 public boolean isUndefined() {
486 // -----------------------------
487 return (history == -1);
490 public boolean isInto(final Step container) {
491 // --------------------------------------
492 return (step == container.getNumber());
495 public boolean isPublished() {
496 // -----------------------------
497 return (countag > 0);
500 public boolean isShared() {
501 // --------------------------
502 return (countag + history > 1);
505 public boolean isVersioned() {
506 // -----------------------------
507 return (history > 0);
514 public int getStep() {
520 * @param step the step to set
522 public void setStep(final int step) {
530 public String getDid() {
536 * @param did the did to set
538 public void setDid(final String did) {
546 public File getFile() {
552 * @param myfile the myfile to set
554 public void setFile(final File myfile) {
555 this.myfile = myfile;
560 * @return the history
562 public int getHistory() {
568 * @param history the history to set
570 public void setHistory(final int history) {
571 this.history = history;
576 * @param version the version to set
578 public void setVersion(final String version) {
579 this.version = version;
584 * @param state the state to set
586 public void setProgressState(final ProgressState state) {
592 * @return the countag
594 public int getCountag() {
600 * @param countag the countag to set
602 public void setCountag(final int countag) {
603 this.countag = countag;