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;
308 public String getFormat() {
314 * Database fetch constructor.
316 protected Document() {
321 * Initialization constructor.
323 * @throws MissedPropertyException
324 * @throws InvalidPropertyException
325 * @throws MultiplyDefinedException
327 public Document(final Properties dprop) throws MissedPropertyException,
328 InvalidPropertyException, MultiplyDefinedException {
329 super(dprop); // Throws one of the above exception if not valid
330 myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
332 step = dprop.step.getNumber();
334 version = dprop.version;
335 author = dprop.author;
338 lasdate = myfile.getDate(); // Today if not defined in the properties
342 state = ProgressState.inWORK; // Promoted when saving this document
343 version = new Revision().toString();
345 if (name == null) { // Newed document
346 this.name = "%n"; // Named later at publication
347 this.history = -1; // Marks the document as undefined for future assignment
351 // ==============================================================================================================================
352 // Public member functions
353 // ==============================================================================================================================
355 public File getAttachedFile(final String format) {
356 List<Relation> exports = getRelations(ConvertsRelation.class);
358 for (Iterator<Relation> i = exports.iterator(); i.hasNext();) {
359 File export = (File) i.next().getTo();
360 if (export.getFormat().equals(format)) {
367 public User getAuthor() {
371 public Date getCreationDate() {
372 return myfile.getDate();
375 public Date getLastModificationDate() {
379 public void setLastModificationDate(final Date aDate) {
383 public String getFormat() {
384 return myfile.getFormat();
387 public Document getPreviousVersion() {
388 Relation previous = getFirstRelation(VersionsRelation.class);
389 if (previous == null) {
392 return (Document) previous.getTo();
396 public ProgressState getProgressState() {
401 * Returns the path where all physical files attached to this document are saved. This path is relative to the vault of the repository
402 * and include the file name, without extension, common to all physical files attached to this document.
404 * @return the path of the document
406 public String getRelativePath() {
407 String[] table = myfile.getRelativePath().split("\\x2E");
408 StringBuffer path = new StringBuffer(table[0]);
409 for (int i = 1; i < table.length - 1; i++) {
410 path.append('.').append(table[i]);
412 return path.toString();
416 * Returns the global unique reference of this document lineage. The document reference is common to all versions of the document
417 * (versioning a document does not change its reference). It is made of the owner study reference suffixed by a document identifier
418 * unique in the scope of the study.
420 * @return the document reference
422 public String getReference() {
426 public File getSourceFile() {
431 * Returns the stamps such as review and approval attached to this document, if exist. If several stamps exist, they are returned in
432 * ascending order of dates.
434 * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
436 public Timestamp[] getStamps() {
437 Vector<Timestamp> stamps = new Vector<Timestamp>();
439 for (Iterator<Relation> i = this.getAllRelations().iterator(); i
441 Relation link = i.next();
442 if (link instanceof StampRelation) {
443 stamps.add(((StampRelation) link).getTo());
446 Timestamp[] result = stamps.toArray(new Timestamp[stamps.size()]);
447 ComparatorByDate bydate = new Timestamp.ComparatorByDate();
449 Arrays.sort(result, bydate);
454 * Returns the title of this document.
456 * @return the document title, or an empty string is this document is undefined.
457 * @see #isUndefined()
459 public String getTitle() {
460 // -------------------------
461 if (this.isUndefined()) {
469 * Set document title.
472 * document title to set
474 public void setTitle(final String aTitle) {
478 public DocumentType getType() {
483 * Returns the version number of this document. The version number, when exists, is either of the internal form (m.n.s) usable for
484 * building a Revision object, or any string in case of external document (document with EXTERN state).<br/> <br/> Note: document slots
485 * have a version number equal to "0.0.0".
487 * @return the version number of this document, or null if this is EXTERN.
488 * @see #isUndefined()
490 public String getVersion() {
495 * Returns true if this document is undefined. An undefined document is a meta-document created for reserving the persistent reference
496 * of a new document before saving (or importing) this later into the repository. The working copy of a such document may include this
501 * @see #initialize(Properties)
503 public boolean isUndefined() {
504 return (history == -1);
507 public boolean isInto(final Step container) {
508 return (step == container.getNumber());
511 public boolean isPublished() {
512 return (countag > 0);
515 public boolean isShared() {
516 return (countag + history > 1);
519 public boolean isVersioned() {
520 return (history > 0);
528 public int getStep() {
538 public void setStep(final int step) {
547 public String getDid() {
557 public void setDid(final String did) {
566 public File getFile() {
576 public void setFile(final File myfile) {
577 this.myfile = myfile;
583 * @return the history
585 public int getHistory() {
595 public void setHistory(final int history) {
596 this.history = history;
605 public void setVersion(final String version) {
606 this.version = version;
615 public void setProgressState(final ProgressState state) {
622 * @return the countag
624 public int getCountag() {
634 public void setCountag(final int countag) {
635 this.countag = countag;