1 package org.splat.dal.bo.som;
5 * @author Daniel Brunier-Coulin
6 * @copyright OPEN CASCADE 2012-2015
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 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
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(final User user) {
138 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;
162 * Copy base properties from the given original document for versioning.
165 * the original document
168 * @return document properties
170 public Properties setDocument(final Document base,
171 final ProjectSettingsService.Step aStep) {
175 format = base.getFormat();
176 state = ProgressState.inWORK; // For incrementing the version number at save time
177 version = base.version;
181 public Properties setExternReference(final String ref)
182 throws InvalidPropertyException {
183 if (ref.length() == 0) {
184 throw new InvalidPropertyException("reference");
186 if (ref.equals(new Revision().toString())) {
187 throw new InvalidPropertyException("reference"); // Internal version number
193 public Properties setFormat(final String format)
194 throws InvalidPropertyException {
195 if (format.length() == 0) {
196 throw new InvalidPropertyException("format");
198 this.format = format;
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");
212 public Properties setName(final String name)
213 throws InvalidPropertyException {
214 if (name.length() == 0) {
215 throw new InvalidPropertyException("name");
221 public String getName() {
225 public Properties setOwner(final ProjectElement owner) {
230 public ProjectElement getOwner() {
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");
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
254 public Properties setStep(final ProjectSettingsService.Step step) {
259 public Properties setType(final DocumentType type) {
264 // - Global validity check
266 public void checkValidity() throws MissedPropertyException,
267 InvalidPropertyException, MultiplyDefinedException {
269 throw new MissedPropertyException("type");
272 throw new MissedPropertyException("owner");
275 throw new MissedPropertyException("step");
277 if (author == null) {
278 throw new MissedPropertyException("author");
280 if (format == null) {
281 throw new MissedPropertyException("format");
283 if (owner instanceof Study && !step.appliesTo(Study.class)) {
284 throw new InvalidPropertyException("step");
286 if (!type.isContentInto(step)) {
287 throw new InvalidPropertyException("step");
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");
296 if (version != null) {
298 state = ProgressState.EXTERN;
308 public String getFormat() {
314 * Database fetch constructor.
316 protected Document() {
321 * Initialization constructor.
324 * @throws MissedPropertyException
325 * @throws InvalidPropertyException
326 * @throws MultiplyDefinedException
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
333 step = dprop.step.getNumber();
335 version = dprop.version;
336 author = dprop.author;
339 lasdate = myfile.getDate(); // Today if not defined in the properties
343 state = ProgressState.inWORK; // Promoted when saving this document
344 version = new Revision().toString();
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
352 // ==============================================================================================================================
353 // Public member functions
354 // ==============================================================================================================================
357 * Get the attached file of the given format.
361 * @return the attached file or null if not found
363 public File getAttachedFile(final String format) {
364 List<Relation> exports = getRelations(ConvertsRelation.class);
366 for (Relation rel : exports) {
367 File export = (File) rel.getTo();
368 if (export.getFormat().equals(format)) {
376 public User getAuthor() {
380 public Date getCreationDate() {
381 return myfile.getDate();
384 public Date getLastModificationDate() {
388 public void setLastModificationDate(final Date aDate) {
392 public String getFormat() {
393 return myfile.getFormat();
396 public Document getPreviousVersion() {
397 Relation previous = getFirstRelation(VersionsRelation.class);
398 if (previous == null) {
401 return (Document) previous.getTo();
405 public ProgressState getProgressState() {
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.
413 * @return the path of the document
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]);
421 return path.toString();
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.
429 * @return the document reference
431 public String getReference() {
435 public File getSourceFile() {
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.
443 * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
445 public Timestamp[] getStamps() {
446 Vector<Timestamp> stamps = new Vector<Timestamp>();
448 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
450 Relation link = i.next();
451 if (link instanceof StampRelation) {
452 stamps.add(((StampRelation) link).getTo());
455 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
456 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
458 Arrays.sort(result, bydate);
463 * Returns the title of this document.
465 * @return the document title, or an empty string is this document is undefined.
466 * @see #isUndefined()
468 public String getTitle() {
469 // -------------------------
470 if (this.isUndefined()) {
478 * Set document title.
481 * document title to set
483 public void setTitle(final String aTitle) {
487 public DocumentType getType() {
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".
496 * @return the version number of this document, or null if this is EXTERN.
497 * @see #isUndefined()
499 public String getVersion() {
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
510 * @see #initialize(Properties)
512 public boolean isUndefined() {
513 return (history == -1);
516 public boolean isInto(final Step container) {
517 return (step == container.getNumber());
520 public boolean isPublished() {
521 return (countag > 0);
524 public boolean isShared() {
525 return (countag + history > 1);
528 public boolean isVersioned() {
529 return (history > 0);
537 public int getStep() {
547 public void setStep(final int step) {
556 public String getDid() {
566 public void setDid(final String did) {
575 public File getFile() {
585 public void setFile(final File myfile) {
586 this.myfile = myfile;
592 * @return the history
594 public int getHistory() {
604 public void setHistory(final int history) {
605 this.history = history;
614 public void setVersion(final String version) {
615 this.version = version;
624 public void setProgressState(final ProgressState state) {
631 * @return the countag
633 public int getCountag() {
643 public void setCountag(final int countag) {
644 this.countag = countag;