Salome HOME
Refactoring: kernel and som are moved to Siman-Common.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / som / Step.java
diff --git a/Workspace/Siman-Common/src/org/splat/som/Step.java b/Workspace/Siman-Common/src/org/splat/som/Step.java
new file mode 100644 (file)
index 0000000..e22975e
--- /dev/null
@@ -0,0 +1,396 @@
+package org.splat.som;
+/**
+ * 
+ * @author    Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+import java.util.Iterator;
+
+import org.hibernate.Session;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MismatchException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.NotApplicableException;
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+import org.splat.som.Database;
+
+
+public class Step {
+       
+       private ProjectSettings.Step    step;
+    private ProjectElement          owner;
+    private List<SimulationContext> contex;
+    private List<Publication>       docums;
+    private User                    actor;     // Actor involved in operations on published documents and requiring a time-stamp
+
+//  ==============================================================================================================================
+//  Constructor
+//  ==============================================================================================================================
+
+    protected Step (ProjectSettings.Step step, ProjectElement owner) {
+//  ----------------------------------------------------------------
+      this.step   = step;
+      this.owner  = owner;
+      this.contex = new Vector<SimulationContext>();
+      this.docums = new Vector<Publication>();
+      this.actor  = null;
+
+//  Filtering of Simulation contexts, if exist
+      for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+       SimulationContext adoc = i.next();
+        if (!adoc.isInto(this)) continue;
+        this.contex.add(adoc);
+      }
+//  Filtering of Documents, if exist
+      for (Iterator<Publication> i=owner.PublicationIterator(); i.hasNext();) {
+       Publication mydoc = i.next();
+        if (!mydoc.value().isInto(this)) continue;
+        this.docums.add(mydoc);
+      }
+    }
+
+//  ==============================================================================================================================
+//  Public member functions
+//  ==============================================================================================================================
+
+    public Publication createDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException {
+//  -------------------------------------------------------------
+      Document  newdoc = new Document(dprop.setOwner(owner).setStep(step));
+
+//    Creation of the save directory      
+      File wdir = newdoc.getSaveDirectory();
+         if (!wdir.exists()) if (!wdir.mkdirs()) throw new IOException("Cannot create the repository vault directory");
+
+//    Identification and save
+      newdoc.buildReferenceFrom(getOwnerStudy());
+      Database.getSession().save(newdoc);
+
+      return  new Publication(newdoc, owner);
+    }
+
+    public Publication assignDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
+//  -------------------------------------------------------------
+      String refid = dprop.getReference();
+      if    (refid == null)    return null;
+
+      Document  slot = Database.selectDocument(refid, new Revision().toString());
+      if ( slot == null )      return null;
+      if (!slot.isUndefined()) return null;     // Should not happen
+
+      slot.initialize(dprop.setOwner(getOwnerStudy()));
+      return  new Publication(slot, owner);
+    }
+
+    public Publication versionDocument (Publication base) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+//  -----------------------------------------------------
+      return versionDocument(base, new Document.Properties());
+    }
+
+    public Publication versionDocument (Publication base, String reason) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+//  --------------------------------------------------------------------
+      return versionDocument(base, new Document.Properties().setDescription(reason));
+    }
+
+    public Publication versionDocument (Publication base, Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+//  --------------------------------------------------------------------------------
+      Document previous = base.value();
+      
+      dprop.setDocument(previous);        // Initializes the Step property
+      if (dprop.getStep().getNumber() != this.step.getNumber()) throw new MismatchException();
+
+      if (dprop.getAuthor() == null) dprop.setAuthor(previous.getAuthor());
+      String    summary = dprop.getDescription();
+
+//    Creation of the document
+      Document  newdoc = new Document(dprop.setOwner(owner).setStep(step));
+      newdoc.buildReferenceFrom(getOwner(), previous);
+      Database.getSession().save(newdoc);
+
+//    Versioning
+      if (summary == null) newdoc.addRelation( new VersionsRelation(newdoc, previous) );
+      else                 newdoc.addRelation( new VersionsRelation(newdoc, previous, summary) );
+
+//    Update of usedby relations, if exist
+      List<Relation> relist = previous.getRelations(UsedByRelation.class);
+      Study          scope  = getOwnerStudy();
+      for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
+        UsedByRelation relation  = (UsedByRelation)i.next();
+        Document       relatedoc = relation.getTo();
+        if (scope.shares(relatedoc)) relatedoc.addRelation( new UsesRelation(relatedoc, newdoc) );
+        else                         relation.moveTo(newdoc);
+      }
+      return  new Publication(newdoc, owner);
+    }
+
+    public SimulationContext addSimulationContext (SimulationContext.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+//  ----------------------------------------------------------------------------------
+      SimulationContext           context = new SimulationContext(dprop.setStep(step));
+      return addSimulationContext(context);
+    }
+
+    public SimulationContext addSimulationContext (SimulationContext context) {
+//  -------------------------------------------------------------------------
+      context.hold();            // Increments the reference count of simulation context
+      if (owner.isSaved()) try {
+        Session  session = Database.getSession();
+        Index    lucin   = Database.getIndex();
+
+        if (!context.isSaved()) session.save(context);
+        owner.add(context);
+        contex.add(context);     // The context is also referenced from this (transient) Step
+        session.update(owner);
+        updateKnowledgeElementsIndex(lucin);
+      }
+      catch (Exception error) {
+        return null;
+      }
+      else {                     // Happens when copying a scenario
+        owner.add(context);
+        contex.add(context);     // The context is also referenced from this (transient) Step
+//      In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
+      }
+      return context;
+    }
+
+    public User getActor () {
+//  -----------------------
+      return actor;
+    }
+
+    public List<Publication> getAllDocuments () {
+//  -------------------------------------------
+      return  Collections.unmodifiableList(docums);
+    }
+    
+    public List<SimulationContext> getAllSimulationContexts () {
+//  ----------------------------------------------------------
+      return  Collections.unmodifiableList(contex);
+    }
+
+    public Publication getDocument (int index) {
+//  ------------------------------------------
+      for (Iterator<Publication> i=docums.iterator(); i.hasNext();) {
+       Publication found = i.next();                          // In a given study step,
+       if (found.value().getIndex() == index) return found;   // there is only one publication of a given document
+      }
+      return null;
+    }
+    
+    public int getNumber () {
+//  -----------------------
+      return step.getNumber();
+    }
+
+    public ProjectElement getOwner () {
+//  ---------------------------------
+      return owner;   // May be a Study or a Scenario
+    }
+
+    public Study getOwnerStudy () {
+//  -----------------------------
+      if (owner instanceof Study) return  (Study)owner;
+      else                        return ((Scenario)owner).getOwnerStudy();
+    }
+
+    public String getPath () {
+//  ------------------------
+      return step.getPath();
+    }
+
+    public List<Publication> getResultDocuments () {
+//  ----------------------------------------------
+      List<Publication> result = new Vector<Publication>();
+      
+      if (!docums.isEmpty()) for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+       Publication  content = i.next();
+        DocumentType type    = content.value().getType();
+        if (!type.isResultOf(this.getStep())) continue;
+        result.add(content);
+         }
+      return result;
+    }
+
+    public ProjectSettings.Step getStep () {
+//  --------------------------------------
+      return step;
+    }
+
+    public SimulationContext getSimulationContext (int index) {
+//  ---------------------------------------------------------
+      for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+        SimulationContext myctex = i.next();
+        if (myctex.getIndex() == index) return myctex;
+      }
+      return null;
+    }
+
+    public List<SimulationContext> getSimulationContext (SimulationContextType type) {
+//  --------------------------------------------------------------------------------
+      Vector<SimulationContext> result = new Vector<SimulationContext>();
+
+      for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+        SimulationContext myctex = i.next();
+        if (myctex.getType().equals(type)) result.add(myctex);
+      }
+      return result;
+    }
+
+    public List<DocumentType> getValidDocumentTypes () {
+//  --------------------------------------------------
+      return Document.selectTypesOf(step);
+    }
+
+    public boolean isStarted () {
+//  ---------------------------
+      if (!step.mayContain(KnowledgeElement.class)) return !docums.isEmpty();
+
+      List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
+      if (kelm.isEmpty() && docums.isEmpty()) return false;
+      return true;
+    }
+
+    public boolean isFinished () {
+//  ----------------------------
+      if (!step.mayContain(KnowledgeElement.class)) {   // Check if all result documents are approved
+        if (docums.isEmpty()) return false;
+        boolean result = false;
+        for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+          Document     content = i.next().value();
+          DocumentType type    = content.getType();
+          if (!type.isResultOf(this.getStep())) continue;
+          if (content.getProgressState() == ProgressState.EXTERN) continue;
+          result = true;          // There is at least 1 non external result document
+          if (content.getProgressState() != ProgressState.APPROVED) return false;
+       }
+       return result;
+      }
+      else {                                            // Check if all existing knowledges are approved
+        List<KnowledgeElement> kelm  = ((Scenario)owner).getAllKnowledgeElements();
+        if (kelm.isEmpty()) return false;
+        for (Iterator<KnowledgeElement> i=kelm.iterator(); i.hasNext(); ) {
+                 KnowledgeElement  content = i.next();
+          if (content.getProgressState() != ProgressState.APPROVED) return false;
+               }
+        return true;
+      }
+    }
+
+    public boolean mayContain (@SuppressWarnings("rawtypes") Class type) {
+//  --------------------------------------------------------------------
+      return step.mayContain(type);
+    }
+
+    public boolean removeDocument (Publication doctag) {
+//  --------------------------------------------------
+      Document     value   = doctag.value();
+      Publication  torem   = getDocument(value.getIndex());
+      Session      session = Database.getSession();
+
+      if (torem == null)        return false;
+
+      this.remove(torem);
+      session.update(owner);
+      if (!value.isPublished() && !value.isVersioned()) {         // The referenced document is no more used
+       Set<Relation>  links = value.getAllRelations();
+       List<Document> using = new Vector<Document>();
+        for (Iterator<Relation> i=links.iterator(); i.hasNext(); ) {
+          Relation link = i.next();
+          if (link.getClass().equals(ConvertsRelation.class)) {   // File conversion
+           session.delete(link.getTo());                         // The corresponding physical file is not removed from the vault
+          } else
+          if (link.getClass().equals(UsesRelation.class)) {       // Document dependency
+               using.add((Document)link.getTo());
+          }
+        }
+        for (Iterator<Document> i=using.iterator(); i.hasNext(); ) {
+          i.next().removeRelation(UsedByRelation.class, value);
+        }
+       session.delete(value);                              // The corresponding physical file is not removed from the vault
+      }
+      return true;
+    }
+
+    public boolean removeSimulationContext (SimulationContext context) {
+//  ------------------------------------------------------------------
+      SimulationContext  torem   = getSimulationContext(context.getIndex());
+      Session            session = Database.getSession();
+
+      if (torem == null)        return false;
+      if (!owner.remove(torem)) return false;
+
+      contex.remove(torem);
+      session.update(owner);
+      if (torem.isShared()) {
+        torem.release();
+        session.update(torem);
+      } else {
+       session.delete(torem);
+      }
+      return true;
+    }
+
+    public void setActor (User user) {
+//  --------------------------------
+      actor = user;
+    }
+//  ==============================================================================================================================
+//  Protected member functions
+//  ==============================================================================================================================
+
+    protected boolean add (Publication newdoc) {
+//  ------------------------------------------
+      if (!owner.add(newdoc)) return false;   // Updates the study in memory
+      docums.add(0, newdoc);                  // Updates this step
+      newdoc.value().hold();                  // Increments the configuration tag count of document
+//    If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
+//    database (it will be saved later by cascading the update of owner scenario).    
+      return true;
+    }
+
+    protected boolean remove (Publication oldoc) {
+//  --------------------------------------------
+      if (!owner.remove(oldoc)) return false; // Updates the study in memory
+      docums.remove(oldoc);                   // Updates this step
+      oldoc.value().release();                // Decrements the configuration tag count of document
+//    The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
+      return true;
+    }
+
+//  ==============================================================================================================================
+//  Private services
+//  ==============================================================================================================================
+
+    private void updateKnowledgeElementsIndex(Index lucin) {
+//  ------------------------------------------------------
+      Scenario[] scenarii;
+      if (owner instanceof Scenario) {
+       scenarii    = new Scenario[1];
+       scenarii[0] = (Scenario)owner;
+      } else {
+        scenarii    = getOwnerStudy().getScenarii();
+      }
+      try {
+        for (int i=0; i<scenarii.length; i++) {
+         Scenario              scene = scenarii[i];
+         List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
+         for (Iterator<KnowledgeElement> j=knelm.iterator(); j.hasNext(); ) {
+            KnowledgeElement kelm = j.next();
+            lucin.update(kelm);
+         }
+         scene.updateMyIndex(lucin);
+        }
+      }
+      catch (Exception error) {
+//      logger.error("Unable to re-index Knowledge Elements, reason:", error);
+      }
+    }
+}
\ No newline at end of file