4 * @author Daniel Brunier-Coulin
5 * @copyright OPEN CASCADE 2012
9 import java.io.IOException;
10 import java.util.Collections;
11 import java.util.List;
13 import java.util.Vector;
14 import java.util.Iterator;
16 import org.hibernate.Session;
17 import org.splat.kernel.InvalidPropertyException;
18 import org.splat.kernel.MismatchException;
19 import org.splat.kernel.MissedPropertyException;
20 import org.splat.kernel.MultiplyDefinedException;
21 import org.splat.kernel.NotApplicableException;
22 import org.splat.kernel.Relation;
23 import org.splat.kernel.User;
24 import org.splat.som.Database;
29 private ProjectSettings.Step step;
30 private ProjectElement owner;
31 private List<SimulationContext> contex;
32 private List<Publication> docums;
33 private User actor; // Actor involved in operations on published documents and requiring a time-stamp
35 // ==============================================================================================================================
37 // ==============================================================================================================================
39 protected Step (ProjectSettings.Step step, ProjectElement owner) {
40 // ----------------------------------------------------------------
43 this.contex = new Vector<SimulationContext>();
44 this.docums = new Vector<Publication>();
47 // Filtering of Simulation contexts, if exist
48 for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
49 SimulationContext adoc = i.next();
50 if (!adoc.isInto(this)) continue;
51 this.contex.add(adoc);
53 // Filtering of Documents, if exist
54 for (Iterator<Publication> i=owner.PublicationIterator(); i.hasNext();) {
55 Publication mydoc = i.next();
56 if (!mydoc.value().isInto(this)) continue;
57 this.docums.add(mydoc);
61 // ==============================================================================================================================
62 // Public member functions
63 // ==============================================================================================================================
65 public Publication createDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException {
66 // -------------------------------------------------------------
67 Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
69 // Creation of the save directory
70 File wdir = newdoc.getSaveDirectory();
71 if (!wdir.exists()) if (!wdir.mkdirs()) throw new IOException("Cannot create the repository vault directory");
73 // Identification and save
74 newdoc.buildReferenceFrom(getOwnerStudy());
75 Database.getSession().save(newdoc);
77 return new Publication(newdoc, owner);
80 public Publication assignDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
81 // -------------------------------------------------------------
82 String refid = dprop.getReference();
83 if (refid == null) return null;
85 Document slot = Database.selectDocument(refid, new Revision().toString());
86 if ( slot == null ) return null;
87 if (!slot.isUndefined()) return null; // Should not happen
89 slot.initialize(dprop.setOwner(getOwnerStudy()));
90 return new Publication(slot, owner);
93 public Publication versionDocument (Publication base) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
94 // -----------------------------------------------------
95 return versionDocument(base, new Document.Properties());
98 public Publication versionDocument (Publication base, String reason) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
99 // --------------------------------------------------------------------
100 return versionDocument(base, new Document.Properties().setDescription(reason));
103 public Publication versionDocument (Publication base, Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
104 // --------------------------------------------------------------------------------
105 Document previous = base.value();
107 dprop.setDocument(previous); // Initializes the Step property
108 if (dprop.getStep().getNumber() != this.step.getNumber()) throw new MismatchException();
110 if (dprop.getAuthor() == null) dprop.setAuthor(previous.getAuthor());
111 String summary = dprop.getDescription();
113 // Creation of the document
114 Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
115 newdoc.buildReferenceFrom(getOwner(), previous);
116 Database.getSession().save(newdoc);
119 if (summary == null) newdoc.addRelation( new VersionsRelation(newdoc, previous) );
120 else newdoc.addRelation( new VersionsRelation(newdoc, previous, summary) );
122 // Update of usedby relations, if exist
123 List<Relation> relist = previous.getRelations(UsedByRelation.class);
124 Study scope = getOwnerStudy();
125 for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
126 UsedByRelation relation = (UsedByRelation)i.next();
127 Document relatedoc = relation.getTo();
128 if (scope.shares(relatedoc)) relatedoc.addRelation( new UsesRelation(relatedoc, newdoc) );
129 else relation.moveTo(newdoc);
131 return new Publication(newdoc, owner);
134 public SimulationContext addSimulationContext (SimulationContext.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
135 // ----------------------------------------------------------------------------------
136 SimulationContext context = new SimulationContext(dprop.setStep(step));
137 return addSimulationContext(context);
140 public SimulationContext addSimulationContext (SimulationContext context) {
141 // -------------------------------------------------------------------------
142 context.hold(); // Increments the reference count of simulation context
143 if (owner.isSaved()) try {
144 Session session = Database.getSession();
145 Index lucin = Database.getIndex();
147 if (!context.isSaved()) session.save(context);
149 contex.add(context); // The context is also referenced from this (transient) Step
150 session.update(owner);
151 updateKnowledgeElementsIndex(lucin);
153 catch (Exception error) {
156 else { // Happens when copying a scenario
158 contex.add(context); // The context is also referenced from this (transient) Step
159 // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
164 public User getActor () {
165 // -----------------------
169 public List<Publication> getAllDocuments () {
170 // -------------------------------------------
171 return Collections.unmodifiableList(docums);
174 public List<SimulationContext> getAllSimulationContexts () {
175 // ----------------------------------------------------------
176 return Collections.unmodifiableList(contex);
179 public Publication getDocument (int index) {
180 // ------------------------------------------
181 for (Iterator<Publication> i=docums.iterator(); i.hasNext();) {
182 Publication found = i.next(); // In a given study step,
183 if (found.value().getIndex() == index) return found; // there is only one publication of a given document
188 public int getNumber () {
189 // -----------------------
190 return step.getNumber();
193 public ProjectElement getOwner () {
194 // ---------------------------------
195 return owner; // May be a Study or a Scenario
198 public Study getOwnerStudy () {
199 // -----------------------------
200 if (owner instanceof Study) return (Study)owner;
201 else return ((Scenario)owner).getOwnerStudy();
204 public String getPath () {
205 // ------------------------
206 return step.getPath();
209 public List<Publication> getResultDocuments () {
210 // ----------------------------------------------
211 List<Publication> result = new Vector<Publication>();
213 if (!docums.isEmpty()) for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
214 Publication content = i.next();
215 DocumentType type = content.value().getType();
216 if (!type.isResultOf(this.getStep())) continue;
222 public ProjectSettings.Step getStep () {
223 // --------------------------------------
227 public SimulationContext getSimulationContext (int index) {
228 // ---------------------------------------------------------
229 for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
230 SimulationContext myctex = i.next();
231 if (myctex.getIndex() == index) return myctex;
236 public List<SimulationContext> getSimulationContext (SimulationContextType type) {
237 // --------------------------------------------------------------------------------
238 Vector<SimulationContext> result = new Vector<SimulationContext>();
240 for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
241 SimulationContext myctex = i.next();
242 if (myctex.getType().equals(type)) result.add(myctex);
247 public List<DocumentType> getValidDocumentTypes () {
248 // --------------------------------------------------
249 return Document.selectTypesOf(step);
252 public boolean isStarted () {
253 // ---------------------------
254 if (!step.mayContain(KnowledgeElement.class)) return !docums.isEmpty();
256 List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
257 if (kelm.isEmpty() && docums.isEmpty()) return false;
261 public boolean isFinished () {
262 // ----------------------------
263 if (!step.mayContain(KnowledgeElement.class)) { // Check if all result documents are approved
264 if (docums.isEmpty()) return false;
265 boolean result = false;
266 for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
267 Document content = i.next().value();
268 DocumentType type = content.getType();
269 if (!type.isResultOf(this.getStep())) continue;
270 if (content.getProgressState() == ProgressState.EXTERN) continue;
271 result = true; // There is at least 1 non external result document
272 if (content.getProgressState() != ProgressState.APPROVED) return false;
276 else { // Check if all existing knowledges are approved
277 List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
278 if (kelm.isEmpty()) return false;
279 for (Iterator<KnowledgeElement> i=kelm.iterator(); i.hasNext(); ) {
280 KnowledgeElement content = i.next();
281 if (content.getProgressState() != ProgressState.APPROVED) return false;
287 public boolean mayContain (@SuppressWarnings("rawtypes") Class type) {
288 // --------------------------------------------------------------------
289 return step.mayContain(type);
292 public boolean removeDocument (Publication doctag) {
293 // --------------------------------------------------
294 Document value = doctag.value();
295 Publication torem = getDocument(value.getIndex());
296 Session session = Database.getSession();
298 if (torem == null) return false;
301 session.update(owner);
302 if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
303 Set<Relation> links = value.getAllRelations();
304 List<Document> using = new Vector<Document>();
305 for (Iterator<Relation> i=links.iterator(); i.hasNext(); ) {
306 Relation link = i.next();
307 if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
308 session.delete(link.getTo()); // The corresponding physical file is not removed from the vault
310 if (link.getClass().equals(UsesRelation.class)) { // Document dependency
311 using.add((Document)link.getTo());
314 for (Iterator<Document> i=using.iterator(); i.hasNext(); ) {
315 i.next().removeRelation(UsedByRelation.class, value);
317 session.delete(value); // The corresponding physical file is not removed from the vault
322 public boolean removeSimulationContext (SimulationContext context) {
323 // ------------------------------------------------------------------
324 SimulationContext torem = getSimulationContext(context.getIndex());
325 Session session = Database.getSession();
327 if (torem == null) return false;
328 if (!owner.remove(torem)) return false;
330 contex.remove(torem);
331 session.update(owner);
332 if (torem.isShared()) {
334 session.update(torem);
336 session.delete(torem);
341 public void setActor (User user) {
342 // --------------------------------
345 // ==============================================================================================================================
346 // Protected member functions
347 // ==============================================================================================================================
349 protected boolean add (Publication newdoc) {
350 // ------------------------------------------
351 if (!owner.add(newdoc)) return false; // Updates the study in memory
352 docums.add(0, newdoc); // Updates this step
353 newdoc.value().hold(); // Increments the configuration tag count of document
354 // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
355 // database (it will be saved later by cascading the update of owner scenario).
359 protected boolean remove (Publication oldoc) {
360 // --------------------------------------------
361 if (!owner.remove(oldoc)) return false; // Updates the study in memory
362 docums.remove(oldoc); // Updates this step
363 oldoc.value().release(); // Decrements the configuration tag count of document
364 // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
368 // ==============================================================================================================================
370 // ==============================================================================================================================
372 private void updateKnowledgeElementsIndex(Index lucin) {
373 // ------------------------------------------------------
375 if (owner instanceof Scenario) {
376 scenarii = new Scenario[1];
377 scenarii[0] = (Scenario)owner;
379 scenarii = getOwnerStudy().getScenarii();
382 for (int i=0; i<scenarii.length; i++) {
383 Scenario scene = scenarii[i];
384 List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
385 for (Iterator<KnowledgeElement> j=knelm.iterator(); j.hasNext(); ) {
386 KnowledgeElement kelm = j.next();
389 scene.updateMyIndex(lucin);
392 catch (Exception error) {
393 // logger.error("Unable to re-index Knowledge Elements, reason:", error);