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.Persistent;
16 import org.splat.dal.bo.kernel.Relation;
17 import org.splat.dal.bo.kernel.User;
18 import org.splat.dal.bo.som.Timestamp.ComparatorByDate;
19 import org.splat.kernel.InvalidPropertyException;
20 import org.splat.kernel.MissedPropertyException;
21 import org.splat.kernel.MultiplyDefinedException;
22 import org.splat.service.technical.ProjectSettingsService;
23 import org.splat.service.technical.ProjectSettingsServiceImpl;
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
88 public Properties copy() {
89 Properties copy = new Properties();
90 copy.type = this.type;
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;
105 // - Protected services
107 public User getAuthor() {
111 public String getDescription() {
115 public String getLocalPath() {
119 public String getReference() {
123 public ProjectSettingsService.Step getStep() {
127 public DocumentType getType() {
131 // - Property setters
133 public Properties setAuthor(User user) {
138 public Properties setDate(Date date) {
147 public Date getDate() {
151 public Properties setDescription(String summary)
152 throws InvalidPropertyException {
153 if (summary.length() == 0)
154 throw new InvalidPropertyException("description");
155 this.summary = summary;
159 public Properties setDocument(Document base) {
161 step = ProjectSettingsServiceImpl.getStep(base.step);
163 format = base.getFormat();
164 state = ProgressState.inWORK; // For incrementing the version number at save time
165 version = base.version;
169 public Properties setExternReference(String ref)
170 throws InvalidPropertyException {
171 if (ref.length() == 0)
172 throw new InvalidPropertyException("reference");
173 if (ref.equals(new Revision().toString()))
174 throw new InvalidPropertyException("reference"); // Internal version number
179 public Properties setFormat(String format)
180 throws InvalidPropertyException {
181 if (format.length() == 0)
182 throw new InvalidPropertyException("format");
183 this.format = format;
187 // Required only for passing search arguments
188 public Properties setLocalPath(String path)
189 throws InvalidPropertyException {
190 if (path.length() == 0)
191 throw new InvalidPropertyException("path");
196 public Properties setName(String name) throws InvalidPropertyException {
197 if (name.length() == 0)
198 throw new InvalidPropertyException("name");
203 public String getName() {
207 public Properties setOwner(ProjectElement owner) {
212 public ProjectElement getOwner() {
215 // Required only for passing search arguments
216 public Properties setReference(String did)
217 throws InvalidPropertyException {
218 if (did.length() == 0)
219 throw new InvalidPropertyException("reference");
224 public Properties setState(ProgressState state)
225 throws InvalidPropertyException {
226 if (state == ProgressState.inPROGRESS
227 || state == ProgressState.TEMPLATE)
228 throw new InvalidPropertyException("state"); // Non document states
233 public Properties setStep(ProjectSettingsService.Step step) {
238 public Properties setType(DocumentType type) {
243 // - Global validity check
245 public void checkValidity() throws MissedPropertyException,
246 InvalidPropertyException, MultiplyDefinedException {
248 throw new MissedPropertyException("type");
250 throw new MissedPropertyException("owner");
252 throw new MissedPropertyException("step");
254 throw new MissedPropertyException("author");
256 throw new MissedPropertyException("format");
257 if (owner instanceof Study && !step.appliesTo(Study.class))
258 throw new InvalidPropertyException("step");
259 if (!type.isContentInto(step))
260 throw new InvalidPropertyException("step");
261 if (state != null && state != ProgressState.EXTERN) {
262 // inDRAFT, inCHECK or APPROVED + version = imposed version (future use)
263 // inWORK + version = base version incremented at save time (used for versioning)
265 throw new InvalidPropertyException("state");
267 if (version != null) {
269 state = ProgressState.EXTERN;
274 // Database fetch constructor
275 protected Document() {
278 // Internal constructor
279 public Document(Properties dprop) throws MissedPropertyException,
280 InvalidPropertyException, MultiplyDefinedException {
281 // -------------------------------------
282 super(dprop); // Throws one of the above exception if not valid
283 myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
285 step = dprop.step.getNumber();
287 version = dprop.version;
288 author = dprop.author;
291 lasdate = myfile.getDate(); // Today if not defined in the properties
295 state = ProgressState.inWORK; // Promoted when saving this document
296 version = new Revision().toString();
298 if (name == null) { // Newed document
299 this.name = "%n"; // Named later at publication
300 this.history = -1; // Marks the document as undefined for future assignment
304 // ==============================================================================================================================
305 // Public member functions
306 // ==============================================================================================================================
308 public File getAttachedFile(String format) {
309 // -------------------------------------------
310 List<Relation> exports = getRelations(ConvertsRelation.class);
312 for (Iterator<Relation> i = exports.iterator(); i.hasNext();) {
313 File export = (File) i.next().getTo();
314 if (export.getFormat().equals(format))
320 public User getAuthor() {
321 // ------------------------
325 public Date getCreationDate() {
326 // ------------------------------
327 return myfile.getDate();
330 public Date getLastModificationDate() {
331 // --------------------------------------
335 public void setLastModificationDate(Date aDate) {
339 public String getFormat() {
340 // --------------------------
341 return myfile.getFormat();
344 public Document getPreviousVersion() {
345 // -------------------------------------
346 Relation previous = getFirstRelation(VersionsRelation.class);
347 if (previous != null)
348 return (Document) previous.getTo();
353 public ProgressState getProgressState() {
354 // ----------------------------------------
359 * Returns the path where all physical files attached to this document are saved. This path is relative to the vault of the repository
360 * and include the file name, without extension, common to all physical files attached to this document.
362 * @return the path of the document
364 public String getRelativePath() {
365 // --------------------------------
366 String[] table = myfile.getRelativePath().split("\\x2E");
367 StringBuffer path = new StringBuffer(table[0]);
368 for (int i = 1; i < table.length - 1; i++)
369 path.append('.').append(table[i]);
370 return path.toString();
374 * Returns the global unique reference of this document lineage. The document reference is common to all versions of the document
375 * (versioning a document does not change its reference). It is made of the owner study reference suffixed by a document identifier
376 * unique in the scope of the study.
378 * @return the document reference
380 public String getReference() {
381 // -----------------------------
385 public File getSourceFile() {
386 // ----------------------------
391 * Returns the stamps such as review and approval attached to this document, if exist. If several stamps exist, they are returned in
392 * ascending order of dates.
394 * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
396 public Timestamp[] getStamps() {
397 // -------------------------------
398 Vector<Timestamp> stamps = new Vector<Timestamp>();
400 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
402 Relation link = i.next();
403 if (link instanceof StampRelation)
404 stamps.add(((StampRelation) link).getTo());
406 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
407 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
409 Arrays.sort(result, bydate);
414 * Returns the title of this document.
416 * @return the document title, or an empty string is this document is undefined.
417 * @see #isUndefined()
419 public String getTitle() {
420 // -------------------------
421 if (this.isUndefined())
428 * Set document title.
429 * @param aTitle document title to set
431 public void setTitle(String aTitle) {
435 public DocumentType getType() {
436 // ------------------------------
441 * Returns the version number of this document. The version number, when exists, is either of the internal form (m.n.s) usable for
442 * building a Revision object, or any string in case of external document (document with EXTERN state).<br/> <br/> Note: document slots
443 * have a version number equal to "0.0.0".
445 * @return the version number of this document, or null if this is EXTERN.
446 * @see #isUndefined()
448 public String getVersion() {
449 // ---------------------------
454 * Returns true if this document is undefined. An undefined document is a meta-document created for reserving the persistent reference
455 * of a new document before saving (or importing) this later into the repository. The working copy of a such document may include this
460 * @see #initialize(Properties)
462 public boolean isUndefined() {
463 // -----------------------------
464 return (history == -1);
467 public boolean isInto(Step container) {
468 // --------------------------------------
469 return (step == container.getNumber());
472 public boolean isPublished() {
473 // -----------------------------
474 return (countag > 0);
477 public boolean isShared() {
478 // --------------------------
479 return (countag + history > 1);
482 public boolean isVersioned() {
483 // -----------------------------
484 return (history > 0);
491 public int getStep() {
497 * @param step the step to set
499 public void setStep(int step) {
507 public String getDid() {
513 * @param did the did to set
515 public void setDid(String did) {
523 public File getFile() {
529 * @param myfile the myfile to set
531 public void setFile(File myfile) {
532 this.myfile = myfile;
537 * @return the history
539 public int getHistory() {
545 * @param history the history to set
547 public void setHistory(int history) {
548 this.history = history;
553 * @param version the version to set
555 public void setVersion(String version) {
556 this.version = version;
561 * @param state the state to set
563 public void setProgressState(ProgressState state) {
569 * @return the countag
571 public int getCountag() {
577 * @param countag the countag to set
579 public void setCountag(int countag) {
580 this.countag = countag;