Salome HOME
The draft of the "Copy from existing study" action is added. The YACS step is introdu...
authorrkv <rkv@opencascade.com>
Thu, 21 Mar 2013 12:45:52 +0000 (12:45 +0000)
committerrkv <rkv@opencascade.com>
Thu, 21 Mar 2013 12:45:52 +0000 (12:45 +0000)
41 files changed:
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Any.java
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycle.java
Workspace/Siman-Common/src/org/splat/dal/dao/kernel/AbstractGenericDAOImpl.java
Workspace/Siman-Common/src/org/splat/dal/dao/kernel/GenericDAO.java
Workspace/Siman-Common/src/org/splat/log/AppLogger.java
Workspace/Siman-Common/src/org/splat/service/ProjectElementService.java
Workspace/Siman-Common/src/org/splat/service/ProjectElementServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/ScenarioService.java
Workspace/Siman-Common/src/org/splat/service/ScenarioServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java
Workspace/Siman-Common/src/org/splat/service/dto/ScenarioDTO.java [new file with mode: 0644]
Workspace/Siman-Common/src/org/splat/service/technical/StepsConfigService.java
Workspace/Siman-Common/src/org/splat/service/technical/StepsConfigServiceImpl.java
Workspace/Siman-Common/src/org/splat/util/IOUtils.java [new file with mode: 0644]
Workspace/Siman-Common/src/spring/businessServiceContext.xml
Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java
Workspace/Siman-Common/src/test/splat/service/TestStepsConfigService.java [new file with mode: 0644]
Workspace/Siman-Common/src/test/splat/util/TestEntitiesGenerator.java
Workspace/Siman/WebContent/WEB-INF/tiles/tiles-defs.xml
Workspace/Siman/WebContent/conf/som.xml
Workspace/Siman/WebContent/skin/icon.schema.png [new file with mode: 0644]
Workspace/Siman/WebContent/study/copyStudy.jsp [new file with mode: 0644]
Workspace/Siman/src/org/splat/simer/Action.java
Workspace/Siman/src/org/splat/simer/ApplicationSettings.java
Workspace/Siman/src/org/splat/simer/CopyStudyAction.java [new file with mode: 0644]
Workspace/Siman/src/org/splat/simer/DocumentFacade.java
Workspace/Siman/src/org/splat/simer/ImportDocumentAction.java
Workspace/Siman/src/org/splat/simer/NewScenarioAction.java
Workspace/Siman/src/org/splat/simer/NewStudyAction.java
Workspace/Siman/src/som.properties
Workspace/Siman/src/som_en.properties
Workspace/Siman/src/spring/applicationContext.xml
Workspace/Siman/src/struts.xml

index c84935c09a2ef227b0d3e07d9174097d38acfeb4..e131b6a62a32a8ff58b418397112133f3284c303 100644 (file)
@@ -1,4 +1,5 @@
 package org.splat.dal.bo.kernel;
+
 /**
  * Abstract root class of persistent objects supporting dynamic attributes.<br/>
  * Dynamic attributes are instances of concrete subclasses of Attribute that are assigned to Any objects at run time.
@@ -18,72 +19,110 @@ import org.splat.kernel.MissedPropertyException;
 import org.splat.kernel.MultiplyDefinedException;
 import org.splat.kernel.ObjectProperties;
 
-
 public abstract class Any extends Persistent {
 
-    private  Set<Attribute> attributes = new HashSet<Attribute>();
-
-//  ==============================================================================================================================
-//  Constructors
-//  ==============================================================================================================================
-
-//  Database fetch constructor.
-    protected Any () {
-    }
-//  Initialization constructors
-    protected Any (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-//  --------------------------------------
-      super(oprop);
-    }
-    protected Any (Attribute... field) {
-      for (int i=0; i<field.length; i++) {
-       if (field[i] == null) continue;     // Happen when newing an Any object without property 
-        if (field[i].getFrom().equals(this)) getAttributes().add(field[i]);
-      }
-    }
-
-//  ==============================================================================================================================
-//  Public member functions
-//  ==============================================================================================================================
-
-    public Attribute getAttribute (Class<? extends Attribute> type) {
-      for (Iterator<Attribute> i=getAttributes().iterator(); i.hasNext(); ) {
-       Attribute field = i.next();
-        if (field.getClass().equals(type)) return field;
-      }
-      return null;
-    }
-
-//  ==============================================================================================================================
-//  Protected services
-//  ==============================================================================================================================
-
-    public boolean removeAttribute (Attribute field) {
-      for (Iterator<Attribute> i=getAttributes().iterator(); i.hasNext(); ) {
-        if (!i.next().equals(field)) continue;
-       i.remove();
-       return true;
-      }
-      return false;
-    }
-
-    public boolean setAttribute (Attribute field) {
-      Class<?> type    = field.getClass();
-
-      if (!field.getFrom().equals(this)) return false;
-      for (Iterator<Attribute> i=getAttributes().iterator(); i.hasNext(); ) {
-        if (!i.next().getClass().equals(type)) continue;
-        i.remove();
-       break;
-      }
-      getAttributes().add(field);
-      return true;
-    }
+       private final Set<Attribute> attributes = new HashSet<Attribute>();
+
+       // ==============================================================================================================================
+       // Constructors
+       // ==============================================================================================================================
+
+       // Database fetch constructor.
+       protected Any() {
+               super();
+       }
+
+       // Initialization constructors
+       protected Any(final ObjectProperties oprop) throws MissedPropertyException,
+                       InvalidPropertyException, MultiplyDefinedException {
+               // --------------------------------------
+               super(oprop);
+       }
+
+       protected Any(final Attribute... field) {
+               for (int i = 0; i < field.length; i++) {
+                       if (field[i] == null) {
+                               continue; // Happen when newing an Any object without property
+                       }
+                       if (field[i].getFrom().equals(this)) {
+                               getAttributes().add(field[i]);
+                       }
+               }
+       }
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       public Attribute getAttribute(final Class<? extends Attribute> type) {
+               Attribute found = null;
+               for (Attribute field : getAttributes()) {
+                       if (field.getClass().equals(type)) {
+                               found = field;
+                               break;
+                       }
+               }
+               return found;
+       }
+
+       // ==============================================================================================================================
+       // Protected services
+       // ==============================================================================================================================
+
+       public boolean removeAttribute(final Attribute field) {
+               boolean res = false;
+               for (Iterator<Attribute> i = getAttributes().iterator(); i.hasNext();) {
+                       if (i.next().equals(field)) {
+                               i.remove();
+                               res = true;
+                               break;
+                       }
+               }
+               return res;
+       }
+
+       public boolean setAttribute(final Attribute field) {
+               Class<?> type = field.getClass();
+
+               if (!field.getFrom().equals(this)) {
+                       return false;
+               }
+               for (Iterator<Attribute> i = getAttributes().iterator(); i.hasNext();) {
+                       if (i.next().getClass().equals(type)) {
+                               i.remove();
+                               break;
+                       }
+               }
+               getAttributes().add(field);
+               return true;
+       }
+
        /**
         * Get the attributes.
+        * 
         * @return the attributes
         */
        protected Set<Attribute> getAttributes() {
                return attributes;
        }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.kernel.Persistent#evict()
+        */
+       @Override
+       public void evict() {
+               super.evict();
+               // Evict all attributes of the persistent object
+               Set<Attribute> tmpSet = new HashSet<Attribute>();
+               tmpSet.addAll(attributes);
+               attributes.clear();
+               for (Attribute field : tmpSet) {
+                       if (field.isSaved()) { // to avoid recursive evict
+                               field.evict();
+                       }
+                       attributes.add(field);
+               }
+       }
 }
\ No newline at end of file
index debc3f65f035398ea672c1a0cf1ec15dbf12b946..152661bc642929db34eef58389235ef648fce473 100644 (file)
@@ -169,8 +169,7 @@ public abstract class Entity extends Any {
                }
                if (res != null) {
                        if (LOG.isDebugEnabled()) {
-                               LOG.debug("Contains: "
-                                               + this.getAllRelations().contains(res));
+                               LOG.debug("Contains: " + this.getAllRelations().contains(res));
                                LOG.debug("Nb relations of this before: "
                                                + this.getAllRelations().size());
                        }
@@ -183,15 +182,37 @@ public abstract class Entity extends Any {
                        if (res.isBidirectional()) {
                                if (LOG.isDebugEnabled()) {
                                        LOG.debug("Nb relations of reverse before: "
-                                                       + ((Entity)res.getTo()).getAllRelations().size());
+                                                       + ((Entity) res.getTo()).getAllRelations().size());
                                }
-                               ((Entity)res.getTo()).getAllRelations().remove(res.getReverse());
+                               ((Entity) res.getTo()).getAllRelations().remove(
+                                               res.getReverse());
                                if (LOG.isDebugEnabled()) {
                                        LOG.debug("Nb relations of reverse after: "
-                                                       + ((Entity)res.getTo()).getAllRelations().size());
+                                                       + ((Entity) res.getTo()).getAllRelations().size());
                                }
                        }
                }
                return res;
        }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.kernel.Any#evict()
+        */
+       @Override
+       public void evict() {
+               super.evict();
+               // Evict all attributes of the persistent object
+               Set<Relation> tmpSet = new HashSet<Relation>();
+               tmpSet.addAll(relations);
+               relations.clear();
+               // Evict relations
+               for (Relation rel : tmpSet) {
+                       if (rel.isSaved()) { // to avoid recursive evict
+                               rel.evict();
+                       }
+                       relations.add(rel);
+               }
+       }
 }
\ No newline at end of file
index 1f95b0dd4aa0e99914f3b959a4657c4f62c66b27..b710fb0a8756856c8d2bf990a1e2366af5b43078 100644 (file)
@@ -46,7 +46,10 @@ public abstract class Persistent {
        private String _uid = IdGenerator.createId();
 
        protected abstract static class Properties implements ObjectProperties {
-               private long rid; // Primary key of persistent objects
+               /**
+                * Primary key of the persistent objects.
+                */
+               private long rid;
 
                private boolean tobechecked = true; // Property validity check flag
 
@@ -109,6 +112,15 @@ public abstract class Persistent {
        // Public member functions
        // ==============================================================================================================================
 
+       /**
+        * Generate new GUID for this object. Must be called when this object is <BR>
+        * intended to be copied as another new persistent object. 
+        */
+       public void evict() {
+               _uid = IdGenerator.createId();
+               rid = 0;
+       }
+
        /**
         * Persistent objects are equal if their UIDs are equal.<BR>
         * {@inheritDoc}
index 62d1e876af8c1c2a65594b35d5408de1abc2275f..296b860f84df8754ce67407383d3e21687a331ea 100644 (file)
@@ -8,6 +8,7 @@ package org.splat.dal.bo.som;
 
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -180,8 +181,8 @@ public abstract class ProjectElement extends Entity {
        public boolean publishes(final Document doc) {
                boolean res = false;
                long index = doc.getIndex();
-               for (Iterator<Publication> i = docums.iterator(); i.hasNext();) {
-                       Document found = i.next().value();
+               for (Publication pub : docums) {
+                       Document found = pub.value();
                        res = (found.getIndex() == index);
                        if (res) {
                                break;
@@ -261,4 +262,25 @@ public abstract class ProjectElement extends Entity {
         * @return the project element study
         */
        public abstract Study getOwnerStudy();
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.kernel.Entity#evict()
+        */
+       @Override
+       public void evict() {
+               super.evict();
+               // Evict all attributes of the persistent object
+               Set<Publication> tmpSet = new HashSet<Publication>();
+               tmpSet.addAll(docums);
+               docums.clear();
+               // Evict publications
+               for (Publication rel : tmpSet) {
+                       if (rel.isSaved()) { // to avoid recursive evict
+                               rel.evict();
+                       }
+                       docums.add(rel);
+               }
+       }
 }
\ No newline at end of file
index a78f1daf92e68577ec529c56229413134ecda8a4..d91597245ad7f0d4a00f432c68007eb5cd4c03c2 100644 (file)
@@ -13,7 +13,7 @@
 <!-- Publication properties
   -->
     <!-- Document       mydoc -->    
-    <many-to-one  name="mydoc" column="doc" cascade="merge"  access="field" not-null="true"/>
+    <many-to-one  name="mydoc" column="doc" cascade="merge,evict"  access="field" not-null="true"/>
     
     <!-- ProjectElement owner -->    
     <many-to-one  name="owner" column="owner" cascade="merge" access="field" not-null="true" />
index 63da57aeb0014d31e7e8d30cf77304ea7145dfe5..cc0160f7d68ef4c23ec194a47ac5ba810ceec8b2 100644 (file)
@@ -233,4 +233,18 @@ public class Publication extends Persistent {
        public void setValue(final Document aDoc) {
                this.mydoc = aDoc;
        }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.dal.bo.kernel.Persistent#evict()
+        */
+       @Override
+       public void evict() {
+               super.evict();
+               // Evict the document
+               if (value() != null) {
+                       value().evict();
+               }
+       }
 }
\ No newline at end of file
index 9d07158f9c6b3788f19be0b792a03b732dc32df3..e9d2b570024e23bdd69f8aeac71315d4d5db68a5 100644 (file)
 <!-- Uses relation: Document to Document
   -->
     <union-subclass name="org.splat.dal.bo.som.UsesRelation" extends="org.splat.dal.bo.kernel.Relation" table="uses_rel">
-               <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
+               <many-to-one cascade="merge,evict" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- UsedBy relation: Document to Document
   -->
     <union-subclass name="org.splat.dal.bo.som.UsedByRelation" extends="org.splat.dal.bo.kernel.Relation" table="usedby_rel">
-               <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
+               <many-to-one cascade="merge,evict" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Versions relation: Document to Document
   -->
     <union-subclass name="org.splat.dal.bo.som.VersionsRelation" extends="org.splat.dal.bo.kernel.Relation" table="versions_rel">
-        <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
+        <many-to-one cascade="merge,evict" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Converts relation: Document to File
index be38e6a5bd0ca976f22c7f36c8c22f61da4248ea..228a424921d764412f5a737cb74601c6062a52d1 100644 (file)
@@ -31,7 +31,7 @@
       <property name="visibility" type="Visibility" column="area" access="field" not-null="true" />    
   
       <!-- List<Scenario> scenarii     -->    
-      <list name="scenarii" lazy="false" cascade="merge,delete-orphan" access="field">
+      <list name="scenarii" lazy="false" cascade="merge,delete-orphan,evict" access="field">
         <key         column="owner" not-null="true" />
         <list-index  column="scendex"/>
         <one-to-many class="org.splat.dal.bo.som.Scenario" />
index 60af1dfba3e1a6961c702ba606c446229def446a..fd304905db36ea0d19d096e2116b8f634003085d 100644 (file)
@@ -476,4 +476,23 @@ public class Study extends ProjectElement {
                this.markreference = markreference;
        }
        
+       /** 
+        * {@inheritDoc}
+        * @see org.splat.dal.bo.som.ProjectElement#evict()
+        */
+       @Override
+       public void evict() {
+               super.evict();
+               // Evict all attributes of the persistent object
+               Set<Scenario> tmpSet = new HashSet<Scenario>();
+               tmpSet.addAll(scenarii);
+               scenarii.clear();
+               // Evict publications
+               for (Scenario rel : tmpSet) {
+                       if (rel.isSaved()) { // to avoid recursive evict
+                               rel.evict();
+                       }
+                       scenarii.add(rel);
+               }
+       }
 }
\ No newline at end of file
index 072130a233394b6deef911728410c8e6b78422e3..5c67d1e10f03e2c8ecc8ddafdf15223e918257a6 100644 (file)
@@ -141,14 +141,29 @@ public class ValidationCycle extends Persistent {
     public ValidationCycle () {
     }
     public ValidationCycle (final Study from, final Properties vprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-      super(vprop);                  // Throws one of the above exception if not valid
-      mytype    = vprop.doctype;
-      publisher = vprop.publisher;   // May be null
-      reviewer  = vprop.reviewer;    // May be null
-      approver  = vprop.approver;    // May be null
-      signatory = vprop.signatory;   // May be null
-      context   = new ValidationCycleRelation(from, this);
-    }
+        super(vprop);                  // Throws one of the above exception if not valid
+        mytype    = vprop.doctype;
+        publisher = vprop.publisher;   // May be null
+        reviewer  = vprop.reviewer;    // May be null
+        approver  = vprop.approver;    // May be null
+        signatory = vprop.signatory;   // May be null
+        context   = new ValidationCycleRelation(from, this);
+      }
+
+    /**
+     * Create a copy of the given cycle for the given study.
+     * @param study the owner study
+     * @param src the original validation cycle
+     */
+    public ValidationCycle (final Study study, final ValidationCycle src) {
+        super();                  // Throws one of the above exception if not valid
+        mytype    = src.getDocumentType();
+        publisher = src.publisher;   // May be null
+        reviewer  = src.reviewer;    // May be null
+        approver  = src.approver;    // May be null
+        signatory = src.signatory;   // May be null
+        context   = new ValidationCycleRelation(study, this);
+      }
 
 //  ==============================================================================================================================
 //  Public member functions
index 64996b4234c6b3d042390bb9c30ec18b079bc615..393c124a2fa8bcecb9fd720f7610a3ec80d8e0f3 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Properties;
 
 import org.hibernate.Criteria;
 import org.hibernate.LockOptions;
+import org.hibernate.Session;
 import org.hibernate.criterion.Criterion;
 import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Order;
@@ -44,6 +45,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         * @param newInstance
         *            new object as a transient instance
         * @return new primary key for the created persistent object
+        * @see Session#save(Object)
         */
        @SuppressWarnings(UNCHECKED)
        public PK create(final T newInstance) {
@@ -55,6 +57,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         * 
         * @param newInstance
         *            new object as a transient instance
+        * @see Session#saveOrUpdate(Object)
         */
        @SuppressWarnings(UNCHECKED)
        public void saveOrUpdate(final T newInstance) {
@@ -67,6 +70,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         * @param id
         *            primary key of an object to read
         * @return an object found by the given key
+        * @see Session#get(Class, Serializable)
         */
        @SuppressWarnings(UNCHECKED)
        public T get(final PK id) {
@@ -142,6 +146,21 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
                return aDetachedCriteria.getExecutableCriteria(getSession()).list();
        }
 
+       /**
+        * Retrieve a list of DTO objects using the given criteria.
+        * 
+        * @param <DTO>
+        *            the class of returned DTOs
+        * @param aDetachedCriteria
+        *            search criteria
+        * @return a list of DTO objects filtered according to the given criteria
+        */
+       @SuppressWarnings(UNCHECKED)
+       public <DTO> List<DTO> getFilteredDTOList(
+                       final DetachedCriteria aDetachedCriteria) {
+               return aDetachedCriteria.getExecutableCriteria(getSession()).list();
+       }
+
        /**
         * Retrieve a list of objects which were previously persisted to the database using the given criteria.
         * 
@@ -260,6 +279,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         * 
         * @param transientObject
         *            transient instance of the object to refresh
+        * @see Session#refresh(Object)
         */
        public void refresh(final T transientObject) {
                getSession().refresh(transientObject);
@@ -272,6 +292,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         *            transient instance of the object to load
         * @param id
         *            object primary key
+        * @see Session#load(Object, Serializable)
         */
        public void load(final T transientObject, final PK id) {
                getSession().load(transientObject, id);
@@ -284,6 +305,7 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         *            transient instance of the object to lock
         * @param lockOptions
         *            lock options
+        * @see Session#refresh(Object, LockOptions)
         */
        public void refresh(final T transientObject, final LockOptions lockOptions) {
                getSession().refresh(transientObject, lockOptions);
@@ -294,35 +316,61 @@ public abstract class AbstractGenericDAOImpl<T, PK extends Serializable>
         * 
         * @param persistentObject
         *            a persistent object to delete from the database
+        * @see Session#delete(Object)
         */
        public void delete(final T persistentObject) {
                getSession().delete(persistentObject);
        }
 
        /**
-        * Makes detached object persistent.
+        * Make a transient instance persistent. This operation cascades to <BR>
+        * associated instances if the association is mapped with cascade="persist".
         * 
         * @param transientObject
         *            transient instance of the object to be made persistent
+        * @see Session#persist(Object)
         */
        public void persist(final T transientObject) {
                getSession().persist(transientObject);
        }
 
        /**
-        * Merge detached object with persistent data.
+        * Copy the state of the given object onto the persistent object with the <BR>
+        * same identifier. If there is no persistent instance currently associated<BR>
+        * with the session, it will be loaded. Return the persistent instance. If <BR>
+        * the given instance is unsaved, save a copy of and return it as a newly <BR>
+        * persistent instance. The given instance does not become associated with <BR>
+        * the session. This operation cascades to associated instances if the <BR>
+        * association is mapped with cascade="merge".
         * 
         * @param transientObject
         *            transient instance of the object to be merged with persistent data
         * @return merged persistent object
+        * @see Session#merge(Object)
         */
        @SuppressWarnings(UNCHECKED)
        public T merge(final T transientObject) {
                return (T) getSession().merge(transientObject);
        }
 
+       /**
+        * Remove this instance from the session cache. Changes to the instance will<BR>
+        * not be synchronized with the database. This operation cascades to <BR>
+        * associated instances if the association is mapped with cascade="evict".
+        * 
+        * @param persistentObject
+        *            the object to be removed from session cache
+        * @see Session#evict(Object)
+        */
+       @SuppressWarnings(UNCHECKED)
+       public void evict(final T persistentObject) {
+               getSession().evict(persistentObject);
+       }
+
        /**
         * Synchronize the session data with the database.
+        * 
+        * @see Session#flush()
         */
        public void flush() {
                getSession().flush();
index b4a5b9f6cb0a3e9e2292f2f115dc874770b7cdb8..09ea36e505af76f9da7d9183d3af75d65de47a92 100644 (file)
@@ -14,6 +14,7 @@ import java.util.List;
 import java.util.Properties;
 
 import org.hibernate.LockOptions;
+import org.hibernate.Session;
 import org.hibernate.criterion.Criterion;
 import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Order;
@@ -36,6 +37,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         * @param newInstance
         *            new object as a transient instance
         * @return new primary key for the created persistent object
+        * @see Session#save(Object)
         */
        PK create(T newInstance);
 
@@ -44,6 +46,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         * 
         * @param newInstance
         *            new object as a transient instance
+        * @see Session#saveOrUpdate(Object)
         */
        public void saveOrUpdate(final T newInstance);
 
@@ -53,6 +56,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         * @param id
         *            primary key of an object to read
         * @return an object found by the given key
+        * @see Session#get(Class, Serializable)
         */
        T get(PK id);
 
@@ -69,6 +73,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         * 
         * @param transientObject
         *            transient instance of the object to refresh
+        * @see Session#refresh(Object)
         */
        void refresh(T transientObject);
 
@@ -79,6 +84,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         *            transient instance of the object to load
         * @param id
         *            object primary key
+        * @see Session#load(Object, Serializable)
         */
        public void load(final T transientObject, final PK id);
 
@@ -89,6 +95,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         *            transient instance of the object to lock
         * @param lockOptions
         *            lock options
+        * @see Session#refresh(Object, LockOptions)
         */
        public void refresh(final T transientObject, final LockOptions lockOptions);
 
@@ -97,6 +104,7 @@ public interface GenericDAO<T, PK extends Serializable> {
         * 
         * @param persistentObject
         *            a persistent object to delete from the database
+        * @see Session#delete(Object)
         */
        void delete(T persistentObject);
 
@@ -143,6 +151,18 @@ public interface GenericDAO<T, PK extends Serializable> {
         */
        public List<T> getFilteredList(final DetachedCriteria aDetachedCriteria);
 
+       /**
+        * Retrieve a list of DTO objects using the given criteria.
+        * 
+        * @param <DTO>
+        *            the class of returned DTOs
+        * @param aDetachedCriteria
+        *            search criteria
+        * @return a list of DTO objects filtered according to the given criteria
+        */
+       public <DTO> List<DTO> getFilteredDTOList(
+                       final DetachedCriteria aDetachedCriteria);
+
        /**
         * Retrieve a list of objects which were previously persisted to the database using the given criteria.
         * 
@@ -220,24 +240,46 @@ public interface GenericDAO<T, PK extends Serializable> {
        public List<T> getFilteredList(Properties andParams, Order... anOrder);
 
        /**
-        * Makes detached object persistent.
+        * Make a transient instance persistent. This operation cascades to <BR>
+        * associated instances if the association is mapped with cascade="persist".
         * 
         * @param transientObject
         *            transient instance of the object to be made persistent
+        * @see Session#persist(Object)
         */
        public void persist(T transientObject);
 
        /**
-        * Merge detached object with persistent data.
+        * Copy the state of the given object onto the persistent object with the <BR>
+        * same identifier. If there is no persistent instance currently associated<BR>
+        * with the session, it will be loaded. Return the persistent instance. If <BR>
+        * the given instance is unsaved, save a copy of and return it as a newly <BR>
+        * persistent instance. The given instance does not become associated with <BR>
+        * the session. This operation cascades to associated instances if the <BR>
+        * association is mapped with cascade="merge".
         * 
         * @param transientObject
         *            transient instance of the object to be merged with persistent data
         * @return merged persistent object
+        * @see Session#merge(Object)
         */
        public T merge(T transientObject);
 
+       /**
+        * Remove this instance from the session cache. Changes to the instance will<BR>
+        * not be synchronized with the database. This operation cascades to <BR>
+        * associated instances if the association is mapped with cascade="evict".
+        * 
+        * @param persistentObject
+        *            the object to be removed from session cache
+        * @see Session#evict(Object)
+        */
+       public void evict(final T persistentObject);
+
        /**
         * Synchronize the session data with the database.
+        * 
+        * @see Session#flush()
         */
        public void flush();
 }
index ec9bbd3887b5f9ed70092b77aed23fd5f087db8c..d8952c4a08113d9322946416a3c905b7e714d752 100644 (file)
@@ -208,6 +208,33 @@ public class AppLogger {
                _logger.info(formatMessage(code, context), exception);
        }
 
+       /**
+        * Allows to check if INFO logging level is enabled.
+        * 
+        * @return <b>true</b> if INFO logging level is enabled and <b>false</b> otherwise 
+        */
+       public boolean isInfoEnabled() {
+               return _logger.isInfoEnabled();
+       }
+
+       /**
+        * Allows to check if ERROR logging level is enabled.
+        * 
+        * @return <b>true</b> if ERROR logging level is enabled and <b>false</b> otherwise 
+        */
+       public boolean isErrorEnabled() {
+               return _logger.isErrorEnabled();
+       }
+
+       /**
+        * Allows to check if WARN logging level is enabled.
+        * 
+        * @return <b>true</b> if WARN logging level is enabled and <b>false</b> otherwise 
+        */
+       public boolean isWarnEnabled() {
+               return _logger.isWarnEnabled();
+       }
+
        // Debug
 
        /**
index 81792bbc6c231a197e6e163897a7fb842681f71f..722703166f56dca8cb77704281423163f2050add 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.splat.service;
 
+import java.util.Map;
+
 import org.splat.dal.bo.som.ProjectElement;
 import org.splat.som.Step;
 
@@ -38,6 +40,15 @@ public interface ProjectElementService {
         */
        Step[] getSteps(ProjectElement elem);
 
+       /**
+        * Get map of steps numbers to steps for the given project element.
+        * 
+        * @param elem
+        *            the project element
+        * @return map of steps numbers to steps
+        */
+       public Map<Integer, Step> getStepsMap(final ProjectElement elem);
+
        /**
         * Refreshes the internal data potentially out-of-date. This function needs to be called when Publication objects are added to this
         * Project Element before being saved. The reason is, as saving a persistent object changes its hashcode, hashed data need to be rebuilt
index fda1d9d75db5d34258e965ec86253e621b7a5bd8..d01bdd6d7b42e89825aae00a12847a4440e0aefc 100644 (file)
@@ -9,8 +9,10 @@
 
 package org.splat.service;
 
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import org.splat.dal.bo.som.ProjectElement;
 import org.splat.dal.bo.som.Publication;
@@ -70,15 +72,30 @@ public class ProjectElementServiceImpl implements ProjectElementService {
                return elem.getFolders(); // No protection against this object corruption as it would not corrupt the database
        }
 
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ProjectElementService#getStepsMap(org.splat.dal.bo.som.ProjectElement)
+        */
+       public Map<Integer, Step> getStepsMap(final ProjectElement elem) {
+               Step[] steps = getSteps(elem);
+               Map<Integer, Step> res = new HashMap<Integer, Step>();
+               for (Step step : steps) {
+                       res.put(step.getNumber(), step);
+               }
+               return res;
+       }
+
        /**
         * Refreshes the internal data potentially out-of-date. This function needs to be called when Publication objects are added to this
         * Project Element before being saved. The reason is, as saving a persistent object changes its hashcode, hashed data need to be rebuilt
         * after saving for making functions based on this hashcode such as remove(), working.
-        * @param elem the project element to refresh
+        * 
+        * @param elem
+        *            the project element to refresh
         */
        @Transactional
        public void refresh(final ProjectElement elem) {
-               // -------------------------
                Publication[] curdoc = elem.getDocums().toArray(
                                new Publication[elem.getDocums().size()]);
 
@@ -106,12 +123,14 @@ public class ProjectElementServiceImpl implements ProjectElementService {
         * @param stepsConfigService
         *            steps config service
         */
-       public void setStepsConfigService(final StepsConfigService stepsConfigService) {
+       public void setStepsConfigService(
+                       final StepsConfigService stepsConfigService) {
                _stepsConfigService = stepsConfigService;
        }
 
        /**
         * Get the projectElementDAO.
+        * 
         * @return the projectElementDAO
         */
        public ProjectElementDAO getProjectElementDAO() {
@@ -120,7 +139,9 @@ public class ProjectElementServiceImpl implements ProjectElementService {
 
        /**
         * Set the projectElementDAO.
-        * @param projectElementDAO the projectElementDAO to set
+        * 
+        * @param projectElementDAO
+        *            the projectElementDAO to set
         */
        public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
                _projectElementDAO = projectElementDAO;
index 58a1bbb6ff4ca048025fbcb112d4f0a6a27a0a6c..4012fa94c87daa0a140827ec088fb78ce965697e 100644 (file)
@@ -17,11 +17,13 @@ import org.splat.dal.bo.som.KnowledgeElement;
 import org.splat.dal.bo.som.Scenario;
 import org.splat.dal.bo.som.SimulationContext;
 import org.splat.dal.bo.som.Study;
+import org.splat.exception.InvalidParameterException;
 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.service.dto.ScenarioDTO;
 import org.splat.service.dto.StepDTO;
 import org.splat.som.Step;
 
@@ -32,6 +34,45 @@ import org.splat.som.Step;
  */
 public interface ScenarioService {
 
+       /**
+        * Get a list of scenarios of a study with the given id.
+        * 
+        * @param studyId
+        *            the study id
+        * @return list of scenario DTOs
+        */
+       public List<ScenarioDTO> getStudyScenarios(final Long studyId);
+
+       /**
+        * Copy content of a source study into the given study up to the given step.
+        * 
+        * @param fromStudyId
+        *            the source study id
+        * @param fromScenId
+        *            the source scenario id
+        * @param finalStepNum
+        *            the final source step number
+        * @param toStudyId
+        *            the target study
+        * @throws InvalidParameterException
+        *             if study, scenario or step is not found
+        * @throws MissedPropertyException
+        *             if document creation is failed
+        * @throws InvalidPropertyException
+        *             if document creation is failed
+        * @throws MultiplyDefinedException
+        *             if document creation is failed
+        * @throws IOException
+        *             if document file creation is failed
+        * @throws NotApplicableException
+        *             if document state is not applicable
+        */
+       public void copyStudyContent(final long fromStudyId, final long fromScenId,
+                       final int finalStepNum, final long toStudyId)
+                       throws InvalidParameterException, MissedPropertyException,
+                       InvalidPropertyException, MultiplyDefinedException,
+                       NotApplicableException, IOException;
+
        /**
         * Get lists of scenario steps, documents and files for building siman-salome.conf file.
         * 
index b47c01fdbe777e04c5ee0c2fca4c9791eb3a1570..9340c5c31d35a2e236e859ffeb660b36c0dc1186 100644 (file)
@@ -19,8 +19,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
+import org.hibernate.transform.Transformers;
 import org.splat.common.properties.MessageKeyEnum;
 import org.splat.dal.bo.kernel.Relation;
 import org.splat.dal.bo.kernel.Role;
@@ -32,6 +35,7 @@ import org.splat.dal.bo.som.File;
 import org.splat.dal.bo.som.KnowledgeElement;
 import org.splat.dal.bo.som.KnowledgeElementType;
 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.SimulationContext;
@@ -39,6 +43,7 @@ import org.splat.dal.bo.som.SimulationContextType;
 import org.splat.dal.bo.som.Study;
 import org.splat.dal.bo.som.UsedByRelation;
 import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.bo.som.ValidationCycle;
 import org.splat.dal.bo.som.Document.Properties;
 import org.splat.dal.dao.kernel.RoleDAO;
 import org.splat.dal.dao.kernel.UserDAO;
@@ -46,6 +51,8 @@ import org.splat.dal.dao.som.KnowledgeElementDAO;
 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
 import org.splat.dal.dao.som.ScenarioDAO;
 import org.splat.dal.dao.som.StudyDAO;
+import org.splat.dal.dao.som.ValidationCycleDAO;
+import org.splat.exception.InvalidParameterException;
 import org.splat.i18n.I18nUtils;
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MismatchException;
@@ -55,11 +62,14 @@ import org.splat.kernel.NotApplicableException;
 import org.splat.log.AppLogger;
 import org.splat.service.dto.DocumentDTO;
 import org.splat.service.dto.FileDTO;
+import org.splat.service.dto.ScenarioDTO;
 import org.splat.service.dto.StepDTO;
 import org.splat.service.technical.IndexService;
 import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.StepsConfigService;
 import org.splat.som.Step;
 import org.splat.util.BeanHelper;
+import org.splat.util.IOUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -75,6 +85,10 @@ public class ScenarioServiceImpl implements ScenarioService {
        public final static AppLogger LOG = AppLogger
                        .getLogger(ScenarioServiceImpl.class);
 
+       /**
+        * " to " literal.
+        */
+       private static final String TO = " to ";
        /**
         * Injected index service.
         */
@@ -154,6 +168,16 @@ public class ScenarioServiceImpl implements ScenarioService {
         */
        private DocumentTypeService _documentTypeService;
 
+       /**
+        * Injected validation cycle DAO.
+        */
+       private ValidationCycleDAO _validationCycleDAO;
+
+       /**
+        * Injected project settings service.
+        */
+       private StepsConfigService _stepsConfigService;
+
        /**
         * Get the projectElementService.
         * 
@@ -213,6 +237,216 @@ public class ScenarioServiceImpl implements ScenarioService {
                _stepService = stepService;
        }
 
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ScenarioService#getStudyScenarios(java.lang.Long)
+        */
+       @Override
+       @Transactional(readOnly = true)
+       public List<ScenarioDTO> getStudyScenarios(final Long studyId) {
+               DetachedCriteria query = DetachedCriteria
+                               .forClass(Scenario.class, "scen")
+                               .add(Restrictions.eq("owner.rid", studyId))
+                               .setProjection(
+                                               Projections.projectionList().add(
+                                                               Projections.property("scen.title"), "title")
+                                                               .add(Projections.property("scen.rid"), "index"))
+                               .setResultTransformer(
+                                               Transformers.aliasToBean(ScenarioDTO.class));
+               return getScenarioDAO().getFilteredDTOList(query);
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.service.ScenarioService#copyStudyContent(long, long, int, long)
+        */
+       @Override
+       @Transactional
+       public void copyStudyContent(final long fromStudyId, final long fromScenId,
+                       final int finalStepNum, final long toStudyId)
+                       throws InvalidParameterException, MissedPropertyException,
+                       InvalidPropertyException, MultiplyDefinedException,
+                       NotApplicableException, IOException {
+               Study fromStudy = getStudyService().selectStudy(fromStudyId);
+               if (fromStudy == null) {
+                       throw new InvalidParameterException(MessageKeyEnum.STD_000002
+                                       .toString(), String.valueOf(fromStudyId));
+               }
+               Scenario fromScen = null;
+               for (Scenario scen : fromStudy.getScenariiList()) {
+                       if (scen.getIndex() == fromScenId) {
+                               fromScen = scen;
+                       }
+               }
+
+               Study toStudy = getStudyService().selectStudy(toStudyId);
+               if (toStudy == null) {
+                       throw new InvalidParameterException(MessageKeyEnum.STD_000002
+                                       .toString(), String.valueOf(toStudy));
+               }
+
+               // Check if the step is applied to a scenario and scenario is defined
+               if (fromScen == null
+                               && getStepsConfigService().stepInvolves(finalStepNum,
+                                               Scenario.class)) {
+                       throw new InvalidParameterException(MessageKeyEnum.SCN_000006
+                                       .toString(), String.valueOf(fromScenId));
+               }
+
+               // Copy validation cycles
+               for (ValidationCycle fromCycle : fromStudy.getValidationCycles()
+                               .values()) {
+                       ValidationCycle cycle = new ValidationCycle(toStudy, fromCycle);
+                       getValidationCycleDAO().create(cycle);
+                       toStudy.addRelation(cycle.getContext());
+                       toStudy.getValidationCycles().put(
+                                       cycle.getDocumentType().getName(), cycle); // Replaces the cycle if exists as default,
+               }
+
+               // Copy content of the study up to the given step
+               Map<Publication, Publication> oldToNewPub = new HashMap<Publication, Publication>();
+               copyDocs(fromStudy, toStudy, finalStepNum, oldToNewPub);
+               if (fromScen != null) {
+                       copyDocs(fromScen, toStudy.getScenariiList().get(0), finalStepNum,
+                                       oldToNewPub);
+               }
+               copyDependencies(fromStudy, finalStepNum, oldToNewPub);
+               if (fromScen != null) {
+                       copyDependencies(fromScen, finalStepNum, oldToNewPub);
+               }
+       }
+
+       /**
+        * Copy dependencies between documents from the given project element up to <BR>
+        * the given step according to the given map of old publications to new publications.
+        * 
+        * @param from
+        *            the source project element
+        * @param finalStepNum
+        *            the final step for copy processing
+        * @param oldToNewPub
+        *            the old to new publications map
+        */
+       private void copyDependencies(final ProjectElement from,
+                       final int finalStepNum,
+                       final Map<Publication, Publication> oldToNewPub) {
+               // Copy dependencies between copied documents
+               for (Publication pub : from.getDocums()) {
+                       // If the document in the step before the final one
+                       if (pub.value().getStep() <= finalStepNum) {
+                               Publication newPub = oldToNewPub.get(pub);
+                               for (Publication used : pub.getRelations(UsesRelation.class)) {
+                                       newPub.addDependency(oldToNewPub.get(used));
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Copy documents with dependencies up to the given step.
+        * 
+        * @param from
+        *            the source project element
+        * @param to
+        *            the destination project element
+        * @param finalStepNum
+        *            the final step for copy process
+        * @param oldToNewPub2
+        * @throws MissedPropertyException
+        *             if document creation is failed
+        * @throws InvalidPropertyException
+        *             if document creation is failed
+        * @throws MultiplyDefinedException
+        *             if document creation is failed
+        * @throws IOException
+        *             if document file creation is failed
+        * @throws NotApplicableException
+        *             if document state is not applicable
+        * @param oldToNewPub
+        *            the old to new publications map
+        * 
+        */
+       private void copyDocs(final ProjectElement from, final ProjectElement to,
+                       final int finalStepNum,
+                       final Map<Publication, Publication> oldToNewPub)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, NotApplicableException, IOException {
+               Map<Integer, Step> steps = getProjectElementService().getStepsMap(to);
+               // Copy publications without old versions and relations to not copied steps documents
+               for (Publication pub : from.getDocums()) {
+                       // If the document in the step before the final one
+                       if (pub.value().getStep() <= finalStepNum) {
+                               // Copy the document
+                               oldToNewPub.put(pub, createDoc(pub.value(), steps.get(pub
+                                               .value().getStep())));
+                       }
+               }
+       }
+
+       /**
+        * Create a copy of the given document and publish it in the given step.
+        * 
+        * @param fromDoc
+        *            the source document
+        * @param step
+        *            the destination step
+        * @return the created publication
+        * @throws MissedPropertyException
+        *             if document creation is failed
+        * @throws InvalidPropertyException
+        *             if document creation is failed
+        * @throws MultiplyDefinedException
+        *             if document creation is failed
+        * @throws IOException
+        *             if document file creation is failed
+        * @throws NotApplicableException
+        *             if document state is not applicable
+        */
+       private Publication createDoc(final Document fromDoc, final Step step)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException, NotApplicableException {
+
+               java.io.File upfile = fromDoc.getSourceFile().asFile();
+               // Creation of the document
+               Document.Properties dprop = new Document.Properties().setName(
+                               fromDoc.getTitle()).setType(fromDoc.getType()).setFormat(
+                               fromDoc.getFormat()).setAuthor(fromDoc.getAuthor());
+               dprop.setLocalPath(upfile.getPath());
+               Publication addoc = getStepService().createDocument(step, dprop);
+               copyFile(upfile, addoc.getSourceFile());
+               getPublicationService().saveAs(addoc, fromDoc.getProgressState());
+
+               // Copy attached files
+               for (Relation rel : addoc.value().getRelations(ConvertsRelation.class)) {
+                       File attach = ((ConvertsRelation) rel).getTo();
+                       ConvertsRelation export = getPublicationService().attach(addoc,
+                                       attach.getFormat());
+                       copyFile(attach.asFile(), export.getTo());
+               }
+               return addoc;
+       }
+
+       /**
+        * Copy a file. Print info message.
+        * 
+        * @param upfile
+        *            the source file.
+        * @param targetFile
+        *            the target file
+        * @throws IOException
+        *             if failed
+        */
+       private void copyFile(final java.io.File upfile, final File targetFile)
+                       throws IOException {
+               if (LOG.isInfoEnabled()) {
+                       LOG.info("Copy " + upfile.getAbsolutePath() + TO
+                                       + targetFile.asFile().getPath());
+               }
+               IOUtils.copy(upfile, targetFile.asFile());
+       }
+
        /**
         * {@inheritDoc}
         * 
@@ -366,8 +600,9 @@ public class ScenarioServiceImpl implements ScenarioService {
                return study;
        }
 
-       /** 
+       /**
         * {@inheritDoc}
+        * 
         * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
         */
        @Transactional
@@ -759,7 +994,7 @@ public class ScenarioServiceImpl implements ScenarioService {
                                ConvertsRelation export = getPublicationService().attach(pub,
                                                fileFormat);
                                if (LOG.isDebugEnabled()) {
-                                       LOG.debug("Moving " + upfile.getName() + " to "
+                                       LOG.debug("Moving " + upfile.getName() + TO
                                                        + export.getTo().asFile().getPath());
                                }
                                upfile.renameTo(export.getTo().asFile());
@@ -803,7 +1038,7 @@ public class ScenarioServiceImpl implements ScenarioService {
                        } else {
                                throw new IOException(
                                                "Can't delete the existing destination file to move file from "
-                                                               + upfile.getAbsolutePath() + " to "
+                                                               + upfile.getAbsolutePath() + TO
                                                                + updir.getAbsolutePath());
                        }
                }
@@ -813,8 +1048,7 @@ public class ScenarioServiceImpl implements ScenarioService {
                        getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
                } else {
                        throw new IOException("Can't move file from "
-                                       + upfile.getAbsolutePath() + " to "
-                                       + updir.getAbsolutePath());
+                                       + upfile.getAbsolutePath() + TO + updir.getAbsolutePath());
                }
        }
 
@@ -1366,4 +1600,44 @@ public class ScenarioServiceImpl implements ScenarioService {
                _simulationContextTypeService = simulationContextTypeService;
        }
 
+       /**
+        * Get the validationCycleDAO.
+        * 
+        * @return the validationCycleDAO
+        */
+       public ValidationCycleDAO getValidationCycleDAO() {
+               return _validationCycleDAO;
+       }
+
+       /**
+        * Set the validationCycleDAO.
+        * 
+        * @param validationCycleDAO
+        *            the validationCycleDAO to set
+        */
+       public void setValidationCycleDAO(
+                       final ValidationCycleDAO validationCycleDAO) {
+               _validationCycleDAO = validationCycleDAO;
+       }
+
+       /**
+        * Get steps config.
+        * 
+        * @return steps config service
+        */
+       private StepsConfigService getStepsConfigService() {
+               return _stepsConfigService;
+       }
+
+       /**
+        * Set steps config service.
+        * 
+        * @param stepsConfigService
+        *            steps config service
+        */
+       public void setStepsConfigService(
+                       final StepsConfigService stepsConfigService) {
+               _stepsConfigService = stepsConfigService;
+       }
+
 }
index 9b7bd1c9bb719b4d0e5c8ef794084024ab06191b..d6bf598962b848b99a8c3eabad3be6d38c9481c9 100644 (file)
@@ -54,12 +54,12 @@ import org.splat.dal.bo.som.Publication;
 import org.splat.dal.bo.som.Scenario;
 import org.splat.dal.bo.som.SimulationContext;
 import org.splat.dal.bo.som.Study;
-import org.splat.dal.bo.som.Study.Properties;
 import org.splat.dal.bo.som.ValidationCycle;
-import org.splat.dal.bo.som.ValidationCycle.Actor;
 import org.splat.dal.bo.som.ValidationCycleRelation;
 import org.splat.dal.bo.som.ValidationStep;
 import org.splat.dal.bo.som.Visibility;
+import org.splat.dal.bo.som.Study.Properties;
+import org.splat.dal.bo.som.ValidationCycle.Actor;
 import org.splat.dal.dao.som.DescriptionAttributeDAO;
 import org.splat.dal.dao.som.DocumentDAO;
 import org.splat.dal.dao.som.IDBuilderDAO;
@@ -68,6 +68,7 @@ import org.splat.dal.dao.som.ScenarioDAO;
 import org.splat.dal.dao.som.StudyDAO;
 import org.splat.dal.dao.som.UsedByRelationDAO;
 import org.splat.dal.dao.som.ValidationCycleDAO;
+import org.splat.exception.BusinessException;
 import org.splat.exception.IncompatibleDataException;
 import org.splat.exception.InvalidParameterException;
 import org.splat.kernel.InvalidPropertyException;
@@ -80,9 +81,9 @@ import org.splat.service.dto.DocumentDTO;
 import org.splat.service.dto.StudyFacadeDTO;
 import org.splat.service.technical.IndexService;
 import org.splat.service.technical.ProjectSettingsService;
-import org.splat.service.technical.ProjectSettingsService.Step;
 import org.splat.service.technical.ProjectSettingsServiceImpl;
 import org.splat.service.technical.RepositoryService;
+import org.splat.service.technical.ProjectSettingsService.Step;
 import org.splat.som.Revision;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -486,8 +487,8 @@ public class StudyServiceImpl implements StudyService {
                                aStudyDTO.getAllRelations().add(link); // RKV
 
                                validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
-                       } catch (Exception error) {
-                               LOG.error("Unable to re-index Knowledge Elements, reason:",
+                       } catch (BusinessException error) {
+                               LOG.error("Unable to create validation cycle, reason:",
                                                error);
                                return;
                        }
diff --git a/Workspace/Siman-Common/src/org/splat/service/dto/ScenarioDTO.java b/Workspace/Siman-Common/src/org/splat/service/dto/ScenarioDTO.java
new file mode 100644 (file)
index 0000000..8d6116b
--- /dev/null
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   20.03.2013
+ * @author         $Author$
+ * @version        $Revision$
+ * @copyright      OPEN CASCADE 2012
+ *****************************************************************************/
+
+package org.splat.service.dto;
+
+/**
+ * Scenario DTO class.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ */
+public class ScenarioDTO {
+       /**
+        * Scenario persistent id.
+        */
+       private Long _index = 0L;
+       /**
+        * Scenario title.
+        */
+       private String _title = "";
+
+       /**
+        * Get the scenario persistent id.
+        * 
+        * @return the id
+        */
+       public Long getIndex() {
+               return _index;
+       }
+
+       /**
+        * Set the scenario persistent id.
+        * 
+        * @param index
+        *            the id to set
+        */
+       public void setIndex(final Long index) {
+               _index = index;
+       }
+
+       /**
+        * Get the title.
+        * 
+        * @return the title
+        */
+       public String getTitle() {
+               return _title;
+       }
+
+       /**
+        * Set the title.
+        * 
+        * @param title
+        *            the title to set
+        */
+       public void setTitle(final String title) {
+               this._title = title;
+       }
+}
index b688c5ea0566ab6ee2a2ea04fd78ccc5a087576c..9b1e60603719a7f426f3d58dd29a286e0b28ac2c 100644 (file)
@@ -8,7 +8,7 @@
  * @copyright      OPEN CASCADE 2012
  *****************************************************************************/
 
-package org.splat.service.technical; 
+package org.splat.service.technical;
 
 import java.util.List;
 
@@ -16,7 +16,7 @@ import org.splat.dal.bo.som.ProjectElement;
 
 /**
  * Study steps configuration service.
- *
+ * 
  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
  */
 public interface StepsConfigService {
@@ -31,6 +31,18 @@ public interface StepsConfigService {
        List<ProjectSettingsService.Step> getStepsOf(
                        Class<? extends ProjectElement> level);
 
+       /**
+        * Check whether the workflow step involves a project element(s) of the given level.
+        * 
+        * @param stepNum
+        *            the step number
+        * @param level
+        *            the project element level
+        * @return true if there are project element's steps of the given level before the given step
+        */
+       public boolean stepInvolves(final int stepNum,
+                       final Class<? extends ProjectElement> level);
+
        /**
         * Get the steps.
         * 
index 0776d9453a715d16b6ca60271048516d70257496..39c5f70a8a8e291a4723e04dc3cfaef435a64821 100644 (file)
@@ -47,6 +47,28 @@ public class StepsConfigServiceImpl implements StepsConfigService {
                return result;
        }
 
+       /**
+        * Check whether the workflow step involves a project element(s) of the given level.
+        * 
+        * @param stepNum
+        *            the step number
+        * @param level
+        *            the project element level
+        * @return true if there are project element's steps of the given level before the given step
+        */
+       public boolean stepInvolves(final int stepNum,
+                       final Class<? extends ProjectElement> level) {
+               boolean res = false;
+               for (int i = 0; i < _steps.size(); i++) {
+                       ProjectSettingsService.Step step = _steps.get(i);
+                       if (step.appliesTo(level) && step.getNumber() <= stepNum) {
+                               res = true;
+                               break;
+                       }
+               }
+               return res;
+       }
+
        /**
         * Get the steps.
         * 
diff --git a/Workspace/Siman-Common/src/org/splat/util/IOUtils.java b/Workspace/Siman-Common/src/org/splat/util/IOUtils.java
new file mode 100644 (file)
index 0000000..3bf960e
--- /dev/null
@@ -0,0 +1,215 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   21.03.2013
+ * @author         $Author$
+ * @version        $Revision$
+ * @copyright      OPEN CASCADE 2012
+ *****************************************************************************/
+package org.splat.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URL;
+
+/**
+ * Class for working with files.
+ */
+public final class IOUtils {
+
+       /**
+        * Private constructor.
+        */
+       private IOUtils() {
+
+       }
+
+       /**
+        * Copy a source stream to a target stream using a buffer of 1024 bytes.
+        * 
+        * @param src
+        *            source stream
+        * @param target
+        *            target stream
+        * 
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copy(final InputStream src, final OutputStream target)
+                       throws IOException {
+
+               byte[] buffer = new byte[1024];
+
+               for (int i = src.read(buffer); i != -1; i = src.read(buffer)) {
+                       target.write(buffer, 0, i);
+               }
+
+               target.flush();
+       }
+
+       /**
+        * Copy a source stream to a target file defined by its path.
+        * 
+        * @param src
+        *            source stream
+        * @param targetFilePath
+        *            target file path
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copy(final InputStream src, final String targetFilePath)
+                       throws IOException {
+
+               FileOutputStream outputStream = new FileOutputStream(targetFilePath);
+               try {
+
+                       copy(src, outputStream);
+                       outputStream.flush();
+
+               } finally {
+                       outputStream.close();
+               }
+
+       }
+
+       /**
+        * Copy a Reader to a Writer using a buffer of 1024.
+        * 
+        * @param src
+        *            source reader
+        * @param res
+        *            result writer
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copy(final Reader src, final Writer res)
+                       throws IOException {
+
+               char[] buffer = new char[1024];
+
+               for (int i = src.read(buffer); i != -1; i = src.read(buffer)) {
+                       res.write(buffer, 0, i);
+               }
+
+               res.flush();
+       }
+
+       /**
+        * Copy a source file to a target file.
+        * 
+        * @param src
+        *            source file
+        * @param target
+        *            target file
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copy(final File src, final File target)
+                       throws IOException {
+
+               FileInputStream inputStream = new FileInputStream(src);
+               try {
+
+                       FileOutputStream outputStream = new FileOutputStream(target);
+                       try {
+
+                               copy(inputStream, outputStream);
+                               outputStream.flush();
+
+                       } finally {
+                               outputStream.close();
+                       }
+
+               } finally {
+                       inputStream.close();
+               }
+       }
+
+       /**
+        * Copy a source file to a target file defined by their paths.
+        * 
+        * @param srcPath
+        *            source file path
+        * @param resPath
+        *            target file path
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copy(final String srcPath, final String resPath)
+                       throws IOException {
+
+               FileInputStream inputStream = new FileInputStream(srcPath);
+               try {
+
+                       FileOutputStream outputStream = new FileOutputStream(resPath);
+                       try {
+
+                               copy(inputStream, outputStream);
+                               outputStream.flush();
+
+                       } finally {
+                               outputStream.close();
+                       }
+
+               } finally {
+                       inputStream.close();
+               }
+       }
+
+       /**
+        * Copy data from URL to a file.
+        * 
+        * @param srcUrl
+        *            source URL string
+        * @param resFilePath
+        *            result file path
+        * @throws IOException
+        *             if reading or writing is failed
+        */
+       static public void copyURLtoFile(final String srcUrl,
+                       final String resFilePath) throws IOException {
+
+               URL url = new URL(srcUrl);
+
+               InputStream inputStream = url.openStream();
+               try {
+
+                       FileOutputStream res = new FileOutputStream(resFilePath);
+                       try {
+
+                               IOUtils.copy(inputStream, res);
+                               res.flush();
+
+                       } finally {
+                               res.close();
+                       }
+
+               } finally {
+                       inputStream.close();
+               }
+       }
+
+       /**
+        * Delete the content of the folder or delete the file. If it is a folder <BR>
+        * then delete all children before.
+        * 
+        * @param file
+        *            the file or folder to delete
+        * @return return true if succeeded, otherwise return false
+        */
+       static public boolean delete(final File file) {
+               if (file.isDirectory()) {
+                       for (File child : file.listFiles()) {
+                               delete(child);
+                       }
+               }
+               return file.delete();
+       }
+}
index ef382affb666210f7d13e182ca618ab0801e6d4b..538a4ed6f5620a09ef60b0e9eaed2a3d6001568e 100644 (file)
@@ -72,6 +72,8 @@ http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
                <property name="projectElementDAO" ref="projectElementDAO" />
                <property name="repositoryService" ref="repositoryService" />
                <property name="timestampDAO" ref="timestampDAO" />
+        <property name="simulationContextService"
+            ref="simulationContextService" />
        </bean>
 
        <bean id="scenarioService"
@@ -86,7 +88,8 @@ http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
                <property name="studyService" ref="studyService" />
                <property name="knowledgeElementDAO" ref="knowledgeElementDAO" />
                <property name="scenarioDAO" ref="scenarioDAO" />
-               <property name="studyDAO" ref="studyDAO" />
+        <property name="studyDAO" ref="studyDAO" />
+        <property name="validationCycleDAO" ref="validationCycleDAO" />
                <property name="knowledgeElementTypeService"
                        ref="knowledgeElementTypeService" />
                <property name="userService" ref="userService" />
index 607e62dd123aab33bb37550c42461917874df2fa..b402d1d9cac2e17b2f1fe8f1112d488407ac946a 100644 (file)
@@ -38,6 +38,7 @@ import org.splat.dal.bo.som.Document.Properties;
 import org.splat.dal.dao.kernel.UserDAO;
 import org.splat.dal.dao.som.Database;
 import org.splat.dal.dao.som.ScenarioDAO;
+import org.splat.dal.dao.som.StudyDAO;
 import org.splat.exception.BusinessException;
 import org.splat.i18n.I18nUtils;
 import org.splat.kernel.InvalidPropertyException;
@@ -55,6 +56,7 @@ import org.splat.service.StepService;
 import org.splat.service.StudyService;
 import org.splat.service.dto.DocumentDTO;
 import org.splat.service.dto.FileDTO;
+import org.splat.service.dto.ScenarioDTO;
 import org.splat.service.dto.StepDTO;
 import org.splat.service.technical.ProjectSettingsService;
 import org.splat.service.technical.RepositoryService;
@@ -168,6 +170,13 @@ public class TestScenarioService extends BaseTest {
        @Qualifier("studyService")
        private transient StudyService _studyService;
 
+       /**
+        * The StudyDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyDAO")
+       private transient StudyDAO _studyDAO;
+
        /**
         * Test of getting a scenario content for building siman-salome.conf.<BR>
         * <B>Description :</B> <BR>
@@ -1152,6 +1161,97 @@ public class TestScenarioService extends BaseTest {
                        BusinessException {
                LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
                startNestedTransaction();
+       
+               HibernateTemplate ht = getHibernateTemplate();
+       
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               _projectSettings.configure("classpath:test/som.xml");
+       
+               // Create a test user
+               User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+               _userDAO.create(goodUser);
+               SimulationContextType prodtype = _simulationContextService
+                               .selectType("product");
+               Assert
+                               .assertNotNull(prodtype,
+                                               "Simulation context type 'product' must be created in the database.");
+       
+               String productName = "New Test Product " + new Date().toString();
+       
+               ht.flush();
+               ht.clear();
+               long studyId1 = _scenarioService.createStudy("goodUser",
+                               "Test Study 1", productName, "Test description");
+               Assert.assertTrue(studyId1 > 0);
+       
+               ht.flush();
+               ht.clear();
+               try {
+                       _scenarioService.createStudy("badbadUser", "Test Study 2",
+                                       productName, "Test description");
+                       Assert.fail("Study must not be created for not existing user.");
+               } catch (InvalidPropertyException ipe) {
+                       LOG.debug("Expected exception: " + ipe.getMessage());
+               }
+       
+               ht.flush();
+               ht.clear();
+               long studyId3 = _scenarioService.createStudy("goodUser",
+                               "Test Study 3", productName, "Test description");
+               Assert.assertTrue(studyId3 > 0);
+       
+               // Check that the simulation context is the same
+               Study study1 = _studyService.selectStudy(studyId1);
+               Study study3 = _studyService.selectStudy(studyId3);
+               Assert.assertEquals(study1.SimulationContextIterator().next(), study3
+                               .SimulationContextIterator().next());
+       
+               // Check the title of the created scenario
+               String scTitle = study1.getScenarii()[0].getTitle();
+               Assert.assertEquals(scTitle, I18nUtils
+                               .getMessageLocaleDefault("label.scenario")
+                               + " 1");
+               Assert.assertFalse(scTitle.equals("label.scenario 1"));
+       
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testCreateStudyFromPython()");
+       }
+
+       /**
+        * Test study content copy.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call the method for a not existing source study.</i><BR>
+        * <i>1. call the method for a not existing source scenario.</i><BR>
+        * <i>1. call the method for a not existing source study.</i><BR>
+        * <i>2. call the method for an existing username and an existing product.</i><BR>
+        * <i>3. call the method for a not existing username expecting an exception.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>1: The new study must be created. The new product simulation context must be created.</li>
+        * <li>2: The new study must be created.</li>
+        * <li>3: The new study must not be created. Exception must be thrown.</li>
+        * </ul>
+        * </i>
+        * 
+        * @throws IOException
+        *             if application configuration loading is failed
+        * @throws SQLException
+        *             if application configuration loading is failed
+        * @throws BusinessException
+        *             if test data creation is failed
+        */
+       @Test(groups = { "study", "sevice", "functional", "business" })
+       public void testCopyStudyContent() throws IOException, SQLException,
+                       BusinessException {
+               LOG.debug(">>>>> BEGIN testCopyStudyContent()");
+               startNestedTransaction();
 
                HibernateTemplate ht = getHibernateTemplate();
 
@@ -1206,7 +1306,7 @@ public class TestScenarioService extends BaseTest {
                Assert.assertFalse(scTitle.equals("label.scenario 1"));
 
                rollbackNestedTransaction();
-               LOG.debug(">>>>> END testCreateStudyFromPython()");
+               LOG.debug(">>>>> END testCopyStudyContent()");
        }
 
        /**
@@ -1247,13 +1347,13 @@ public class TestScenarioService extends BaseTest {
                        SQLException, BusinessException {
                LOG.debug(">>>>> BEGIN testAssignStudyContextFromPython()");
                startNestedTransaction();
-
+       
                HibernateTemplate ht = getHibernateTemplate();
-
+       
                Database.getInstance().reset();
                _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
                _projectSettings.configure("classpath:test/som.xml");
-
+       
                // Create a test user
                User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
                _userDAO.create(goodUser);
@@ -1262,18 +1362,18 @@ public class TestScenarioService extends BaseTest {
                Assert
                                .assertNotNull(prodtype,
                                                "Simulation context type 'product' must be created in the database.");
-
+       
                String productName = "New Test Product " + new Date().toString();
-
+       
                ht.flush();
                ht.clear();
                long studyId1 = _scenarioService.createStudy("goodUser",
                                "Test Study 1", productName, "Test description");
                Assert.assertTrue(studyId1 > 0);
-
+       
                ht.flush();
                ht.clear();
-
+       
                // //////// START OF TESTS
                // 1. call the method for not existing study id.</i><BR>
                try {
@@ -1283,37 +1383,37 @@ public class TestScenarioService extends BaseTest {
                } catch (InvalidPropertyException ipe) {
                        LOG.debug("Expected exception: " + ipe.getMessage());
                }
-
+       
                // 2. call the method for not existing context type and context value.</i><BR>
                _scenarioService.assignStudyContext(studyId1, "new context type",
                                "new context value");
-
+       
                ht.flush();
                ht.clear();
-
+       
                // Check the assigned simulation context
                checkCtx(studyId1, "new context type", "new context value");
-
+       
                // 3. call the method for existing context type and context value.</i><BR>
                _scenarioService.assignStudyContext(studyId1, "new context type",
                                "new context value");
-
+       
                ht.flush();
                ht.clear();
-
+       
                // Check the assigned simulation context
                checkCtx(studyId1, "new context type", "new context value");
-
+       
                // 4. call the method for existing context type and not existing context value.</i><BR>
                _scenarioService.assignStudyContext(studyId1, "new context type",
                                "new context value1");
-
+       
                ht.flush();
                ht.clear();
-
+       
                // Check the assigned simulation context
                checkCtx(studyId1, "new context type", "new context value1");
-
+       
                // 5. call the method for empty context type.</i><BR>
                try {
                        _scenarioService.assignStudyContext(studyId1, "",
@@ -1330,11 +1430,107 @@ public class TestScenarioService extends BaseTest {
                } catch (InvalidPropertyException ipe) {
                        LOG.debug("Expected exception: " + ipe.getMessage());
                }
-
+       
                rollbackNestedTransaction();
                LOG.debug(">>>>> END testAssignStudyContextFromPython()");
        }
 
+       /**
+        * Test getting a study scenarios DTO list.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and get its scenarios DTO list.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call the method for not existing study id.</i><BR>
+        * <i>2. call the method for a study with one scenario.</i><BR>
+        * <i>3. call the method for a study with several scenarios.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>1: The returned list of DTO must be empty.</li>
+        * <li>2: The returned list of DTO must contain one scenario DTO.</li>
+        * <li>3: The returned list of DTO must contain several scenario DTOs.</li>
+        * </ul>
+        * </i>
+        * 
+        * @throws IOException
+        *             if application configuration loading is failed
+        * @throws SQLException
+        *             if application configuration loading is failed
+        * @throws BusinessException
+        *             if test data creation is failed
+        */
+       @Test(groups = { "study", "sevice", "functional", "business" })
+       public void testGetStudyScenarios() throws IOException,
+                       SQLException, BusinessException {
+               LOG.debug(">>>>> BEGIN testGetStudyScenarios()");
+               startNestedTransaction();
+
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               _projectSettings.configure("classpath:test/som.xml");
+
+               // Create a test user
+               User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+               _userDAO.create(goodUser);
+               Study study = TestEntitiesGenerator.getTestStudy(goodUser);
+               long studyId1 = _studyDAO.create(study);
+               ht.flush();
+               Scenario scen = TestEntitiesGenerator.getTestScenario(study, "test scen11");
+               long id11 = _scenarioDAO.create(scen);
+               ht.flush();
+               study = TestEntitiesGenerator.getTestStudy(goodUser);
+               long studyId2 = _studyDAO.create(study);
+               ht.flush();
+               scen = TestEntitiesGenerator.getTestScenario(study, "test scen21");
+               long id21 = _scenarioDAO.create(scen);
+               ht.flush();
+               scen = TestEntitiesGenerator.getTestScenario(study, "test scen22");
+               long id22 = _scenarioDAO.create(scen);
+               ht.flush();
+               scen = TestEntitiesGenerator.getTestScenario(study, "test scen23");
+               long id23 = _scenarioDAO.create(scen);
+               ht.flush();
+               ht.clear();
+               
+               // //////// START OF TESTS
+               // 1. call the method for not existing study id.
+               List<ScenarioDTO> scens = _scenarioService.getStudyScenarios(-1L);
+
+               Assert.assertNotNull(scens);
+               Assert.assertTrue(scens.isEmpty());
+               
+               // 2. call the method for a study with one scenario.
+               scens = _scenarioService.getStudyScenarios(studyId1);
+
+               ht.flush();
+               ht.clear();
+               Assert.assertNotNull(scens);
+               Assert.assertEquals(scens.size(), 1);
+               Assert.assertEquals(scens.get(0).getIndex().longValue(), id11);
+               Assert.assertEquals(scens.get(0).getTitle(), "test scen11");
+
+               // 3. call the method for a study with several scenarios.
+               scens = _scenarioService.getStudyScenarios(studyId2);
+               Assert.assertEquals(scens.size(), 3);
+               Assert.assertEquals(scens.get(0).getIndex().longValue(), id21);
+               Assert.assertEquals(scens.get(0).getTitle(), "test scen21");
+               Assert.assertEquals(scens.get(1).getIndex().longValue(), id22);
+               Assert.assertEquals(scens.get(1).getTitle(), "test scen22");
+               Assert.assertEquals(scens.get(2).getIndex().longValue(), id23);
+               Assert.assertEquals(scens.get(2).getTitle(), "test scen23");
+
+               ht.flush();
+               ht.clear();
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testGetStudyScenarios()");
+       }
+
        /**
         * Check if the context is assigned to the study.
         * 
diff --git a/Workspace/Siman-Common/src/test/splat/service/TestStepsConfigService.java b/Workspace/Siman-Common/src/test/splat/service/TestStepsConfigService.java
new file mode 100644 (file)
index 0000000..ac4221d
--- /dev/null
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * 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.List;
+
+import org.splat.dal.bo.som.Scenario;
+import org.splat.dal.bo.som.Study;
+import org.splat.log.AppLogger;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.StepsConfigService;
+import org.splat.service.technical.ProjectSettingsService.Step;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import test.splat.common.BaseTest;
+
+/**
+ * Test class for ProjectService.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ * 
+ */
+public class TestStepsConfigService extends BaseTest {
+
+       /**
+        * Logger for the class.
+        */
+       private static final AppLogger LOG = AppLogger
+                       .getLogger(TestStepsConfigService.class);
+
+       /**
+        * The ProjectSettingsService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectSettings")
+       private transient ProjectSettingsService _projectSettings;
+
+       /**
+        * The StepsConfigService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("stepsConfigService")
+       private transient StepsConfigService _stepsConfigService;
+
+       /**
+        * Test steps configuration. First steps do not involve scenario steps.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Load configuration and check the result.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call the method for som.xml</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>test/som.xml</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>First step involves a study only. Other steps involve both a study and a scenario. </li>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws IOException
+        *             if configuration loading is failed
+        * @throws SQLException
+        *             if configuration loading is failed
+        */
+       @Test
+       public void testStepInvolves() throws IOException, SQLException {
+               LOG.debug(">>>>> BEGIN testStepInvolves()()");
+               startNestedTransaction();
+               // ////// Load good workflow customization
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               try {
+                       _projectSettings.configure("classpath:test/som.xml");
+               } catch (FileNotFoundException e) {
+                       Assert.fail("Can't find configuration file: ", e);
+               }
+               List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
+               Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+               Assert.assertTrue(_stepsConfigService.stepInvolves(1, Study.class));
+               Assert.assertFalse(_stepsConfigService.stepInvolves(1, Scenario.class));
+               for (int i = 2; i <= steps.size(); i++) {
+                       Assert.assertTrue(_stepsConfigService.stepInvolves(i, Study.class));
+                       Assert.assertTrue(_stepsConfigService.stepInvolves(i, Scenario.class));
+               }
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testStepInvolves()()");
+       }
+}
index f534c4bf3890cb3e79318c29d671de996d5021c9..e21a357d53de911b65f0d5da30c882e449c2c24f 100644 (file)
@@ -58,8 +58,7 @@ public class TestEntitiesGenerator {
         */
        public static Study getTestStudy(final User user) throws BusinessException {
                Study.Properties studyProps = new Study.Properties();
-               studyProps.setActor(user).setManager(user)
-                               .setTitle("a test study")
+               studyProps.setActor(user).setManager(user).setTitle("a test study")
                                // .setDescription("description")
                                .setDate(new Date()).setReference("test reference")
                                .setSimulationContexts(new ArrayList<SimulationContext>());
@@ -78,9 +77,24 @@ public class TestEntitiesGenerator {
         */
        public static Scenario getTestScenario(final Study study)
                        throws BusinessException {
-               Scenario.Properties sprops = new Scenario.Properties().setTitle(
-                               "TST_Scenario").setManager(study.getAuthor()).setOwnerStudy(
-                               study);
+               return getTestScenario(study, "TST_Scenario");
+       }
+
+       /**
+        * Create a transient test scenario.
+        * 
+        * @param title
+        *            the scenario title
+        * @param study
+        *            the owner study
+        * @return the created scenario
+        * @throws BusinessException
+        *             if creation is failed
+        */
+       public static Scenario getTestScenario(final Study study, final String title)
+                       throws BusinessException {
+               Scenario.Properties sprops = new Scenario.Properties().setTitle(title)
+                               .setManager(study.getAuthor()).setOwnerStudy(study);
                Scenario aScenario = new Scenario(sprops);
                study.getScenariiList().add(aScenario);
                return aScenario;
index c68d3f77bf7eacf88ccdf7056f9ab2edda0a737f..716d29dd479a5920121c36e065c2f2584378e340 100644 (file)
 </definition>
 
 <definition name="page.newstudy" extends="baseLayoutWithoutTitleBar">
-       <put-attribute name="presentation_pane"   value="/study/newStudy.jsp"/>
+    <put-attribute name="presentation_pane"   value="/study/newStudy.jsp"/>
+</definition>
+
+<definition name="page.newcopy" extends="baseLayoutWithoutTitleBar">
+    <put-attribute name="presentation_pane"   value="/study/copyStudy.jsp"/>
 </definition>
 
 <definition name="page.searchstudy" extends="baseLayoutWithoutTitleBar">
index 419200919bf8317957080bd6d0db763c31313c45..b26d101c9f7a03b2c3b27bccec694b91cade5043 100644 (file)
@@ -6,7 +6,7 @@
 <!-- 1. Database physical location
      -->
     <database>
-        <repository disk="/home/siman/Repository" />
+        <repository disk="D:\users\rkv\SALOME_SIMER\rep" />
     </database>
 
 
@@ -70,6 +70,7 @@
         <article type="log"           uses="script"/>
         <article type="results"       uses="script"/>
         <article type="report"        uses="results"/>
+        <article type="schema"/>
         <article type="memorandum"/>
         <article type="minutes"/>
         <article type="coparisonResult"/>
             <flow contents="memorandum,minutes,coparisonResult" result="coparisonResult"/>
             <storage path="6.Report"/>
         </step>
+        <step name="schema">
+            <flow contents="schema" result="schema"/>
+            <storage path="7.Schema"/>
+            <module name="YACS"/>
+        </step>
         <step name="capitalization">
             <flow contents="knowledge"/>
-            <storage path="6.Report"/>
+            <storage path="8.Summary"/>
         </step>
       </scenario>
         <step name="reporting">
         <document type="results">
             <import format="med"/>      <!-- Calculation results source file          -->
         </document>
+        <document type="schema">
+            <import format="xml"/>      <!-- Calculation results source file          -->
+        </document>
     </mappings>
     
     <default-doctypes>
         <step number="6">
             <mapping extension="srd"    type="coparisonResult"/>
         </step>
+        <step number="7">
+            <mapping extension="xml"    type="schema"/>
+        </step>
     </default-doctypes>
     
 </project-structure>
\ No newline at end of file
diff --git a/Workspace/Siman/WebContent/skin/icon.schema.png b/Workspace/Siman/WebContent/skin/icon.schema.png
new file mode 100644 (file)
index 0000000..94b97ba
Binary files /dev/null and b/Workspace/Siman/WebContent/skin/icon.schema.png differ
diff --git a/Workspace/Siman/WebContent/study/copyStudy.jsp b/Workspace/Siman/WebContent/study/copyStudy.jsp
new file mode 100644 (file)
index 0000000..29aca70
--- /dev/null
@@ -0,0 +1,87 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
+<%@ taglib prefix="s" uri="/struts-tags"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+
+    <script language="JavaScript">
+
+    function initialize () {
+//  ----------------------
+      create.elements[0].focus();
+    }
+
+    function setValue () {
+//  -------------------
+      var select = create.elements[1].value;  // contextValue select input
+      if (select == "0") {                    // Creation of a new context type
+        tds = document.getElementById("select");
+        tde = document.getElementById("enter");
+        tds.style.display = "none";           // Hides the select input
+        tde.style.display = "block";          // Displays the text input
+      }
+      create.elements[2].focus();
+    }
+    </script>
+
+<!-- New study dialog
+     =============================================================================================================================
+  -->
+      <div id=article-box>
+        <div id=section><s:text name="title.newstudy"/></div>
+        <div id=top-spacer></div>
+        <form name="create" action="valid-new" method="post">
+        <table class="text">
+
+          <tr class="error">
+            <td colspan=3><s:text name="%{error}"/></td>
+          </tr>
+
+          <tr>
+            <td>
+              &nbsp;<s:text name="field.studytitle"/>*:&nbsp;
+            </td>
+            <td colspan=2>
+              <input type=text size="60" name=title value="<s:property value="title"/>">
+            </td>
+          </tr>
+
+          <tr>
+            <td>
+              &nbsp;<s:text name="field.product"/>*:&nbsp;
+            </td>
+            <s:if test="projectContextValues.size > 0">
+              <td id=select>
+                <select name="projectContext" style="width:214px" onChange="setValue()">
+                  <option value="-1"><s:text name="menu.select"/></option>
+                  <option value="0">&nbsp;<s:text name="menu.newproduct"/></option>
+                  <optgroup label="&nbsp;<s:text name="label.products"/>">
+                    <s:iterator value="projectContextValues">
+                      <option value="<s:property value="index"/>">&nbsp;<s:property value="value"/></option>
+                    </s:iterator>
+                  </optgroup>
+                </select>
+              </td>
+              <td id=enter style="display: none">
+                <input type=text size="30" name=projectContext>
+              </td>
+            </s:if>
+            <s:else>
+              <td>
+                <input type=hidden         name=projectContext value="0">
+                <input type=text size="30" name=projectContext>
+              </td>
+            </s:else>
+            <td align=right>
+              <input type="submit" value="<s:text name="button.newstudy"/>"/>
+            </td>
+          </tr>
+
+        </table>
+        </form>
+        <div id=top-spacer></div>
+      </div>
+
+<!-- Reserved
+  -->
+    <div id=right-pane></div>
+    <div id=bottom-spacer></div>
index d61c9e6ecd411de0ccb5dd5cb837b4dc912b4d91..6dabea0aa5195ba0b4aeee781d36833b9ebc83c2 100644 (file)
@@ -582,7 +582,7 @@ public class Action extends ActionSupport implements ServletRequestAware,
         */
        public void setErrorCode(final String code) {
                this._errorCode = code;
-               this.setMessage(code);
+               this.setMessage(getText(code));
        }
 
        /**
index 99fdb59a957150f1e90fd2b5ada4162ad75993d9..a30dd31f205cb74a73566486b633d84d1eee7cbd 100644 (file)
@@ -214,6 +214,10 @@ public class ApplicationSettings {
         * Edit menu item name.
         */
        private static final String MNU_NAME_EDIT = "menu.edit";
+       /**
+        * Edit menu item name.
+        */
+       private static final String MNU_NAME_REMOVE = "menu.remove";
        /**
         * Script menu item name.
         */
@@ -229,7 +233,7 @@ public class ApplicationSettings {
        /**
         * Remove menu item name.
         */
-       private static final String MNU_NAME_REMOVE = "menu.remove.version";
+       private static final String MNU_NAME_REMOVE_VERSION = "menu.remove.version";
        /**
         * Rename menu item name.
         */
@@ -333,13 +337,19 @@ public class ApplicationSettings {
                _projectSettings = projectSettingsService;
        }
 
+       /**
+        * New study menu.
+        */
        private static class NewMenu extends SimpleMenu {
+               /**
+                * New study menu constructor.
+                */
                private NewMenu() {
                        super("create");
                        addItem("new-empty", "menu.new.empty", "image.empty.png",
                                        "select?menu=create&item=new-empty");
-                       addItem("new-copy", new MenuItem("menu.new.copy")
-                                       .icon("image.copy.png"));
+                       addItem("new-copy", "menu.new.copy", "image.copy.png",
+                                       "select?menu=create&item=new-copy");
                        /*
                         * addItem("new-instance", new MenuItem("menu.new.instance") .icon(IMG_HOLD)); addItem("new-import", new
                         * MenuItem("menu.new.import") .icon("icon.upload.png"));
@@ -348,7 +358,13 @@ public class ApplicationSettings {
                }
        }
 
+       /**
+        * Search menu.
+        */
        private static class SearchMenu extends SimpleMenu {
+               /**
+                * Search menu constructor.
+                */
                private SearchMenu() {
                        super("search");
                        addItem("search-study", "menu.search.study", "image.study.png",
@@ -361,7 +377,13 @@ public class ApplicationSettings {
                }
        }
 
+       /**
+        * Configuration menu.
+        */
        private static class PropertiesMenu extends SimpleMenu {
+               /**
+                * Configuration menu constructor.
+                */
                private PropertiesMenu() {
                        super("configuration");
                        addItem("prop-general", "menu.prop.general", IMG_HOLD,
@@ -377,7 +399,13 @@ public class ApplicationSettings {
                }
        }
 
+       /**
+        * Data administrator menu.
+        */
        private static class DatadminMenu extends SimpleMenu {
+               /**
+                * Data administrator menu constructor.
+                */
                private DatadminMenu() {
                        super("datadmin");
                        addItem("admin-scontext", "menu.admin.context", IMG_HOLD,
@@ -389,7 +417,13 @@ public class ApplicationSettings {
                }
        }
 
+       /**
+        * System administrator menu.
+        */
        private static class SysadminMenu extends SimpleMenu {
+               /**
+                * System administrator menu constructor.
+                */
                private SysadminMenu() {
                        super("sysadmin");
                        addItem("admin-indexing", "menu.admin.indexing", "image.index.png",
@@ -471,36 +505,56 @@ public class ApplicationSettings {
        };
 
        // Resources relative to studies
+       /**
+        * Study popup menu.
+        */
        private static class EditableMarkedStudyPopup extends PopupMenu {
+               /**
+                * User rights for the selected study.
+                */
                private transient StudyRights _user = null;
 
-               private EditableMarkedStudyPopup(final boolean isPublic, final boolean isMarked) {
+               /**
+                * Study popup menu constructor.
+                * 
+                * @param isPublic
+                *            public study flag
+                * @param isMarked
+                *            "marked as reference" study flag
+                */
+               private EditableMarkedStudyPopup(final boolean isPublic,
+                               final boolean isMarked) {
                        super();
-                       
+
                        if (isMarked) {
                                addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
-                                               MNU_NAME_REMOVE_AS_REFERENCE).action(ACT_REMOVE_AS_REFERENCE)
-                                               .confirmation("message.removeasreference.study"));
+                                               MNU_NAME_REMOVE_AS_REFERENCE).action(
+                                               ACT_REMOVE_AS_REFERENCE).confirmation(
+                                               "message.removeasreference.study"));
                        } else {
-                               addItem(MNU_MARK_AS_REFERENCE, new PopupItem(MNU_NAME_MARK_AS_REFERENCE)
-                                               .action(ACT_MARK_AS_REFERENCE).confirmation(
+                               addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
+                                               MNU_NAME_MARK_AS_REFERENCE).action(
+                                               ACT_MARK_AS_REFERENCE).confirmation(
                                                "message.markasreference.study"));
                        }
-                       
+
                        if (isPublic) {
                                addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PROTECT).icon(
-                                               "image.publish.png").action("edit-study?action=protect")
-                                               .confirmation("message.protect.study"));
+                                               "image.publish.png")
+                                               .action("edit-study?action=protect").confirmation(
+                                                               "message.protect.study"));
                        } else {
                                addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PUBLISH).icon(
-                                               "image.publish.png").action("edit-study?action=publish")
-                                               .confirmation("message.publish.study"));
+                                               "image.publish.png")
+                                               .action("edit-study?action=publish").confirmation(
+                                                               "message.publish.study"));
                        }
 
                        /* addItem(MNU_PROMOTE, new PopupItem("menu.archive")); */
                        addSeparator();
                        addItem(MNU_EDIT, new PopupItem("menu.properties").icon(
-                                       "icon.ed.png").action("../select?menu=configuration&item=prop-general"));
+                                       "icon.ed.png").action(
+                                       "../select?menu=configuration&item=prop-general"));
                        addSeparator();
                        addItem(MNU_SCRIPT, new PopupItem(MNU_NAME_SCRIPT)
                                        .action("add-scenario"));
@@ -511,7 +565,7 @@ public class ApplicationSettings {
                        /*
                         * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE) .confirmation("message.purge.study")); addItem("export", new
                         * PopupItem("menu.export") .icon("image.export.png")); // For future needs
-                        */addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(
+                        */addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
                                        IMG_DELETE).action("remove-study").confirmation(
                                        "message.delete.study"));
                }
@@ -570,7 +624,7 @@ public class ApplicationSettings {
                                boolean history = _user.getOperand().isVersioned();
                                PopupItem item = this.item(MNU_REMOVE);
                                if (history) {
-                                       item.rename(MNU_NAME_REMOVE);
+                                       item.rename(MNU_NAME_REMOVE_VERSION);
                                } else {
                                        item.rename("menu.remove.study");
                                }
@@ -583,8 +637,14 @@ public class ApplicationSettings {
         * Popup of In-Work documents.
         */
        private static class EditableDocumentPopup extends PopupMenu {
+               /**
+                * User rights for the selected document.
+                */
                private transient DocumentRights _user = null;
 
+               /**
+                * Document popup menu constructor.
+                */
                private EditableDocumentPopup() {
                        super();
                        addItem("accept", new PopupItem("menu.accept").icon(
@@ -608,9 +668,9 @@ public class ApplicationSettings {
                        addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action(
                                        ACT_NOT_YET_IMPLEMENTED).confirmation(
                                        "message.purge.document"));
-                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
-                                       .action("remove-document").confirmation(
-                                                       "message.delete.document"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
+                                       IMG_DELETE).action("remove-document").confirmation(
+                                       "message.delete.document"));
                }
 
                @Override
@@ -657,7 +717,7 @@ public class ApplicationSettings {
                                Document downer = _user.getOperand();
                                PopupItem item = this.item(MNU_REMOVE);
                                if (downer.isVersioned()) {
-                                       item.rename(MNU_NAME_REMOVE);
+                                       item.rename(MNU_NAME_REMOVE_VERSION);
                                } else {
                                        item.rename("menu.remove.document");
                                }
@@ -669,8 +729,14 @@ public class ApplicationSettings {
         * Popup of In-Draft documents.
         */
        private static class ReviewableDocumentPopup extends PopupMenu {
+               /**
+                * User rights for the selected document.
+                */
                private transient DocumentRights _user = null;
 
+               /**
+                * Document popup menu constructor.
+                */
                private ReviewableDocumentPopup() {
                        super();
                        addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
@@ -745,9 +811,9 @@ public class ApplicationSettings {
                        addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action(
                                        ACT_NOT_YET_IMPLEMENTED).confirmation(
                                        "message.purge.document"));
-                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
-                                       .action("remove-document").confirmation(
-                                                       "message.delete.document"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
+                                       IMG_DELETE).action("remove-document").confirmation(
+                                       "message.delete.document"));
                }
        }
 
@@ -882,7 +948,7 @@ public class ApplicationSettings {
                        addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
                                        .action("edit-context?action=editContext"));
                        addSeparator();
-                       addItem(MNU_REMOVE, new PopupItem("menu.remove").icon(IMG_DELETE)
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
                                        .action("remove-context").confirmation(
                                                        "message.delete.context"));
                }
@@ -929,7 +995,7 @@ public class ApplicationSettings {
                        addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
                                        .action("edit-knowledge?action=editKnowledge"));
                        addSeparator();
-                       addItem(MNU_REMOVE, new PopupItem("menu.remove").icon(IMG_DELETE)
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
                                        .action("remove-knowledge").confirmation(
                                                        "message.delete.knowledge"));
                }
@@ -959,7 +1025,7 @@ public class ApplicationSettings {
                        }
                }
        }
-       
+
        /**
         * Pop-up menu for comments.
         */
@@ -971,13 +1037,16 @@ public class ApplicationSettings {
                        super();
                        addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
                                        .action("editComment(entity_index)"));
-                       addItem(MNU_REMOVE, new PopupItem("menu.remove").icon(IMG_DELETE)
-                                       .action("removeComment(entity_index)").confirmation("message.delete.comment"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("removeComment(entity_index)").confirmation(
+                                                       "message.delete.comment"));
                }
 
                /**
                 * Is enabled.
-                * @param name the entry name
+                * 
+                * @param name
+                *            the entry name
                 * @return true
                 */
                @Override
@@ -985,7 +1054,7 @@ public class ApplicationSettings {
                        return true;
                }
        }
-       
+
        /**
         * Pop-up menu for comments.
         */
@@ -997,14 +1066,16 @@ public class ApplicationSettings {
                        super();
                        addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
                                        .action("showDescriptionEditor()"));
-                       addItem(MNU_REMOVE, new PopupItem("menu.remove").icon(IMG_DELETE)
-                                       .action("removeDescription()")
-                                       .confirmation("message.delete.description"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("removeDescription()").confirmation(
+                                                       "message.delete.description"));
                }
 
                /**
                 * Is enable.
-                * @param name the entry name
+                * 
+                * @param name
+                *            the entry name
                 * @return true
                 */
                @Override
@@ -1036,10 +1107,14 @@ public class ApplicationSettings {
                _menus.put(menu.getName(), menu);
 
                _popups = new HashMap<String, PopupMenu>();
-               _popups.put("steditablemarkpublic", new EditableMarkedStudyPopup(false, false));
-               _popups.put("steditableunmarkpublic", new EditableMarkedStudyPopup(false, true));
-               _popups.put("steditablemarkprivate", new EditableMarkedStudyPopup(true, false));
-               _popups.put("steditableunmarkprivate", new EditableMarkedStudyPopup(true, true));
+               _popups.put("steditablemarkpublic", new EditableMarkedStudyPopup(false,
+                               false));
+               _popups.put("steditableunmarkpublic", new EditableMarkedStudyPopup(
+                               false, true));
+               _popups.put("steditablemarkprivate", new EditableMarkedStudyPopup(true,
+                               false));
+               _popups.put("steditableunmarkprivate", new EditableMarkedStudyPopup(
+                               true, true));
                _popups.put("editable", new EditableDocumentPopup());
                _popups.put("notresult", new NotResultDocumentPopup());
                _popups.put("reviewable", new ReviewableDocumentPopup());
diff --git a/Workspace/Siman/src/org/splat/simer/CopyStudyAction.java b/Workspace/Siman/src/org/splat/simer/CopyStudyAction.java
new file mode 100644 (file)
index 0000000..1286f51
--- /dev/null
@@ -0,0 +1,201 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   19.03.2013
+ * @author         $Author$
+ * @version        $Revision$
+ * @copyright      OPEN CASCADE 2012
+ *****************************************************************************/
+
+package org.splat.simer;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.service.SearchService;
+import org.splat.service.dto.Proxy;
+import org.splat.service.dto.ScenarioDTO;
+import org.splat.service.dto.StudySearchFilterDTO;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.StepsConfigService;
+
+/**
+ * Create a new study from existing one.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ */
+public class CopyStudyAction extends NewStudyAction {
+       /**
+        * Serial version ID.
+        */
+       private static final long serialVersionUID = -3733439553634251282L;
+       /**
+        * List of source studies.
+        */
+       private transient final Map<Long, String> _studies = new LinkedHashMap<Long, String>();
+       /**
+        * List of the selected source study scenarios.
+        */
+       private transient final Map<Long, String> _scenarios = new LinkedHashMap<Long, String>();
+       /**
+        * List of source studies steps.
+        */
+       private transient final Map<Integer, String> _steps = new LinkedHashMap<Integer, String>();
+       /**
+        * The selected source study id.
+        */
+       private long _fromStudyId = 0;
+       /**
+        * Injected search service.
+        */
+       private SearchService _searchService;
+       /**
+        * Injected StepsConfigService service.
+        */
+       private StepsConfigService _stepsConfigService;
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.simer.NewStudyAction#doCreate()
+        */
+       @Override
+       public String doCreate() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException {
+               String res = super.doCreate();
+               if (SUCCESS.equals(res)) {
+                       // Copy content from the selected study
+               }
+               return res;
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see org.splat.simer.NewStudyAction#doInitialize()
+        */
+       @Override
+       public String doInitialize() {
+               // Initialize contexts list, study title and menus.
+               super.doInitialize();
+               
+               // Initialize source studies list, scenarios list and steps list
+               
+               // Get visible studies
+               StudySearchFilterDTO filter = new StudySearchFilterDTO();
+               if (getConnectedUser() != null) {
+                       filter.setConnectedUserId(getConnectedUser().getIndex());
+               }
+               List<Proxy> studies = getSearchService().selectStudiesWhere(filter);
+               
+               // Fill the studies list
+               for (Proxy study: studies) {
+                       _studies.put(study.getIndex(), study.getTitle());
+               }
+               
+               // Fill lists of scenarios and steps according to the selected study
+               if (_fromStudyId > 0 && _studies.containsKey(_fromStudyId)) {
+                       // Get scenarios from the selected study
+                       List<ScenarioDTO> scens = getScenarioService().getStudyScenarios(_fromStudyId);
+                       for (ScenarioDTO scen: scens) {
+                               _scenarios.put(scen.getIndex(), scen.getTitle());
+                       }
+                       // Fill steps
+                       for (ProjectSettingsService.Step step: getStepsConfigService().getSteps()) {
+                               _steps.put(step.getNumber(), getText("folder.step." + step.getNumber()));
+                       }
+               }
+
+               return SUCCESS;
+       }
+
+       /**
+        * Get the studies.
+        * 
+        * @return the studies
+        */
+       public Map<Long, String> getStudies() {
+               return _studies;
+       }
+
+       /**
+        * Get the searchService.
+        * 
+        * @return the searchService
+        */
+       public SearchService getSearchService() {
+               return _searchService;
+       }
+
+       /**
+        * Set the searchService.
+        * 
+        * @param searchService
+        *            the searchService to set
+        */
+       public void setSearchService(final SearchService searchService) {
+               _searchService = searchService;
+       }
+
+       /**
+        * Get the scenarios.
+        * 
+        * @return the scenarios
+        */
+       public Map<Long, String> getScenarios() {
+               return _scenarios;
+       }
+
+       /**
+        * Get the steps.
+        * 
+        * @return the steps
+        */
+       public Map<Integer, String> getSteps() {
+               return _steps;
+       }
+
+       /**
+        * Get the fromStudyId.
+        * 
+        * @return the fromStudyId
+        */
+       public long getFromStudyId() {
+               return _fromStudyId;
+       }
+
+       /**
+        * Set the fromStudyId.
+        * 
+        * @param fromStudyId
+        *            the fromStudyId to set
+        */
+       public void setFromStudyId(final long fromStudyId) {
+               _fromStudyId = fromStudyId;
+       }
+
+       /**
+        * Get the stepsConfigService.
+        * 
+        * @return the stepsConfigService
+        */
+       public StepsConfigService getStepsConfigService() {
+               return _stepsConfigService;
+       }
+
+       /**
+        * Set the stepsConfigService.
+        * 
+        * @param stepsConfigService
+        *            the stepsConfigService to set
+        */
+       public void setStepsConfigService(
+                       final StepsConfigService stepsConfigService) {
+               _stepsConfigService = stepsConfigService;
+       }
+}
index e112a482b52b2b045c09928905b93bb8d9c9aea3..b45ec7502d4b6c772a8ce2606ce9d55c20d889b0 100644 (file)
@@ -424,6 +424,9 @@ public class DocumentFacade implements HistoryFacade {
                String format = _my.getFormat();
                if ("xml".equals(format)) {
                        format = XMLDocument.getActualFormat(_my.getSourceFile().asFile());
+                       if ("schema".equals(_my.getType().getName())) {
+                               format = "schema";
+                       }
                }
 
                _icon = "icon." + format + ICON_EXT;
index a3a4de2ebebe77981383781d4ed671de829bfc4f..697f2b7d3a40b7490a05beedc8fc9630f42481b2 100644 (file)
@@ -2,12 +2,10 @@ package org.splat.simer;
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ResourceBundle;
 
@@ -76,7 +74,8 @@ public class ImportDocumentAction extends BaseUploadDocumentAction {
                Step step = _mystudy.getSelectedStep();
                _documentTypes = getStepService().getValidDocumentTypes(step);
                // Set the document type by default
-               _deftype = getApplicationSettings().getDefaultDocumentType(step, filext);
+               _deftype = getApplicationSettings()
+                               .getDefaultDocumentType(step, filext);
                if (_deftype != null) {
                        setDefaultDocumentType(_deftype.getIndex());
                }
@@ -132,45 +131,45 @@ public class ImportDocumentAction extends BaseUploadDocumentAction {
                                _state = ProgressState.EXTERN; // TODO: Should external extensions be configurable ?
                        }
                } else {
-                       String fileref = tool.extractProperty("reference");
-                       String filever = tool.extractProperty("version"); // Property kept even if the file is not referenced
-                       String filetype = tool.extractProperty("type"); // Property kept even if the file is not referenced
-                       for (Iterator<DocumentType> i = _documentTypes.iterator(); i
-                                       .hasNext();) {
-                               DocumentType type = i.next();
-                               if (type.getName().equals(filetype)) {
-                                       _deftype = type;
-                                       _documentType = type.getIndex(); // Disables the document type field
-                                       break;
-                               }
-                       }
-                       if (fileref != null) {
-                               isOk = findTypeByDocRef(fileref);
-                       }
-                       if (isOk) {
-                               if (filever != null) {
-                                       try {
-                                               Revision.Format get = new Revision.Format(
-                                                               getProjectSettings().getRevisionPattern());
-                                               Revision version = get.parse(filever);
-                                               if (version.isNull()) {
-                                                       throw new ParseException(filever,
-                                                                       filever.length() - 1);
-                                               }
-                                               if (!version.isMinor()) {
-                                                       _state = ProgressState.inCHECK;
-                                               }
-                                               setVersion(version.toString());
-                                       } catch (ParseException e) {
-                                               setErrorCode("message.error.format.version");
-                                               isOk = false;
-                                       }
-                               }
-                               if (isOk) {
-                                       _docname = tool.extractProperty("title"); // Property kept even if the file is not referenced
-                                       isOk = extractDate(tool);
-                               }
-                       }
+                       // String fileref = tool.extractProperty("reference");
+                       // String filever = tool.extractProperty("version"); // Property kept even if the file is not referenced
+                       // String filetype = tool.extractProperty("type"); // Property kept even if the file is not referenced
+                       // for (Iterator<DocumentType> i = _documentTypes.iterator(); i
+                       // .hasNext();) {
+                       // DocumentType type = i.next();
+                       // if (type.getName().equals(filetype)) {
+                       // _deftype = type;
+                       // _documentType = type.getIndex(); // Disables the document type field
+                       // break;
+                       // }
+                       // }
+                       // if (fileref != null) {
+                       // isOk = findTypeByDocRef(fileref);
+                       // }
+                       // if (isOk) {
+                       // if (filever != null) {
+                       // try {
+                       // Revision.Format get = new Revision.Format(
+                       // getProjectSettings().getRevisionPattern());
+                       // Revision version = get.parse(filever);
+                       // if (version.isNull()) {
+                       // throw new ParseException(filever,
+                       // filever.length() - 1);
+                       // }
+                       // if (!version.isMinor()) {
+                       // _state = ProgressState.inCHECK;
+                       // }
+                       // setVersion(version.toString());
+                       // } catch (ParseException e) {
+                       // setErrorCode("message.error.format.version");
+                       // isOk = false;
+                       // }
+                       // }
+                       // if (isOk) {
+                       // _docname = tool.extractProperty("title"); // Property kept even if the file is not referenced
+                       // isOk = extractDate(tool);
+                       // }
+                       // }
                }
                return isOk;
        }
@@ -253,8 +252,8 @@ public class ImportDocumentAction extends BaseUploadDocumentAction {
                                }
                                Publication addoc = getPublicationService().createDoc(
                                                _mystudy.getIndex(), step, _documentType,
-                                               user.getIndex(), _fileName, _docname, _state, _reference,
-                                               getVersion(), aDate, uses);
+                                               user.getIndex(), _fileName, _docname, _state,
+                                               _reference, getVersion(), aDate, uses);
 
                                if (_reference.length() > 0) { // Importation of a not foreign document
                                        _mystudy.updateSimulationContexts(); // In case of simulation contexts extracted from the imported document
index d750428009595c3c60544c01d9c0834cfa86a8b5..1ff8b0abe4545fa4b94fc35282b0d994e28e313e 100644 (file)
@@ -14,6 +14,9 @@ import org.splat.som.Step;
 import org.splat.wapp.Constants;
 import org.splat.wapp.Menu;
 
+/**
+ * New scenario creation action.
+ */
 public class NewScenarioAction extends Action {
 
        private transient OpenStudy _mystudy;
index acdb825c65178b8164d45cc53ca7c8b593fd9170..4a7e0a97d9d5f859d72962fc6256ae70cf157fae 100644 (file)
@@ -68,7 +68,7 @@ public class NewStudyAction extends Action {
                ResourceBundle locale = ResourceBundle.getBundle("labels",
                                getApplicationSettings().getCurrentLocale());
                _title = locale.getString("label.study") + " "
-                               + String.valueOf(number + 1);
+                               + (number + 1);
 
                initializationFullScreenContext(Constants.CREATE_MENU, Constants.NONE,
                                Constants.OPEN);
@@ -89,11 +89,9 @@ public class NewStudyAction extends Action {
         */
        public String doCreate() throws InvalidPropertyException,
                        MissedPropertyException, MultiplyDefinedException {
+               String res = SUCCESS;
                String[] input = _projectContext.split(",");
                int valid = Integer.valueOf(input[0]);
-               String value = ""; // input[1] if exists
-
-               Study.Properties sprop = new Study.Properties();
 
                // Check arguments and creation of the study
                if (valid == -1) {
@@ -102,58 +100,68 @@ public class NewStudyAction extends Action {
                                        .selectType("product");
                        _contelm = getSimulationContextService()
                                        .selectSimulationContextsWhere(cprop.setType(product));
-                       return INPUT; // Title empty, simply wait for input without error message
-               }
-               if (valid == 0) {
-                       value = input[1].trim();
-                       if (value.length() == 0) {
-                               initializationScreenContext(Constants.CREATE_MENU);
-                               return INPUT; // No need to reinitialize the list of existing products
+                       // Title empty, simply wait for input without error message
+                       res = INPUT;
+               } else {
+                       String value; // input[1] if exists
+                       if (valid == 0) {
+                               value = input[1].trim();
+                               if (value.length() == 0) {
+                                       initializationScreenContext(Constants.CREATE_MENU);
+                                       // No need to reinitialize the list of existing products
+                                       res = INPUT;
+                               }
+                       } else {
+                               value = "";
                        }
-               }
-               sprop.setTitle(_title).setManager(getConnectedUser());
-               sprop.checkValidity();
-               sprop.disableCheck();
-               try {
-                       // Addition of a default scenario
-                       ResourceBundle locale = ResourceBundle.getBundle("labels",
-                                       getApplicationSettings().getCurrentLocale());
-                       Scenario.Properties oprop = new Scenario.Properties();
-                       oprop.setTitle(locale.getString("label.scenario") + " 1");
+                       if (SUCCESS.equals(res)) {
+                               Study.Properties sprop = new Study.Properties();
 
-                       // Addition of the entered project context
-                       SimulationContext.Properties cprop = new SimulationContext.Properties();
-                       if (valid == 0) { // Input of new project context
-                               SimulationContextType product = getSimulationContextService()
-                                               .selectType("product");
-                               
-                               SimulationContext testContext = getSimulationContextService().selectSimulationContext(product, value);
-                               
-                               if (testContext == null) {
-                               cprop.setType(
-                                               getSimulationContextService().selectType("product"))
-                                               .setValue(value);
-                               } else {
-                                       cprop.setIndex(testContext.getIndex());
+                               sprop.setTitle(_title).setManager(getConnectedUser());
+                               sprop.checkValidity();
+                               sprop.disableCheck();
+                               try {
+                                       // Addition of a default scenario
+                                       ResourceBundle locale = ResourceBundle.getBundle("labels",
+                                                       getApplicationSettings().getCurrentLocale());
+                                       Scenario.Properties oprop = new Scenario.Properties();
+                                       oprop.setTitle(locale.getString("label.scenario") + " 1");
+               
+                                       // Addition of the entered project context
+                                       SimulationContext.Properties cprop = new SimulationContext.Properties();
+                                       if (valid == 0) { // Input of new project context
+                                               SimulationContextType product = getSimulationContextService()
+                                                               .selectType("product");
+                                               
+                                               SimulationContext testContext = getSimulationContextService().selectSimulationContext(product, value);
+                                               
+                                               if (testContext == null) {
+                                               cprop.setType(
+                                                               getSimulationContextService().selectType("product"))
+                                                               .setValue(value);
+                                               } else {
+                                                       cprop.setIndex(testContext.getIndex());
+                                               }
+                                       } else { // Selection of existing project context
+                                               cprop.setIndex(valid);
+                                       }
+                                       Study study = getScenarioService().createStudy(sprop, oprop, cprop);
+                                       // Update of the session
+                                       number += 1;
+                                       open(study); // Opens the study,
+               
+                                       initializationFullScreenContext(Constants.STUDY_MENU,
+                                                       Constants.NONE, Constants.OPEN);
+               
+                               } catch (Exception error) {
+                                       LOG.error("Unable to save the study, reason:", error);
+                                       setErrorCode("message.error.newstudy");
+                                       initializationScreenContext(Constants.NONE);
+                                       res = ERROR;
                                }
-                       } else { // Selection of existing project context
-                               cprop.setIndex(valid);
                        }
-                       Study study = getScenarioService().createStudy(sprop, oprop, cprop);
-                       // Update of the session
-                       number += 1;
-                       open(study); // Opens the study,
-
-                       initializationFullScreenContext(Constants.STUDY_MENU,
-                                       Constants.NONE, Constants.OPEN);
-
-                       return SUCCESS;
-               } catch (Exception error) {
-                       LOG.error("Unable to save the study, reason:", error);
-                       setErrorCode("message.error.newstudy");
-                       initializationScreenContext(Constants.NONE);
-                       return ERROR;
                }
+               return res;
        }
        
        /**
@@ -167,12 +175,9 @@ public class NewStudyAction extends Action {
                if( LOG.isDebugEnabled() ) {
                        LOG.debug("--- validate");
                }
-               com.opensymphony.xwork2.ActionContext context = 
-                       com.opensymphony.xwork2.ActionContext.getContext();
-               
                if( LOG.isDebugEnabled() ) {
                        LOG.debug("======> MKA test");
-                       LOG.debug(context.getName());
+                       LOG.debug(com.opensymphony.xwork2.ActionContext.getContext().getName());
                }
        }
 
index af1c0d3a5b6d862550a2a978e4c56879b12827d4..dded4fbd94ee25eca1c8b6f3aeff6c58320661e3 100644 (file)
@@ -11,18 +11,20 @@ menu.step.4   = G
 #menu.step.5   = Entrer les conditions de calcul
 menu.step.5   = Effectuer le calcul
 menu.step.6   = Analyser les résultats
-menu.step.7   = Capitaliser ce cas d''étude
-menu.step.8   = Finaliser l''étude
+menu.step.7   = Schéma de calcul
+menu.step.8   = Capitaliser ce cas d''étude
+menu.step.9   = Finaliser l''étude
 
 folder.step.1 = Spécification de l''étude
 folder.step.2 = Description du scénario
 folder.step.3 = Géométrie
 folder.step.4 = Modèle d''analyse
 #folder.step.5 = Conditions de calcul
-folder.step.5 = Schéma de calcul
+folder.step.5 = Exécution de calcul
 folder.step.6 = Résultats
-folder.step.7 = Élements de connaissances
-folder.step.8 = Rapport final
+folder.step.7 = Schéma de calcul
+folder.step.8 = Élements de connaissances
+folder.step.9 = Rapport final
 
 type.document.requirements   = Cahier des charges
 type.document.specification  = Document de spécification
@@ -37,6 +39,7 @@ type.document.report         = Rapport final
 type.document.memorandum     = Note technique
 type.document.minutes        = Compte rendu
 type.document.coparisonResult= Study comparison result
+type.document.schema         = Calculation schema
 
 type.context.customer        = Client
 type.context.product         = Produit
index edd888bc3cbc0f30b6882a61867f8ff164a46c8a..1261b9657d02a60c9dc7d86b2b27f3bfff1f3f58 100644 (file)
@@ -11,18 +11,20 @@ menu.step.4   = Generate the analysis model
 #menu.step.5   = Enter the boundary conditions
 menu.step.5   = Execute the calculation
 menu.step.6   = Analyze the results
-menu.step.7   = Capitalize this use-case
-menu.step.8   = Finalize the study
+menu.step.7   = Calculation schema
+menu.step.8   = Capitalize this use-case
+menu.step.9   = Finalize the study
 
 folder.step.1 = Specification of the study
 folder.step.2 = Description of the scenario
 folder.step.3 = Geometry
 folder.step.4 = Analysis model
 #folder.step.5 = Boundary conditions
-folder.step.5 = Calculation scheme
+folder.step.5 = Calculation execution
 folder.step.6 = Calculation results
-folder.step.7 = Knowledge elements
-folder.step.8 = Final report
+folder.step.7 = Calculation schema
+folder.step.8 = Knowledge elements
+folder.step.9 = Final report
 
 type.document.requirements   = Customer requirements
 type.document.specification  = Specification document
@@ -37,6 +39,7 @@ type.document.report         = Final report
 type.document.memorandum     = Technical report
 type.document.minutes        = Minute meeting
 type.document.coparisonResult= Study comparison result
+type.document.schema         = Calculation schema
 
 type.context.customer        = Customer
 type.context.product         = Product
index 4ff995c9ab3c368dc4afaa7362569693d975c39f..d1a62f4567f05aa2874e70a5e7b1d207c1a6c522 100644 (file)
@@ -26,8 +26,8 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="basenames">
                        <list>
                                <value>conf/log-messages</value>
-                <value>som</value>
-                <value>labels</value>
+                               <value>som</value>
+                               <value>labels</value>
                        </list>
                </property>
        </bean>
@@ -80,7 +80,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="projectSettings" ref="projectSettings" />
                <property name="knowledgeElementTypeService"
                        ref="knowledgeElementTypeService" />
-        <property name="publicationService" ref="publicationService" />
+               <property name="publicationService" ref="publicationService" />
        </bean>
 
        <bean id="openStudy" class="org.splat.simer.OpenStudy"
@@ -100,8 +100,8 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
        <bean id="invalidateAction"
                class="org.splat.simer.InvalidateAction" />
-    
-    <bean id="baseAction" class="org.splat.simer.Action"
+
+       <bean id="baseAction" class="org.splat.simer.Action"
                scope="prototype" abstract="true">
                <property name="applicationSettings" ref="applicationSettings" />
                <property name="openStudy" ref="openStudy" />
@@ -121,6 +121,12 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
+       <bean id="copyStudyAction" class="org.splat.simer.CopyStudyAction"
+               parent="newStudyAction" scope="prototype">
+        <property name="searchService" ref="searchService" />
+        <property name="stepsConfigService" ref="stepsConfigService" />
+       </bean>
+
        <bean id="newScenarioAction"
                class="org.splat.simer.NewScenarioAction" parent="baseAction"
                scope="prototype">
@@ -138,7 +144,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <bean id="importDocumentAction"
                class="org.splat.simer.ImportDocumentAction" scope="prototype"
                parent="baseAction">
-        <property name="studyService" ref="studyService" />
+               <property name="studyService" ref="studyService" />
                <property name="stepService" ref="stepService" />
                <property name="projectSettings" ref="projectSettings" />
                <property name="publicationService" ref="publicationService" />
@@ -156,8 +162,8 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <bean id="removeStudyAction"
                class="org.splat.simer.RemoveStudyAction" scope="prototype"
                parent="baseAction">
-        <property name="studyService" ref="studyService" />
-    </bean>
+               <property name="studyService" ref="studyService" />
+       </bean>
 
        <!--========= Inherited from displayStudyStepAction ========= -->
 
@@ -206,22 +212,22 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                        ref="knowledgeElementTypeService" />
                <property name="scenarioService" ref="scenarioService" />
        </bean>
-       
-    <bean id="editStepCommentAction"
-        class="org.splat.simer.EditStepCommentAction" scope="prototype"
-        parent="displayStudyStepAction">
-        <property name="stepService" ref="stepService" />
-    </bean>
-       
-    <bean id="editStudyDescriptionAction"
-        class="org.splat.simer.EditStudyDescriptionAction" scope="prototype"
+
+       <bean id="editStepCommentAction"
+               class="org.splat.simer.EditStepCommentAction" scope="prototype"
+               parent="displayStudyStepAction">
+               <property name="stepService" ref="stepService" />
+       </bean>
+
+       <bean id="editStudyDescriptionAction"
+               class="org.splat.simer.EditStudyDescriptionAction" scope="prototype"
                parent="displayStudyStepAction" />
-    
-    <bean id="CompareStudyAction"
-        class="org.splat.simer.CompareStudyAction" scope="prototype"
-        parent="displayStudyStepAction">
-        <property name="publicationService" ref="publicationService" />
-    </bean>
+
+       <bean id="CompareStudyAction"
+               class="org.splat.simer.CompareStudyAction" scope="prototype"
+               parent="displayStudyStepAction">
+               <property name="publicationService" ref="publicationService" />
+       </bean>
 
        <!-- End of Inherited from displayStudyStepAction -->
 
@@ -284,7 +290,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="projectSettings" ref="projectSettings" />
                <property name="publicationService" ref="publicationService" />
                <property name="stepService" ref="stepService" />
-        <property name="studyService" ref="studyService" />
+               <property name="studyService" ref="studyService" />
                <property name="repositoryService" ref="repositoryService" />
        </bean>
 
index 0f369c9f9ad1c504ba3cbf84b1a283de416d1623..172ee38e3a6edf933e4260018b0b6ccbf5b95445 100644 (file)
                        <result name="sysadmin" type="tiles">page.home</result>
                </action>
                <action name="select" class="menuAction" method="selectItem">
-                       <result name="new-empty" type="redirectAction">
-                               study/new-empty
-                       </result>
+            <result name="new-empty" type="redirectAction">
+                study/new-empty
+            </result>
+            <result name="new-copy" type="redirectAction">
+                study/new-copy
+            </result>
                        <result name="search-study" type="redirectAction">
                                study/search-study
                        </result>
                        <result name="success">/study/jsonCheckoutRes.jsp</result>
                </action>
 
-               <!-- Creation of a study
-               -->
-               <action name="new-empty" class="newStudyAction"
-                       method="initialize">
-                       <result name="success" type="tiles">page.newstudy</result>
-               </action>
-               <action name="valid-new" class="newStudyAction"
-                       method="create">
-                       <!--interceptor-ref name="siman-validation" /-->
-                       <result name="success" type="redirectAction">
-                               open-study?selection=0.1
-                       </result>
-                       <result name="input" type="tiles">page.newstudy</result>
-                       <result name="error" type="tiles">page.home</result>
-               </action>
+        <!-- Creation of a study
+        -->
+        <action name="new-empty" class="newStudyAction"
+            method="initialize">
+            <result name="success" type="tiles">page.newstudy</result>
+        </action>
+        <action name="valid-new" class="newStudyAction"
+            method="create">
+            <!--interceptor-ref name="siman-validation" /-->
+            <result name="success" type="redirectAction">
+                open-study?selection=0.1
+            </result>
+            <result name="input" type="tiles">page.newstudy</result>
+            <result name="error" type="tiles">page.home</result>
+        </action>
+
+        <!-- Creation of a new study from existing one
+        -->
+        <action name="new-copy" class="copyStudyAction"
+            method="initialize">
+            <result name="success" type="tiles">page.newcopy</result>
+        </action>
+        <action name="valid-copy" class="copyStudyAction"
+            method="create">
+            <result name="success" type="redirectAction">
+                open-study?selection=0.1
+            </result>
+            <result name="input" type="tiles">page.newcopy</result>
+            <result name="error" type="tiles">page.home</result>
+        </action>
 
                <!-- Search for studies, knowledge elements and documents
                -->