]> SALOME platform Git repositories - tools/siman.git/commitdiff
Salome HOME
Document id generation is fixed. Document index is updated in the database now.
authorrkv <rkv@opencascade.com>
Mon, 24 Dec 2012 13:14:51 +0000 (13:14 +0000)
committerrkv <rkv@opencascade.com>
Mon, 24 Dec 2012 13:14:51 +0000 (13:14 +0000)
13 files changed:
Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.java
Workspace/Siman-Common/src/org/splat/service/DocumentServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/PublicationServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java
Workspace/Siman-Common/src/org/splat/som/Step.java
Workspace/Siman-Common/src/test/splat/dao/TestStudyDAO.java
Workspace/Siman-Common/src/test/splat/service/TestProjectSettingsService.java
Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java [new file with mode: 0644]
Workspace/Siman-Common/src/test/splat/service/TestStudyService.java [new file with mode: 0644]

index 97511b3915da3f2fa1adccca2dc80a37e568db4c..bf08b16ff78e281bd56f71348b1935ef35289f69 100644 (file)
@@ -205,4 +205,11 @@ public abstract class ProjectElement extends Entity {
        public Set<Publication> getDocums() {
                return docums;
        }
+
+       /**
+        * Return the study of the project element.
+        * 
+        * @return the project element study
+        */
+       public abstract Study getOwnerStudy();
 }
\ No newline at end of file
index 5ec4291d85be9f5ca871ab8dd9debc2656d97338..63da57aeb0014d31e7e8d30cf77304ea7145dfe5 100644 (file)
@@ -1,4 +1,5 @@
 package org.splat.dal.bo.som;
+
 /**
  * Publication objects are the way to reference document versions from a Project Element.
  * As such, a Document version is added (or published) to a Project Element through a Publication object.
@@ -25,179 +26,211 @@ import org.splat.dal.bo.kernel.Persistent;
 import org.splat.dal.bo.kernel.Relation;
 import org.splat.som.Step;
 
-
+/**
+ * Persistent class representing a tag of a document published in a study/scenario activity.
+ */
 public class Publication extends Persistent {
 
-//  Persistent fields
-    private  Document        mydoc;
-    private  ProjectElement  owner;     // Either Study or Scenario, depending on the step involved by the publication
-    private  char            isnew;     // True if this references a document version new for the owner project element
+       // Persistent fields
+       /**
+        * Persistent field. The published document.
+        */
+       private Document mydoc;
+       /**
+        * Persistent field. Either Study or Scenario, depending on the step involved by the publication.
+        */
+       private ProjectElement owner;
+       /**
+        * Persistent field. True if this references a document version new for the owner project element.
+        */
+       private char isnew;
 
-//  Transient fields
-    private  Step            mystep;
+       // Transient fields
+       /**
+        * Transient field. The step where the document is published.
+        */
+       private Step mystep;
 
-//  ==============================================================================================================================
-//  Construction
-//  ==============================================================================================================================
+       // ==============================================================================================================================
+       // Construction
+       // ==============================================================================================================================
 
-/**
+       /**
         * Get the mystep.
+        * 
         * @return the mystep
         */
        public Step getStep() {
                return mystep;
        }
+
        /**
         * Set the mystep.
-        * @param aStep the mystep to set
+        * 
+        * @param aStep
+        *            the mystep to set
         */
        public void setStep(final Step aStep) {
                this.mystep = aStep;
        }
-       //  Database fetch constructor
-    public Publication () {
-//  ------------------------
-      mystep = null;
-    }
-//  Internal constructors
-    public Publication (final Document doc, final ProjectElement publisher) {
-//  --------------------------------------------------------------
-      mydoc  = doc;
-      mystep = null;
-      owner  = publisher;
-      isnew  = 'Y';
-    }
-//  ==============================================================================================================================
-//  Member functions
-//  ==============================================================================================================================
-
-    public Relation addDependency (final Publication to) {
-//  ----------------------------------------------
-      return  this.addDependency(to.value());
-    }
-
-    public Relation addDependency (final Document to) {
-//  -------------------------------------------
-      if (to == null) {
-               return null;
-       } else {
-               return mydoc.addRelation( new UsesRelation(mydoc, to) );
-       }
-    }
 
-/**
- * Returns either the Study Scenario or the Study itself to which this publication belongs, depending on the Study Step into
- * which the referenced document has been published.<br/>
- * If this publication belongs to a Study, the Project Element returned is the Study returned by getOwnerStudy().
- * 
- * @return the Study Scenario or the Study to which this publication belongs to
- * @see    #getOwnerStudy()
- */
-    public ProjectElement getOwner () {
-//  ---------------------------------
-      return owner;
-    }
+       /**
+        * Database fetch constructor.
+        */
+       public Publication() {
+               super();
+               mystep = null;
+       }
 
-    /**
+       /**
+        * Internal constructors.
+        * 
+        * @param doc
+        *            the published document
+        * @param publisher
+        *            the project element where the document is published
+        */
+       public Publication(final Document doc, final ProjectElement publisher) {
+               super();
+               mydoc = doc;
+               mystep = null;
+               owner = publisher;
+               isnew = 'Y';
+       }
+
+       // ==============================================================================================================================
+       // Member functions
+       // ==============================================================================================================================
+
+       public Relation addDependency(final Publication to) {
+               return this.addDependency(to.value());
+       }
+
+       public Relation addDependency(final Document to) {
+               Relation res = null;
+               if (to != null) {
+                       res = mydoc.addRelation(new UsesRelation(mydoc, to));
+               }
+               return res;
+       }
+
+       /**
+        * Returns either the Study Scenario or the Study itself to which this publication belongs, depending on the Study Step into which the
+        * referenced document has been published.<br/> If this publication belongs to a Study, the Project Element returned is the Study
+        * returned by getOwnerStudy().
+        * 
+        * @return the Study Scenario or the Study to which this publication belongs to
+        * @see #getOwnerStudy()
+        */
+       public ProjectElement getOwner() {
+               return owner;
+       }
+
+       /**
         * Set the owner.
-        * @param owner the owner to set
+        * 
+        * @param owner
+        *            the owner to set
         */
        public void setOwner(final ProjectElement owner) {
                this.owner = owner;
        }
 
-       public Study getOwnerStudy () {
-//  -----------------------------
-      if (owner instanceof Study) {
-               return  (Study)owner;
-       } else {
-               return ((Scenario)owner).getOwnerStudy();
+       /**
+        * Returns the study where the document is published.
+        * 
+        * @return the owner study
+        */
+       public Study getOwnerStudy() {
+               return owner.getOwnerStudy();
        }
-    }
 
-/**
- * Returns the state of this published document.
- * It is the same than the state of the referenced document, unless this publication is out-of-date, in which case it is
- * In-Work state.
- * 
- * @see #outdate()
- * @see #isOutdated()
- */
-    public ProgressState getProgressState () {
-//  ----------------------------------------
-      if (this.isOutdated()) {
-               return ProgressState.inWORK;   // Overrides the document state
-       } else {
-               return mydoc.getProgressState();
-       }
-    }
-
-    public List<Publication> getRelations (final Class<? extends Relation> type) {
-//  ----------------------------------------------------------------------
-      if (type == null) {
-               return null;
-       }
-
-      List<Publication> result = new ArrayList<Publication>();
-      List<Relation>    relist = mydoc.getRelations(type);
-      for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
-        Relation     relation  = i.next();
-        Document     relatedoc = (Document)relation.getTo();
-        Publication  related   = owner.getPublication(relatedoc);
-        if (related != null) {
-          result.add(related);
-        } else if (owner instanceof Scenario) {   // The relation may cross steps belonging to a scenario and its owner study
-                 related = ((Scenario)owner).getOwnerStudy().getPublication(relatedoc);
-                 if (related != null) {
-                         result.add(related);
-                 }
-               }
-      }
-      return result;
-    }
-
-    public File getSourceFile () {
-//  ----------------------------
-      return mydoc.getSourceFile();
-    }
-
-    public boolean isNewForOwner () {
-//  -------------------------------
-      return (isnew == 'Y');
-    }
-
-    public boolean isOutdated () {
-//  ----------------------------
-      return (isnew == 'O');
-    }
-
-    /**
+       /**
+        * Returns the state of this published document. It is the same than the state of the referenced document, unless this publication is
+        * out-of-date, in which case it is In-Work state.
+        * 
+        * @see #outdate()
+        * @see #isOutdated()
+        * @return the document progress state
+        */
+       public ProgressState getProgressState() {
+               ProgressState res;
+               if (this.isOutdated()) {
+                       res = ProgressState.inWORK; // Overrides the document state
+               } else {
+                       res = mydoc.getProgressState();
+               }
+               return res;
+       }
+
+       public List<Publication> getRelations(final Class<? extends Relation> type) {
+               if (type == null) {
+                       return null;
+               }
+
+               List<Publication> result = new ArrayList<Publication>();
+               List<Relation> relist = mydoc.getRelations(type);
+               for (Iterator<Relation> i = relist.iterator(); i.hasNext();) {
+                       Relation relation = i.next();
+                       Document relatedoc = (Document) relation.getTo();
+                       Publication related = owner.getPublication(relatedoc);
+                       if (related != null) {
+                               result.add(related);
+                       } else if (owner instanceof Scenario) { // The relation may cross steps belonging to a scenario and its owner study
+                               related = owner.getOwnerStudy().getPublication(relatedoc);
+                               if (related != null) {
+                                       result.add(related);
+                               }
+                       }
+               }
+               return result;
+       }
+
+       public File getSourceFile() {
+               return mydoc.getSourceFile();
+       }
+
+       public boolean isNewForOwner() {
+               return (isnew == 'Y');
+       }
+
+       public boolean isOutdated() {
+               return (isnew == 'O');
+       }
+
+       /**
         * Get the isnew.
+        * 
         * @return the isnew
         */
        public char getIsnew() {
                return isnew;
        }
+
        /**
         * Set the isnew.
-        * @param isnew the isnew to set
+        * 
+        * @param isnew
+        *            the isnew to set
         */
        public void setIsnew(final char isnew) {
                this.isnew = isnew;
        }
-       
-/**
- * Returns the document version referenced by this Publication.
- */
-    public Document value () {
-//  ------------------------
-      return mydoc;
-    }
+
+       /**
       * Returns the document version referenced by this Publication.
       */
+       public Document value() {
+               return mydoc;
+       }
+
        /**
         * Set the mydoc.
-        * @param mydoc the mydoc to set
+        * 
+        * @param mydoc
+        *            the mydoc to set
         */
-       public void setValue (final Document aDoc) {
+       public void setValue(final Document aDoc) {
                this.mydoc = aDoc;
        }
 }
\ No newline at end of file
index b2e154b9bc9188fddc5bd3ac1de09c3b6f8d0715..42b1e9799e0f42a1050438f0ffddeef423032822 100644 (file)
@@ -10,10 +10,10 @@ import java.util.Calendar;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-import java.util.HashSet;
 import java.util.Vector;
 
 import org.splat.dal.bo.kernel.Persistent;
@@ -44,13 +44,13 @@ public class Scenario extends ProjectElement {
        /**
         * The persistent set of scenario knowledge elements.
         */
-       private Set<KnowledgeElement> kelms = new HashSet<KnowledgeElement>();
+       private final Set<KnowledgeElement> kelms = new HashSet<KnowledgeElement>();
 
        // Transient fields
        /**
         * The transient map of knowledge elements grouped by types.
         */
-       transient private HashMap<Long, List<KnowledgeElement>> known;
+       transient private final HashMap<Long, List<KnowledgeElement>> known;
        /**
         * The scenario transient list of knowledge elements.
         */
@@ -78,6 +78,7 @@ public class Scenario extends ProjectElement {
 
                // - Public services
 
+               @Override
                public void clear() {
                        super.clear();
                        owner = null;
@@ -103,46 +104,49 @@ public class Scenario extends ProjectElement {
                        return manager;
                }
 
-               public Properties setOwnerStudy(Study owner) {
+               public Properties setOwnerStudy(final Study owner) {
                        this.owner = owner;
                        return this;
                }
 
                // - Setters of Scenario properties
 
-               public Properties setBaseStep(Step base)
+               public Properties setBaseStep(final Step base)
                                throws InvalidPropertyException {
-                       if (!(base.getOwner() instanceof Scenario))
+                       if (!(base.getOwner() instanceof Scenario)) {
                                throw new InvalidPropertyException("step");
+                       }
                        this.base = base;
                        return this;
                }
 
-               public Properties setDate(Date date) {
+               public Properties setDate(final Date date) {
                        this.date = date;
                        return this;
                }
 
-               public Properties setDescription(String summary) {
-                       if (summary.length() > 0)
+               public Properties setDescription(final String summary) {
+                       if (summary.length() > 0) {
                                this.summary = summary;
+                       }
                        return this;
                }
 
-               public Properties setInsertAfter(Scenario previous) {
+               public Properties setInsertAfter(final Scenario previous) {
                        this.previous = previous;
                        return this;
                }
 
-               public Properties setManager(User user) {
+               public Properties setManager(final User user) {
                        this.manager = user;
                        return this;
                }
 
-               public Properties setTitle(String title)
+               public Properties setTitle(final String title)
                                throws InvalidPropertyException {
-                       if (title.length() == 0)
+                       if (title.length() == 0) {
                                throw new InvalidPropertyException("title");
+                       }
                        this.title = title;
                        return this;
                }
@@ -151,12 +155,15 @@ public class Scenario extends ProjectElement {
 
                public void checkValidity() throws MissedPropertyException,
                                InvalidPropertyException, MultiplyDefinedException {
-                       if (owner == null)
+                       if (owner == null) {
                                throw new MissedPropertyException("owner");
-                       if (title == null)
+                       }
+                       if (title == null) {
                                throw new MissedPropertyException("title");
-                       if (manager == null)
+                       }
+                       if (manager == null) {
                                throw new MissedPropertyException("manager");
+                       }
                }
        }
 
@@ -168,7 +175,7 @@ public class Scenario extends ProjectElement {
        }
 
        // Internal constructor
-       public Scenario(Properties sprop) throws MissedPropertyException,
+       public Scenario(final Properties sprop) throws MissedPropertyException,
                        InvalidPropertyException, MultiplyDefinedException {
                super(sprop); // Throws one of the above exception if not valid
                owner = sprop.owner;
@@ -190,13 +197,16 @@ public class Scenario extends ProjectElement {
                }
                lasdate = credate; // Inherited attribute
 
-               if (sprop.summary != null)
+               if (sprop.summary != null) {
                        this.setAttribute(new DescriptionAttribute(this, sprop.summary));
+               }
 
                Scenario[] scene = owner.getScenarii();
-               for (int i = 0; i < scene.length; i++)
-                       if (scene[i].sid > this.sid)
+               for (int i = 0; i < scene.length; i++) {
+                       if (scene[i].sid > this.sid) {
                                this.sid = scene[i].sid;
+                       }
+               }
                sid += 1;
        }
 
@@ -209,16 +219,17 @@ public class Scenario extends ProjectElement {
                        knowl = new Vector<KnowledgeElement>(kelms.size());
                        for (Iterator<KnowledgeElement> i = kelms.iterator(); i.hasNext();) {
                                KnowledgeElement kelm = i.next();
-                               if (kelm.getType().equals("usecase"))
+                               if (kelm.getType().equals("usecase")) {
                                        ucase = kelm;
-                               else
+                               } else {
                                        knowl.add(kelm);
+                               }
                        }
                }
                return Collections.unmodifiableList(knowl);
        }
 
-       public KnowledgeElement getKnowledgeElement(long l) {
+       public KnowledgeElement getKnowledgeElement(final long l) {
                for (Iterator<KnowledgeElement> i = kelms.iterator(); i.hasNext();) {
                        KnowledgeElement mykelm = i.next();
                        if (l == mykelm.getIndex()) {
@@ -228,28 +239,13 @@ public class Scenario extends ProjectElement {
                return null;
        }
 
-/* RKV: Not used
- *     public List<KnowledgeElement> getKnowledgeElementsOf(
-                       KnowledgeElementType type) {
-               if (known == null)
-                       known = new HashMap<Long, List<KnowledgeElement>>();
-
-               long numtype = type.getIndex();
-               List<KnowledgeElement> listype = known.get(numtype);
-               if (listype == null) {
-                       listype = new Vector<KnowledgeElement>();
-                       for (Iterator<KnowledgeElement> i = kelms.iterator(); i.hasNext();) {
-                               KnowledgeElement kelm = i.next();
-                               if (kelm.getType().getIndex() == numtype)
-                                       listype.add(kelm);
-                       }
-                       known.put(numtype, listype);
-               }
-               return listype; // No protection against this object corruption as it would not corrupt the database
-       }
-*/
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.som.ProjectElement#getOwnerStudy()
+        */
+       @Override
        public Study getOwnerStudy() {
-               // -----------------------------
                return owner;
        }
 
@@ -257,7 +253,6 @@ public class Scenario extends ProjectElement {
         * Returns the local reference of this scenario. This reference is unique in the scope of the owner study.
         */
        public String getReference() {
-               // -----------------------------
                return String.valueOf(sid);
        }
 
@@ -265,12 +260,11 @@ public class Scenario extends ProjectElement {
                return cuser; // Null if the scenario has not been checked-out
        }
 
-       public void setUser(User aUser) {
+       public void setUser(final User aUser) {
                cuser = aUser; // Null if the scenario has not been checked-out
        }
 
        public boolean isCheckedout() {
-               // ------------------------------
                return (cuser != null);
        }
 
@@ -301,7 +295,7 @@ public class Scenario extends ProjectElement {
         * @param kelm
         *            the scenario transient "use case" knowledge element
         */
-       public void setUcase(KnowledgeElement kelm) {
+       public void setUcase(final KnowledgeElement kelm) {
                ucase = kelm;
        }
 
@@ -313,14 +307,4 @@ public class Scenario extends ProjectElement {
        public KnowledgeElement getUcase() {
                return ucase;
        }
-
-       /**
-        * Get the known.
-        * 
-        * @return the known
-        */
-/* RKV: Not used
- *     public HashMap<Long, List<KnowledgeElement>> getKnowledgeByType() {
-               return known;
-       }
-*/}
\ No newline at end of file
+}
\ No newline at end of file
index bcb760c5c7ea9ebdc8ff79909d8c33d04e244a99..b052879ca1774e7ccd8ffc621ad1aad28cf3ee17 100644 (file)
@@ -67,7 +67,7 @@ public class Study extends ProjectElement {
        /**
         * Transient map of document types to validation cycles.
         */
-       private transient final Map<String, ValidationCycle> validactor = new HashMap<String, ValidationCycle>(); 
+       private transient final Map<String, ValidationCycle> validactor = new HashMap<String, ValidationCycle>();
        /**
         * Transient set of all actors of the study, i.d. contributors and validation cycles participants.
         */
@@ -364,11 +364,18 @@ public class Study extends ProjectElement {
                return res;
        }
 
+       /**
+        * Get the last numerical index of study documents.
+        * 
+        * @return the last value of the index part of study documents reference
+        */
        public int getLastLocalIndex() {
                return docount;
        }
 
        /**
+        * Set visibility of the study.
+        * 
         * @param aVisibility
         *            a study visibility to set
         */
@@ -377,6 +384,8 @@ public class Study extends ProjectElement {
        }
 
        /**
+        * Set the progress state for the study.
+        * 
         * @param aState
         *            a study progress state to set
         */
@@ -385,7 +394,10 @@ public class Study extends ProjectElement {
        }
 
        /**
+        * Set the study version.
+        * 
         * @param aVersion
+        *            the version
         */
        public void setVersion(final String aVersion) {
                version = aVersion;
@@ -427,4 +439,14 @@ public class Study extends ProjectElement {
        public Set<User> getActor() {
                return actor;
        }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.som.ProjectElement#getOwnerStudy()
+        */
+       @Override
+       public Study getOwnerStudy() {
+               return this;
+       }
 }
\ No newline at end of file
index ea82c87dd4ab85e50b15a803cf049898866c64c8..e0558ac577d6066e38b80700086267020e5d2835 100644 (file)
@@ -118,17 +118,12 @@ public class DocumentServiceImpl implements DocumentService {
         */
        @Transactional
        public void generateDocumentId(final Document aDoc, final Properties dprop) {
-               Study owner = null;
-               if (dprop.getOwner() instanceof Study) {
-                       owner = (Study) dprop.getOwner();
-               } else {
-                       owner = ((Scenario) dprop.getOwner()).getOwnerStudy();
-               }
+               Study owner = dprop.getOwner().getOwnerStudy();
 
                // Synchronize the object with the current Hibernate session.
-               owner = getStudyDAO().get(owner.getIndex());
+               //owner = getStudyDAO().merge(owner);
 
-               SimpleDateFormat tostring = new SimpleDateFormat("yyyy"); //RKV: NOPMD: TODO: Use locale here?
+               SimpleDateFormat tostring = new SimpleDateFormat("yyyy"); // RKV: NOPMD: TODO: Use locale here?
                String year = tostring.format(owner.getDate());
                String filename = generateEncodedName(aDoc, owner);
                String path = owner.getReference();
@@ -143,6 +138,8 @@ public class DocumentServiceImpl implements DocumentService {
                                .append(aDoc.getFile().getFormat()) // File name and extension
                                .toString();
                aDoc.getFile().changePath(path);
+//             owner = getStudyDAO().merge(owner);
+//             getStudyDAO().update(owner);
        }
 
        /**
@@ -334,23 +331,21 @@ public class DocumentServiceImpl implements DocumentService {
         */
        public boolean buildReferenceFrom(final Document aDoc,
                        final ProjectElement scope, final Document lineage) {
-               if (aDoc.getProgressState() != ProgressState.inWORK) {
-                       return false;
-               }
-               Study owner = null;
-               Scenario context = null;
-               if (scope instanceof Study) {
-                       owner = (Study) scope;
-               } else {
-                       context = ((Scenario) scope);
-                       owner = context.getOwnerStudy();
-               }
-               aDoc.setDid(lineage.getDid());
-               if (context != null && (lineage.isVersioned() || owner.shares(lineage))) {
-                       aDoc.setVersion(new Revision(aDoc.getVersion()).setBranch(
-                                       context.getReference()).toString());
+               boolean res = (aDoc.getProgressState() == ProgressState.inWORK);
+               if (res) {
+                       Study owner = scope.getOwnerStudy();
+                       Scenario context = null;
+                       if (scope instanceof Scenario) {
+                               context = ((Scenario) scope);
+                       }
+                       aDoc.setDid(lineage.getDid());
+                       if (context != null
+                                       && (lineage.isVersioned() || owner.shares(lineage))) {
+                               aDoc.setVersion(new Revision(aDoc.getVersion()).setBranch(
+                                               context.getReference()).toString());
+                       }
                }
-               return true;
+               return res;
        }
 
        /**
@@ -551,7 +546,7 @@ public class DocumentServiceImpl implements DocumentService {
                        getDocumentDAO().merge(previous);
                }
                aDoc.setProgressState(state);
-               //RKV: getDocumentDAO().update(aDoc);
+               // RKV: getDocumentDAO().update(aDoc);
        }
 
        // protected void upgrade () {
index e3a4e668ae6468c2b42d5b783d98ee86275abcfd..c0c408d1f953e0f29f200dfcaa150cb86bd1f9a7 100644 (file)
@@ -159,7 +159,7 @@ public class PublicationServiceImpl implements PublicationService {
                                                        table[table.length - 1]).setAuthor(user));
                        updir = addoc.getSourceFile().asFile();
                        if (LOG.isInfoEnabled()) {
-                               LOG.info("Moving \"" + upfile.getName() + "\" to \""
+                               LOG.info("Moving \"" + upfile.getAbsolutePath() + "\" to \""
                                                + updir.getPath() + "\".");
                        }
                        upfile.renameTo(updir);
@@ -499,7 +499,7 @@ public class PublicationServiceImpl implements PublicationService {
                                        "Cannot save a Publication object refering an undefined Document");
                }
                if (!aPublication.value().getSourceFile().exists()) {
-                       throw new FileNotFoundException();
+                       throw new FileNotFoundException(aPublication.value().getSourceFile().asFile().getAbsolutePath());
                }
 
                if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
index c0e9e1f49f80724bbd607049ee506576dc9f5c6f..5d29e806638917f71b20592802fba1d49b9262b4 100644 (file)
@@ -241,6 +241,10 @@ public class StepServiceImpl implements StepService {
        public Publication createDocument(final Step aStep,
                        final Document.Properties dprop) throws MissedPropertyException,
                        InvalidPropertyException, MultiplyDefinedException, IOException {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Local index before: "
+                                       + aStep.getOwnerStudy().getLastLocalIndex());
+               }
                Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
                                .setStep(aStep.getStep()));
                getDocumentService().generateDocumentId(newdoc, dprop);
@@ -253,6 +257,12 @@ public class StepServiceImpl implements StepService {
                }
 
                // Identification and save
+               aStep.getOwnerStudy().setLastLocalIndex(
+                               dprop.getOwner().getOwnerStudy().getLastLocalIndex());
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Local index after: "
+                                       + dprop.getOwner().getOwnerStudy().getLastLocalIndex());
+               }
                getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
                getDocumentDAO().create(newdoc);
 
@@ -488,7 +498,7 @@ public class StepServiceImpl implements StepService {
                                                using.add((Document) link.getTo());
                                        }
                                }
-//                             value.getAllRelations().removeAll(converts);
+                               // value.getAllRelations().removeAll(converts);
                                // Remove relations from depending documents
                                if (LOG.isDebugEnabled()) {
                                        LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
index 7fe60146e84a4838997fdafc15a7c4958e985586..aa84a0b13249c6e3fe17aa4df3b6bb955126f512 100644 (file)
@@ -398,7 +398,6 @@ public class StudyServiceImpl implements StudyService {
        @Transactional
        public int generateLocalIndex(final Study aStudy) {
                aStudy.setLastLocalIndex(aStudy.getLastLocalIndex() + 1);
-               getStudyDAO().update(aStudy);
                return aStudy.getLastLocalIndex();
        }
 
index b8a5cd73b48aad1eb4a75acf7f43aa234f6236d5..8fbbb06ef3a09a55a1d22e28b2408b27099341da 100644 (file)
@@ -59,7 +59,7 @@ public class Step {
                        if (!mydoc.value().isInto(this)) {
                                continue;
                        }
-                       mydoc.setStep(this); //RKV
+                       mydoc.setStep(this); // RKV
                        this._docums.add(mydoc);
                }
        }
@@ -108,11 +108,7 @@ public class Step {
        }
 
        public Study getOwnerStudy() {
-               if (_owner instanceof Study) {
-                       return (Study) _owner;
-               } else {
-                       return ((Scenario) _owner).getOwnerStudy();
-               }
+               return _owner.getOwnerStudy();
        }
 
        public String getPath() {
index 18e6b8f8f07870ae3b645b4dc0f56d73c552bf54..60c48d0b1b6ec9e94ff10ed608b2735364da6fe1 100644 (file)
@@ -28,6 +28,7 @@ import org.splat.dal.bo.som.Scenario;
 import org.splat.dal.bo.som.Study;
 import org.splat.dal.bo.som.Document.Properties;
 import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.DocumentDAO;
 import org.splat.dal.dao.som.StudyDAO;
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MissedPropertyException;
@@ -36,6 +37,7 @@ import org.splat.log.AppLogger;
 import org.splat.service.DocumentTypeService;
 import org.splat.service.PublicationService;
 import org.splat.service.StepService;
+import org.splat.service.StudyService;
 import org.splat.service.technical.ProjectSettingsService;
 import org.splat.service.technical.ProjectSettingsService.Step;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,7 +49,7 @@ import org.testng.annotations.Test;
 import test.splat.common.BaseTest;
 
 /**
- * Test class for KnowledgeElementDAO.
+ * Test class for StudyDAO.
  * 
  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
  * 
@@ -95,6 +97,20 @@ public class TestStudyDAO extends BaseTest {
        @Qualifier("documentTypeService")
        private transient DocumentTypeService _documentTypeService;
 
+       /**
+        * The DocumentDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("documentDAO")
+       private transient DocumentDAO _documentDAO;
+
+       /**
+        * The StudyService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyService")
+       private transient StudyService _studyService;
+
        /**
         * Test creation of a study.<BR>
         * <B>Description :</B> <BR>
@@ -243,6 +259,8 @@ public class TestStudyDAO extends BaseTest {
                getHibernateTemplate().clear();
                Study aStudyFound = _studyDAO.get(id);
 
+               Assert.assertNotNull(aStudyFound);
+
                // Call DAO's get method for a not existing id.
                aStudyFound = _studyDAO.get(-1L);
                getHibernateTemplate().flush();
@@ -402,7 +420,7 @@ public class TestStudyDAO extends BaseTest {
 
                Study aStudy = createStudy();
                // Call DAO's create method for a good transient study.
-               Long id = aStudy.getIndex();//_studyDAO.create(aStudy);
+               Long id = aStudy.getIndex();// _studyDAO.create(aStudy);
                Assert.assertNotNull(id,
                                "Create method returns null instead of a new id.");
                Assert.assertTrue(id > 0, "The new id is not a positive number.");
@@ -725,4 +743,85 @@ public class TestStudyDAO extends BaseTest {
 
                return pub;
        }
+
+       /**
+        * Test of getting a study.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to get it from the database.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's read method for an existing id.</i><BR>
+        * <i>2. call DAO's read method for a not existing id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Object is found in the database successfully<BR>
+        * </li>
+        * <li>Result of search is null<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testIsReferenced() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testIsReferenced()");
+               startNestedTransaction();
+
+               HibernateTemplate ht = getHibernateTemplate();
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = aStudy.getIndex();
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               // Call DAO's get method for an existing id.
+               _studyDAO.flush();
+               getHibernateTemplate().evict(aStudy);
+               getHibernateTemplate().clear();
+               Study aStudyFound = _studyDAO.get(id);
+
+               ProjectElement projElem;
+               Step step;
+               long docId;
+               Document doc;
+               for (int i = _projectSettings.getAllSteps().size(); i > 0; i--) {
+                       LOG.debug("Remove documents from the step " + i);
+                       step = _projectSettings.getStep(i);
+                       if (step.appliesTo(Study.class)) {
+                               projElem = aStudyFound;
+                       } else {
+                               projElem = aStudyFound.getScenarii()[0];
+                       }
+
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+
+                       if (aScStep.getDocuments().size() > 0) {
+                               doc = aScStep.getDocuments().get(0).value();
+                               docId = doc.getIndex();
+/*                             Assert.assertEquals(_documentDAO.isReferenced(doc), (ht.find(
+                                               "from UsesRelation where refer=" + docId).size() + ht
+                                               .find("from UsedByRelation where refer=" + docId)
+                                               .size()) > 0);
+*/                     }
+               }
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testIsReferenced()");
+       }
 }
index 63dbf1b4783806c0e6dbcfbe209b3672d76909db..78d376b3564c0c1a395e2e05315fa28db8a39782 100644 (file)
@@ -479,6 +479,7 @@ public class TestProjectSettingsService extends BaseTest {
                // ////// Load good workflow customization
                getHibernateTemplate().clear();
                _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               Database.getInstance().reset();
                try {
                        _projectSettings.configure(ClassLoader.getSystemResource(
                                        "test/som.xml").getPath());
@@ -486,6 +487,7 @@ public class TestProjectSettingsService extends BaseTest {
                        Assert.fail("Can't find configuration file: ", e);
                }
 
+               getHibernateTemplate().flush();
                List<Step> steps = _projectSettings.getStepsOf(Scenario.class);
                Assert.assertTrue(steps.size() > 0, "No steps are created.");
                KnowledgeElementType ucase = _knowledgeElementTypeService.selectType("usecase");
diff --git a/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java b/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java
new file mode 100644 (file)
index 0000000..ae20269
--- /dev/null
@@ -0,0 +1,489 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   12 Oct 2012
+ * @author         $Author$
+ * @version        $Revision$
+ *****************************************************************************/
+package test.splat.service;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.splat.dal.bo.kernel.User;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
+import org.splat.dal.bo.som.ProgressState;
+import org.splat.dal.bo.som.ProjectElement;
+import org.splat.dal.bo.som.Publication;
+import org.splat.dal.bo.som.Scenario;
+import org.splat.dal.bo.som.Study;
+import org.splat.dal.bo.som.Document.Properties;
+import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.StudyDAO;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.NotApplicableException;
+import org.splat.log.AppLogger;
+import org.splat.service.DocumentTypeService;
+import org.splat.service.ProjectElementService;
+import org.splat.service.PublicationService;
+import org.splat.service.StepService;
+import org.splat.service.StudyService;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.RepositoryService;
+import org.splat.service.technical.ProjectSettingsService.Step;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.orm.hibernate3.HibernateTemplate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import test.splat.common.BaseTest;
+
+/**
+ * Test class for PublicationService.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ * 
+ */
+public class TestPublicationService extends BaseTest {
+
+       /**
+        * Logger for the class.
+        */
+       private static final AppLogger LOG = AppLogger
+                       .getLogger(TestPublicationService.class);
+
+       /**
+        * The StudyDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyDAO")
+       private transient StudyDAO _studyDAO;
+
+       /**
+        * The PublicationService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("publicationService")
+       private transient PublicationService _publicationService;
+
+       /**
+        * The ProjectElementService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectElementService")
+       private transient ProjectElementService _projectElementService;
+
+       /**
+        * The StepService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("stepService")
+       private transient StepService _stepService;
+
+       /**
+        * The ProjectSettingsService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectSettings")
+       private transient ProjectSettingsService _projectSettings;
+
+       /**
+        * The DocumentTypeService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("documentTypeService")
+       private transient DocumentTypeService _documentTypeService;
+
+       /**
+        * The StudyService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyService")
+       private transient StudyService _studyService;
+
+       /**
+        * The RepositoryService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("repositoryService")
+       private transient RepositoryService _repositoryService;
+
+       /**
+        * Create a persistent scenario for tests.
+        * 
+        * @return a persistent scenario
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws IOException
+        *             if document creation is failed
+        * @throws SQLException
+        *             if project settings loading is failed
+        */
+       private Study createStudy() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               // Create a scenario for tests
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               // Load workflow customization
+               try {
+                       _projectSettings.configure(ClassLoader.getSystemResource(
+                                       "test/som.xml").getPath());
+               } catch (FileNotFoundException e) {
+                       Assert.fail("Can't find som.xml: ", e);
+               }
+               List<Step> steps = _projectSettings.getAllSteps();
+               Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+               // Create a test user
+               User.Properties uprop = new User.Properties();
+               uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+                               .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+                               .addRole("TST_user").setMailAddress(
+                                               "noreply@salome-platform.org");
+               uprop.disableCheck();
+               User anAuthor = new User(uprop);
+               ht.saveOrUpdate(anAuthor);
+
+               // Create a test study
+               Study.Properties stprops = new Study.Properties().setReference(
+                               "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
+               Study aStudy = new Study(stprops);
+               ht.saveOrUpdate(aStudy);
+
+               // Create a test scenario
+               Scenario.Properties sprops = new Scenario.Properties().setTitle(
+                               "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
+               Scenario aScenario = new Scenario(sprops);
+               aStudy.getScenariiList().add(aScenario);
+               ht.saveOrUpdate(anAuthor);
+               ht.saveOrUpdate(aStudy);
+               ht.saveOrUpdate(aScenario);
+
+               // Create documents for each scenario step
+               Document.Properties dprop = new Document.Properties().setAuthor(
+                               anAuthor).setDate(new Date());
+               int i = 0;
+               Publication usedPub = null;
+               Map<Long, Long> usedMap = new HashMap<Long, Long>();
+               for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
+                       Step step = _projectSettings.getStep(stepNum);
+                       LOG.debug("Create scenario step: " + stepNum);
+                       ProjectElement projElem;
+
+                       if (step.appliesTo(Study.class)) {
+                               projElem = aStudy;
+                       } else {
+                               projElem = aScenario;
+                       }
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+                       List<DocumentType> dtypes = _documentTypeService
+                                       .selectTypesOf(step);
+                       if (dtypes.size() > 0) {
+                               DocumentType dtype = dtypes.get(0);
+                               // Create a document published in the scenario
+                               // document<i>: document type[0] - first type used on the step
+                               // <source-file>.brep
+                               // <attached-file>.med
+                               i++;
+                               dprop.setName("document" + stepNum).setType(dtype);
+                               if (step.getNumber() > 3) {
+                                       dprop.setFormat("med");
+                               } else {
+                                       dprop.setFormat("py");
+                               }
+                               Publication pub = createDoc(projElem, aScStep, dprop, "med",
+                                               false);
+                               if (usedPub != null) {
+                                       pub.addDependency(usedPub);
+                                       LOG.debug("Add dependency: " + pub.value().getTitle()
+                                                       + " from " + usedPub.value().getTitle());
+                                       ht.saveOrUpdate(pub.value());
+                                       ht.flush();
+
+                                       usedMap.put(pub.getIndex(), usedPub.getIndex());
+                               }
+                               usedPub = pub;
+                       }
+                       if (dtypes.size() <= 0) {
+                               LOG.debug("No document types are found for scenario step " + i);
+                       }
+               }
+
+               // Check that the scenario and its documents have been created correctly.
+
+               Assert.assertNotNull(ht.find("from Document"),
+                               "No documents in the database.");
+               Assert.assertTrue(ht.find("from Document").size() > 0,
+                               "No documents in the database.");
+
+               Assert.assertNotNull(ht.find("from Publication where owner="
+                               + aScenario.getIndex()), "No publications in the database.");
+               Assert.assertTrue(
+                               ht.find("from Publication where owner=" + aScenario.getIndex())
+                                               .size() > 0, "No publications in the database.");
+
+               for (Publication p : (List<Publication>) ht
+                               .find("from Publication where owner=" + aScenario.getIndex())) {
+                       LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
+                                       + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
+                                       + "]");
+                       Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
+                                       "The publication was not attached to the scenario.");
+               }
+
+               // Remove the scenario from the current hibernate session.
+               ht.evict(aScenario);
+               // Check that the scenario is created in the database.
+               Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
+               Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
+               Assert.assertTrue(aScen.getDocums().size() > 0,
+                               "No publications in the scenario.");
+
+               Assert.assertTrue(i > 0,
+                               "More then one document must be in the database");
+
+               // Check created uses relations
+               Assert
+                               .assertTrue(usedMap.size() > 0,
+                                               "Uses relations must be created.");
+               boolean foundAny = false;
+               for (Long usingId : usedMap.keySet()) {
+                       for (Publication pub : aScen.getDocums()) {
+                               if (pub.getIndex() == usingId) {
+                                       boolean found = false;
+                                       for (Publication used : aScen.getDocums()) {
+                                               found = (used.getIndex() == usedMap.get(usingId));
+                                               if (found) {
+                                                       break;
+                                               }
+                                       }
+                                       if (!found) {
+                                               for (Publication used : aStudy.getDocums()) {
+                                                       found = (used.getIndex() == usedMap.get(usingId));
+                                                       if (found) {
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       Assert.assertTrue(found,
+                                                       "Uses relation was not created in the database.");
+                                       foundAny = foundAny || found;
+                               }
+                       }
+               }
+               Assert.assertTrue(foundAny,
+                               "No Uses relation was created in the database.");
+
+               return aScenario.getOwnerStudy();
+       }
+
+       /**
+        * Create a document published in the scenario. <BR>
+        * document:<BR>
+        * document type - type used on the step <BR>
+        * &lt;source-file&gt;.brep <BR>
+        * &lt;attached-file&gt;.med
+        * 
+        * @param aScenario
+        *            the scenario to add the document to
+        * @param aScStep
+        *            scenario step where the document to be published
+        * @param dprop
+        *            document properties
+        * @param attachedFileExt
+        *            extension of the secon attached (exported) file
+        * @param isOutdated
+        *            outdated document flag
+        * @return the publication of the created document
+        * @throws IOException
+        * @throws MultiplyDefinedException
+        * @throws InvalidPropertyException
+        * @throws MissedPropertyException
+        */
+       private Publication createDoc(final ProjectElement aScenario,
+                       final org.splat.som.Step aScStep, final Properties dprop,
+                       final String attachedFileExt, final boolean isOutdated)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException {
+               // Create a document published in the scenario
+               // document<i>: document type - type used on the step
+               // <source-file>.brep
+               // <attached-file>.med
+               Publication pub = _stepService.createDocument(aScStep, dprop);
+               Assert.assertNotNull(pub.getOwner(),
+                               "The publication must be attached to the scenario.");
+               Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
+                               "The publication was not attached to the scenario.");
+
+               if (isOutdated) {
+                       pub.setIsnew('O');
+               }
+               aScenario.add(pub);
+               HibernateTemplate ht = getHibernateTemplate();
+               ht.saveOrUpdate(pub);
+
+               // Attach a file
+               ht.save(pub.value());
+               ht.flush();
+               ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
+
+               return pub;
+       }
+
+       /**
+        * Test of generating a study document index.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to generate the next document index.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's read method for an existing id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>The new index must be equal to the incremented old one and saved into the database<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        *             if test study creation is failed
+        * @throws IOException
+        *             if test study creation is failed
+        * @throws ParseException
+        * @throws InterruptedException
+        * @throws NotApplicableException
+        * 
+        */
+       @Test
+       public void testCreateDoc() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException, NotApplicableException, InterruptedException,
+                       ParseException {
+               LOG.debug(">>>>> BEGIN testCreateDoc()");
+               startNestedTransaction();
+
+               HibernateTemplate ht = getHibernateTemplate();
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = aStudy.getIndex();
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               // Call DAO's get method for an existing id.
+               _studyDAO.flush();
+               getHibernateTemplate().evict(aStudy);
+               getHibernateTemplate().clear();
+               Study aStudyFound = _studyDAO.get(id);
+               ht.evict(aStudyFound);
+
+               long userId = aStudyFound.getAuthor().getIndex();
+               org.splat.som.Step[] studySteps = _projectElementService
+                               .getSteps(aStudyFound);
+               org.splat.som.Step[] scSteps = _projectElementService
+                               .getSteps(aStudyFound.getScenarii()[0]);
+
+               List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
+               steps.addAll(Arrays.asList(studySteps));
+               steps.addAll(Arrays.asList(scSteps));
+               steps.addAll(Arrays.asList(studySteps));
+               for (org.splat.som.Step step: steps) {
+                       LOG.debug("Create a document for the step " + step.getNumber());
+
+                       List<DocumentType> dtypes = _documentTypeService
+                                       .selectTypesOf(step.getStep());
+                       if (dtypes.size() > 0) {
+                               DocumentType dtype = dtypes.get(0);
+                               int oldInd = ht.get(Study.class, aStudyFound.getIndex())
+                                               .getLastLocalIndex();
+
+                               // Create a file in the download directory
+                               String fname = "filename" + step.getNumber() + ".py";
+                               String filePath = getDownloadPath(aStudyFound.getAuthor())
+                                               + fname;
+                               LOG.debug(step.getStep().getKey() + ": "
+                                               + step.getOwner().getClass().getSimpleName()
+                                               + ": Create test file: " + filePath);
+                               FileWriter fw = new FileWriter(filePath);
+                               fw
+                                               .write("Simulation of filename.py file for creating a new document at "
+                                                               + new Date());
+                               fw.close();
+
+                               Publication addoc = _publicationService.createDoc(aStudyFound
+                                               .getIndex(), step, dtype.getIndex(), userId, fname,
+                                               "tstdoc", ProgressState.inWORK, "", "", new Date(),
+                                               null);
+
+                               _studyDAO.flush();
+                               ht.flush();
+
+                               int ind = ht.get(Study.class, aStudyFound.getIndex())
+                                               .getLastLocalIndex();
+
+                               LOG.debug("Previous index: " + oldInd + ", new index: " + ind);
+                               Assert.assertEquals(ht.get(Study.class, aStudyFound.getIndex())
+                                               .getLastLocalIndex(), oldInd + 1,
+                                               "Incremented index must be saved in the database.");
+                               aStudy = (Study) ht.find(
+                                               "from Study where rid = " + aStudyFound.getIndex())
+                                               .get(0);
+                               Assert.assertEquals(aStudy.getLastLocalIndex(), oldInd + 1,
+                                               "Incremented index must be saved in the database.");
+                       }
+               }
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testCreateDoc()");
+       }
+
+       /**
+        * Get path to the user's downloads directory. The directory is created if it is not exist yet.
+        * 
+        * @param user
+        *            user
+        * @return absolute path to downloads directory followed by slash
+        */
+       private String getDownloadPath(final User user) {
+               // Prepare download directory
+               File tmpDir = _repositoryService.getDownloadDirectory(user);
+               if (!tmpDir.exists()) {
+                       Assert.assertTrue(tmpDir.mkdir(),
+                                       "Can't create temporary directory: "
+                                                       + tmpDir.getAbsolutePath());
+               }
+
+               return tmpDir.getAbsolutePath() + "/";
+       }
+
+}
diff --git a/Workspace/Siman-Common/src/test/splat/service/TestStudyService.java b/Workspace/Siman-Common/src/test/splat/service/TestStudyService.java
new file mode 100644 (file)
index 0000000..915f54b
--- /dev/null
@@ -0,0 +1,400 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   12 Oct 2012
+ * @author         $Author$
+ * @version        $Revision$
+ *****************************************************************************/
+package test.splat.service;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.splat.dal.bo.kernel.User;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
+import org.splat.dal.bo.som.ProjectElement;
+import org.splat.dal.bo.som.Publication;
+import org.splat.dal.bo.som.Scenario;
+import org.splat.dal.bo.som.Study;
+import org.splat.dal.bo.som.Document.Properties;
+import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.StudyDAO;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.log.AppLogger;
+import org.splat.service.DocumentTypeService;
+import org.splat.service.PublicationService;
+import org.splat.service.StepService;
+import org.splat.service.StudyService;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.ProjectSettingsService.Step;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.orm.hibernate3.HibernateTemplate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import test.splat.common.BaseTest;
+
+/**
+ * Test class for StudyService.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ * 
+ */
+public class TestStudyService extends BaseTest {
+
+       /**
+        * Logger for the class.
+        */
+       private static final AppLogger LOG = AppLogger
+                       .getLogger(TestStudyService.class);
+
+       /**
+        * The StudyDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyDAO")
+       private transient StudyDAO _studyDAO;
+
+       /**
+        * The PublicationService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("publicationService")
+       private transient PublicationService _publicationService;
+
+       /**
+        * The StepService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("stepService")
+       private transient StepService _stepService;
+
+       /**
+        * The ProjectSettingsService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectSettings")
+       private transient ProjectSettingsService _projectSettings;
+
+       /**
+        * The DocumentTypeService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("documentTypeService")
+       private transient DocumentTypeService _documentTypeService;
+
+       /**
+        * The StudyService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyService")
+       private transient StudyService _studyService;
+
+       /**
+        * Create a persistent scenario for tests.
+        * 
+        * @return a persistent scenario
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws IOException
+        *             if document creation is failed
+        * @throws SQLException
+        *             if project settings loading is failed
+        */
+       private Study createStudy() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               // Create a scenario for tests
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               // Load workflow customization
+               try {
+                       _projectSettings.configure(ClassLoader.getSystemResource(
+                                       "test/som.xml").getPath());
+               } catch (FileNotFoundException e) {
+                       Assert.fail("Can't find som.xml: ", e);
+               }
+               List<Step> steps = _projectSettings.getAllSteps();
+               Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+               // Create a test user
+               User.Properties uprop = new User.Properties();
+               uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+                               .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+                               .addRole("TST_user").setMailAddress(
+                                               "noreply@salome-platform.org");
+               uprop.disableCheck();
+               User anAuthor = new User(uprop);
+               ht.saveOrUpdate(anAuthor);
+
+               // Create a test study
+               Study.Properties stprops = new Study.Properties().setReference(
+                               "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
+               Study aStudy = new Study(stprops);
+               ht.saveOrUpdate(aStudy);
+
+               // Create a test scenario
+               Scenario.Properties sprops = new Scenario.Properties().setTitle(
+                               "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
+               Scenario aScenario = new Scenario(sprops);
+               aStudy.getScenariiList().add(aScenario);
+               ht.saveOrUpdate(anAuthor);
+               ht.saveOrUpdate(aStudy);
+               ht.saveOrUpdate(aScenario);
+
+               // Create documents for each scenario step
+               Document.Properties dprop = new Document.Properties().setAuthor(
+                               anAuthor).setDate(new Date());
+               int i = 0;
+               Publication usedPub = null;
+               Map<Long, Long> usedMap = new HashMap<Long, Long>();
+               for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
+                       Step step = _projectSettings.getStep(stepNum);
+                       LOG.debug("Create scenario step: " + stepNum);
+                       ProjectElement projElem;
+
+                       if (step.appliesTo(Study.class)) {
+                               projElem = aStudy;
+                       } else {
+                               projElem = aScenario;
+                       }
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+                       List<DocumentType> dtypes = _documentTypeService
+                                       .selectTypesOf(step);
+                       if (dtypes.size() > 0) {
+                               DocumentType dtype = dtypes.get(0);
+                               // Create a document published in the scenario
+                               // document<i>: document type[0] - first type used on the step
+                               // <source-file>.brep
+                               // <attached-file>.med
+                               i++;
+                               dprop.setName("document" + stepNum).setType(dtype);
+                               if (step.getNumber() > 3) {
+                                       dprop.setFormat("med");
+                               } else {
+                                       dprop.setFormat("py");
+                               }
+                               Publication pub = createDoc(projElem, aScStep, dprop, "med",
+                                               false);
+                               if (usedPub != null) {
+                                       pub.addDependency(usedPub);
+                                       LOG.debug("Add dependency: " + pub.value().getTitle()
+                                                       + " from " + usedPub.value().getTitle());
+                                       ht.saveOrUpdate(pub.value());
+                                       ht.flush();
+
+                                       usedMap.put(pub.getIndex(), usedPub.getIndex());
+                               }
+                               usedPub = pub;
+                       }
+                       if (dtypes.size() <= 0) {
+                               LOG.debug("No document types are found for scenario step " + i);
+                       }
+               }
+
+               // Check that the scenario and its documents have been created correctly.
+
+               Assert.assertNotNull(ht.find("from Document"),
+                               "No documents in the database.");
+               Assert.assertTrue(ht.find("from Document").size() > 0,
+                               "No documents in the database.");
+
+               Assert.assertNotNull(ht.find("from Publication where owner="
+                               + aScenario.getIndex()), "No publications in the database.");
+               Assert.assertTrue(
+                               ht.find("from Publication where owner=" + aScenario.getIndex())
+                                               .size() > 0, "No publications in the database.");
+
+               for (Publication p : (List<Publication>) ht
+                               .find("from Publication where owner=" + aScenario.getIndex())) {
+                       LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
+                                       + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
+                                       + "]");
+                       Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
+                                       "The publication was not attached to the scenario.");
+               }
+
+               // Remove the scenario from the current hibernate session.
+               ht.evict(aScenario);
+               // Check that the scenario is created in the database.
+               Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
+               Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
+               Assert.assertTrue(aScen.getDocums().size() > 0,
+                               "No publications in the scenario.");
+
+               Assert.assertTrue(i > 0,
+                               "More then one document must be in the database");
+
+               // Check created uses relations
+               Assert
+                               .assertTrue(usedMap.size() > 0,
+                                               "Uses relations must be created.");
+               boolean foundAny = false;
+               for (Long usingId : usedMap.keySet()) {
+                       for (Publication pub : aScen.getDocums()) {
+                               if (pub.getIndex() == usingId) {
+                                       boolean found = false;
+                                       for (Publication used : aScen.getDocums()) {
+                                               found = (used.getIndex() == usedMap.get(usingId));
+                                               if (found) {
+                                                       break;
+                                               }
+                                       }
+                                       if (!found) {
+                                               for (Publication used : aStudy.getDocums()) {
+                                                       found = (used.getIndex() == usedMap.get(usingId));
+                                                       if (found) {
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       Assert.assertTrue(found,
+                                                       "Uses relation was not created in the database.");
+                                       foundAny = foundAny || found;
+                               }
+                       }
+               }
+               Assert.assertTrue(foundAny,
+                               "No Uses relation was created in the database.");
+
+               return aScenario.getOwnerStudy();
+       }
+
+       /**
+        * Create a document published in the scenario. <BR>
+        * document:<BR>
+        * document type - type used on the step <BR>
+        * &lt;source-file&gt;.brep <BR>
+        * &lt;attached-file&gt;.med
+        * 
+        * @param aScenario
+        *            the scenario to add the document to
+        * @param aScStep
+        *            scenario step where the document to be published
+        * @param dprop
+        *            document properties
+        * @param attachedFileExt
+        *            extension of the secon attached (exported) file
+        * @param isOutdated
+        *            outdated document flag
+        * @return the publication of the created document
+        * @throws IOException
+        * @throws MultiplyDefinedException
+        * @throws InvalidPropertyException
+        * @throws MissedPropertyException
+        */
+       private Publication createDoc(final ProjectElement aScenario,
+                       final org.splat.som.Step aScStep, final Properties dprop,
+                       final String attachedFileExt, final boolean isOutdated)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException {
+               // Create a document published in the scenario
+               // document<i>: document type - type used on the step
+               // <source-file>.brep
+               // <attached-file>.med
+               Publication pub = _stepService.createDocument(aScStep, dprop);
+               Assert.assertNotNull(pub.getOwner(),
+                               "The publication must be attached to the scenario.");
+               Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
+                               "The publication was not attached to the scenario.");
+
+               if (isOutdated) {
+                       pub.setIsnew('O');
+               }
+               aScenario.add(pub);
+               HibernateTemplate ht = getHibernateTemplate();
+               ht.saveOrUpdate(pub);
+
+               // Attach a file
+               ht.save(pub.value());
+               ht.flush();
+               ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
+
+               return pub;
+       }
+
+       /**
+        * Test of generating a study document index.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to generate the next document index.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's read method for an existing id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>The new index must be equal to the incremented old one and saved into the database<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        *             if test study creation is failed
+        * @throws IOException
+        *             if test study creation is failed
+        * 
+        */
+       @Test
+       public void testGenerateLocalIndex() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testGenerateLocalIndex()");
+               startNestedTransaction();
+
+               HibernateTemplate ht = getHibernateTemplate();
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = aStudy.getIndex();
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               // Call DAO's get method for an existing id.
+               _studyDAO.flush();
+               getHibernateTemplate().evict(aStudy);
+               getHibernateTemplate().clear();
+               Study aStudyFound = _studyDAO.get(id);
+
+               int oldInd = aStudyFound.getLastLocalIndex();
+               int ind = _studyService.generateLocalIndex(aStudyFound);
+
+               _studyDAO.flush();
+               Assert.assertEquals(ind, oldInd + 1, "Index must be incremented.");
+               Assert.assertEquals(ind, aStudyFound.getLastLocalIndex(),
+                               "Index must be incremented.");
+               Assert.assertEquals(ind, ht.get(Study.class, aStudyFound.getIndex())
+                               .getLastLocalIndex(),
+                               "Incremented index must be saved in the database.");
+               aStudy = (Study)ht.find(
+                               "from Study where rid = " + aStudyFound.getIndex()).get(0);
+               Assert.assertEquals(ind, aStudy.getLastLocalIndex(),
+                               "Incremented index must be saved in the database.");
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testGenerateLocalIndex()");
+       }
+}