Salome HOME
Fix: document removing is fixed. Unit tests for StudyDAO and StepService.removeDocume...
authorrkv <rkv@opencascade.com>
Fri, 21 Dec 2012 09:01:38 +0000 (09:01 +0000)
committerrkv <rkv@opencascade.com>
Fri, 21 Dec 2012 09:01:38 +0000 (09:01 +0000)
40 files changed:
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/ActorRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/ConvertsRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/DocumentType.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/StampRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml
Workspace/Siman-Common/src/org/splat/dal/bo/som/UsedByRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/UsesRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycleRelation.java
Workspace/Siman-Common/src/org/splat/dal/bo/som/VersionsRelation.java
Workspace/Siman-Common/src/org/splat/service/StepService.java
Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java
Workspace/Siman-Common/src/spring/businessServiceContext.xml
Workspace/Siman-Common/src/test/splat/dao/TestStudyDAO.java [new file with mode: 0644]
Workspace/Siman-Common/src/test/splat/service/TestStepService.java [new file with mode: 0644]
Workspace/Siman-Common/testng-stepService.xml [new file with mode: 0644]
Workspace/Siman/WebContent/WEB-INF/lib/jsonplugin-0.34.jar [new file with mode: 0644]
Workspace/Siman/WebContent/jap/splat-launcher.jar
Workspace/Siman/WebContent/jap/splat-signedlauncher.jar
Workspace/Siman/WebContent/jsp/menuitem.jsp
Workspace/Siman/WebContent/layout/homeLayout.jsp
Workspace/Siman/WebContent/study/editScenarioProperties.jsp
Workspace/Siman/src/hibernate.properties
Workspace/Siman/src/jdbc.properties
Workspace/Siman/src/org/splat/simer/Action.java
Workspace/Siman/src/org/splat/simer/ApplicationSettings.java
Workspace/Siman/src/org/splat/simer/ConnectionAction.java
Workspace/Siman/src/org/splat/simer/Converter.java
Workspace/Siman/src/org/splat/simer/EditDocumentAction.java
Workspace/Siman/src/org/splat/simer/EditStudyAction.java
Workspace/Siman/src/org/splat/simer/ExceptionAction.java [new file with mode: 0644]
Workspace/Siman/src/org/splat/simer/StudyPropertiesAction.java
Workspace/Siman/src/spring/applicationContext.xml
Workspace/Siman/src/struts.xml

index c66a7ce204cc00469fcfc4fded326d01a9b33790..bb8f0d490aa404f411fe80570f3323fb49996034 100644 (file)
@@ -1,4 +1,5 @@
 package org.splat.dal.bo.kernel;
+
 /**
  * Abstract root class of persistent objects supporting relations to other persistent objects.<br/>
  * Relations are instances of concrete subclasses of Relation that are assigned to Entity objects at run time.<br/>
@@ -10,93 +11,166 @@ package org.splat.dal.bo.kernel;
  * @copyright OPEN CASCADE 2012
  */
 
+import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-import java.util.Vector;
 
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MissedPropertyException;
 import org.splat.kernel.MultiplyDefinedException;
 import org.splat.kernel.ObjectProperties;
+import org.splat.log.AppLogger;
 
-
+/**
+ * Persistent entity class. Entity can have relations to other persistent objects.
+ */
 public abstract class Entity extends Any {
 
-    private final Set<Relation> relations = new HashSet<Relation>();
-
-//  ==============================================================================================================================
-//  Constructors
-//  ==============================================================================================================================
-
-//  Database fetch constructor
-    protected Entity () {
-    }
-//  Initialization constructor
-    protected Entity (final ObjectProperties prop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-      super(prop);
-    }
-
-//  ==============================================================================================================================
-//  Public member functions
-//  ==============================================================================================================================
-
-    public Relation getFirstRelation (final Class<? extends Relation> type) {
-//  -----------------------------------------------------------------
-      for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
-       Relation link = i.next();
-       if (link.getClass().equals(type)) {
-                       return link;
+       /**
+        * The service logger.
+        */
+       public final static AppLogger LOG = AppLogger.getLogger(Entity.class);
+
+       /**
+        * Persistent collection of relations to other persistent objects.
+        */
+       private final Set<Relation> relations = new HashSet<Relation>(); // NOPMD:RKV: mapped as field
+
+       /**
+        * Database fetch constructor.
+        */
+       protected Entity() {
+               super();
+       }
+
+       /**
+        * Initialization constructor.
+        * 
+        * @param prop
+        *            object properties
+        * @throws MissedPropertyException
+        *             if some mandatory property is missed
+        * @throws InvalidPropertyException
+        *             if some property has invalid value
+        * @throws MultiplyDefinedException
+        *             if some property is defined several times
+        */
+       protected Entity(final ObjectProperties prop)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException {
+               super(prop);
+       }
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       /**
+        * Get first relation of the given type.
+        * 
+        * @param type
+        *            the relation type to look for
+        * @return the found relation or null
+        */
+       public Relation getFirstRelation(final Class<? extends Relation> type) {
+               Relation found = null;
+               for (Relation link : relations) {
+                       if (link.getClass().equals(type)) {
+                               found = link;
+                       }
                }
-      }
-      return null;
-    }
-
-    public List<Relation> getRelations (final Class<? extends Relation> type) {
-      List<Relation> result = new Vector<Relation>();
-
-      for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
-       Relation link = i.next();
-       if (link.getClass().equals(type)) {
-                       result.add(link);
+               return found;
+       }
+
+       /**
+        * Get list of all relations of the given type.
+        * 
+        * @param type
+        *            the relation type to look for
+        * @return the list if found relations
+        */
+       public List<Relation> getRelations(final Class<? extends Relation> type) {
+               List<Relation> result = new ArrayList<Relation>();
+
+               for (Relation link : relations) {
+                       if (link.getClass().equals(type)) {
+                               result.add(link);
+                       }
                }
-      }
-      return result;
-    }
-
-//  ==============================================================================================================================
-//  Protected services
-//  ==============================================================================================================================
-
-    public Set<Relation> getAllRelations () {
-      return relations;
-    }
-
-    public Relation addRelation (Relation link) {
-
-      relations.add(link);
-
-      if (link.isBidirectional()) {
-       Entity to = (Entity)link.getTo();   // Bidirectional relation are necessarily between entities
-
-        link = link.getReverse();
-       to.relations.add(link);
-      }
-      return link;
-    }
-
-    public void removeRelation (final Class<? extends Relation> type, final Persistent to) {
-      for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
-       Relation link = i.next();
-       if (!link.getClass().equals(type)) {
-                       continue;
+               return result;
+       }
+
+       // ==============================================================================================================================
+       // Protected services
+       // ==============================================================================================================================
+
+       /**
+        * Get persistent collection of relations.
+        * 
+        * @return entity relations set
+        */
+       public Set<Relation> getAllRelations() {
+               return relations;
+       }
+
+       /**
+        * Add a relation for the entity. If the link is bidirectional then also add the reverse link to the referenced object.
+        * 
+        * @param link
+        *            the relation from this entity to some persistent object
+        * @return the reverse link if the given link is bidirectional otherwise returns the given link
+        */
+       public Relation addRelation(final Relation link) {
+
+               Relation back = link;
+               relations.add(link);
+
+               if (link.isBidirectional()) {
+                       Entity to = (Entity) link.getTo(); // Bidirectional relation are necessarily between entities
+
+                       back = link.getReverse();
+                       to.relations.add(back);
+               }
+               return back;
+       }
+
+       /**
+        * Remove the first relation of the given type to the given object.
+        * 
+        * @param type
+        *            the type of the relation to remove
+        * @param to
+        *            the referenced object to identify the relation to remove
+        * @return the removed relation
+        */
+       public Relation removeRelation(final Class<? extends Relation> type,
+                       final Persistent to) {
+               Relation res = null;
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("Try to remove the link " + type.getSimpleName()
+                                       + " from " + this.toString() + " to " + to.toString());
+               }
+               for (Relation link : relations) {
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("Compare the link " + link.toString());
+                               LOG.debug("link.getClass().equals(type): "
+                                               + link.getClass().equals(type));
+                       }
+                       if (link.getClass().equals(type) && link.getTo().equals(to)) {
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Remove the link "
+                                                       + link.getClass().getSimpleName() + " from "
+                                                       + this.toString() + " to " + to.toString());
+                               }
+                               res = link;
+                               break;
+                       }
                }
-       if (!link.getTo().equals(to)) {
-                       continue;
+               this.getAllRelations().remove(res);
+               if (res.isBidirectional()) {
+                       ((Entity)res.getTo()).getAllRelations().remove(res.getReverse());
                }
-       i.remove();
-       return;
-      }
-    }
+               return res;
+       }
 }
\ No newline at end of file
index a4a9ef9f2c96b816b4b57e4a2b7958ea64718155..bd34d98846fd7b0ea45595e837899d2576f99613 100644 (file)
                <param name="initial_value">1000</param>
         </generator>
        </id>
+<!--         <set name="references" inverse="true" lazy="false"
+            cascade="all-delete-orphan" access="field">
+            <key column="refer" on-delete="cascade"/>
+            <one-to-many class="org.splat.dal.bo.kernel.Relation" />
+        </set> -->
   </class>
 </hibernate-mapping>
\ No newline at end of file
index 2ffa7f558ef9194c237d0f5782241f535b401301..b8a52df6f9ade16e58147b9a2e4d86d339c9bdb9 100644 (file)
@@ -15,5 +15,8 @@
                <!-- Entity  owner -->
                <many-to-one name="owner" column="owner" access="field"
                        not-null="true" />
+        <!-- Referenced entity
+        <many-to-one cascade="merge" name="to" column="refer" access="property"
+            not-null="true" /> -->
        </union-subclass>
 </hibernate-mapping>
\ No newline at end of file
index 1ee3833e7b3a614c97c57bd0fe6d029e9f4f5e00..c5bc21ef8338955fca60bd11ce2749555a21306f 100644 (file)
@@ -1,10 +1,10 @@
 package org.splat.dal.bo.kernel;
+
+
 /**
- * Base implementation of relations between entities.<br/>
- * A relation makes a typed link from an entity to any kind persistent object. The relations are typed by subclasses of this
- * abstract class which define the actual object referenced by the relation.<br/>
- * This Relation base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses
- * by:
+ * Base implementation of relations between entities.<br/> A relation makes a typed link from an entity to any kind persistent object. The
+ * relations are typed by subclasses of this abstract class which define the actual object referenced by the relation.<br/> This Relation
+ * base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses by:
  * <ul>
  * <li>overriding the isBidirectional() and getReverseClass() methods,</li>
  * <li>creating the reverse relation in constructors.</li>
@@ -12,95 +12,89 @@ package org.splat.dal.bo.kernel;
  * Relation objects also support dynamic attributes provided by the Any class.
  * 
  * @see Entity
- * @author    Daniel Brunier-Coulin
+ * @author Daniel Brunier-Coulin
  * @copyright OPEN CASCADE 2012
  */
-
-import java.util.Iterator;
-
 public abstract class Relation extends Any {
 
-//  Persistent fields
-       protected  Entity   owner;        // Study or Document
-
-//  Transient field
-    protected  Relation reverse;
-
-//  ==============================================================================================================================
-//  Constructors
-//  ==============================================================================================================================
-
-//  Database fetch constructor
-    protected Relation () {
-//  ---------------------
-      reverse = null;
-    }
-//  Initialization constructor
-    protected Relation (Entity from) {
-//  --------------------------------
-      this.owner   = from;
-      this.reverse = null;          // Initialized by subclasses
-    }
-
-//  ==============================================================================================================================
-//  Public member functions
-//  ==============================================================================================================================
-
-    public Entity getFrom () {
-//  ------------------------
-      return owner;
-    }
-
-    public Relation getReverse () {
-//  -----------------------------
-      if (!this.isBidirectional() || reverse != null) return reverse;
-
-      Class<? extends Relation> type = this.getReverseClass();
-      Entity                    to   = (Entity)this.getTo();   // Bidirectional relations are necessarily between Entities
-
-      for (Iterator<Relation> i=to.getAllRelations().iterator(); i.hasNext(); ) {
-       Relation asked = i.next();
-       if (!asked.getClass().equals(type)) continue;
-       if (!asked.getTo().equals(owner))   continue;
-       reverse = asked;
-       reverse.reverse = this;     // For benefiting from this execution
-       return reverse;
-      }
-      return null;
-    }
-
-    public Class<? extends Relation> getReverseClass () {
-//  ---------------------------------------------------
-      return null;
-    }
-
-    public boolean isBidirectional () {
-//  ---------------------------------
-      return false;
-    }
-
-/**
- * Moves this relation from its current owner entity to the given one.
- * 
- * @param nowner the document to which this relation is moved
- * */
-    public void moveTo (Entity nowner) {
-
-      Entity oldOwner = this.owner;
-      this.owner = nowner;
-      nowner.getAllRelations().add(this);
-      oldOwner.getAllRelations().remove(this);
-
-      if (this.isBidirectional()) {
-       Relation  link = this.getReverse();
-       link.setTo(nowner);
-      }
-    }
-
-//  ==============================================================================================================================
-//  Abstract functions
-//  ==============================================================================================================================
-
-    public    abstract Persistent getTo ();
-    protected abstract void       setTo (Persistent to);         // For the need of the moveTo() method
+       // Persistent fields
+       protected Entity owner; // Study or Document
+
+       // Transient field
+       protected Relation reverse;
+
+       // ==============================================================================================================================
+       // Constructors
+       // ==============================================================================================================================
+
+       // Database fetch constructor
+       protected Relation() {
+               reverse = null;
+       }
+
+       // Initialization constructor
+       protected Relation(final Entity from) {
+               this.owner = from;
+               this.reverse = null; // Initialized by subclasses
+       }
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       public Entity getFrom() {
+               return owner;
+       }
+
+       public Relation getReverse() {
+               if (this.isBidirectional() && reverse == null) {
+                       Class<? extends Relation> type = this.getReverseClass();
+                       Entity to = (Entity) this.getTo(); // Bidirectional relations are necessarily between Entities
+
+                       for (Relation asked : to.getAllRelations()) {
+                               if (asked.getClass().equals(type)
+                                               && asked.getTo().equals(owner)) {
+                                       reverse = asked;
+                                       reverse.reverse = this; // For benefiting from this execution
+                                       break;
+                               }
+                       }
+               }
+               return reverse;
+       }
+
+       public Class<? extends Relation> getReverseClass() {
+               return null;
+       }
+
+       public boolean isBidirectional() {
+               return false;
+       }
+
+       /**
+        * Moves this relation from its current owner entity to the given one.
+        * 
+        * @param nowner
+        *            the document to which this relation is moved
+        */
+       public void moveTo(final Entity nowner) {
+
+               Entity oldOwner = this.owner;
+               this.owner = nowner;
+               nowner.getAllRelations().add(this);
+               oldOwner.getAllRelations().remove(this);
+
+               if (this.isBidirectional()) {
+                       Relation link = this.getReverse();
+                       link.setTo(nowner);
+               }
+       }
+
+       // ==============================================================================================================================
+       // Abstract functions
+       // ==============================================================================================================================
+
+       public abstract Persistent getTo();
+
+       public abstract void setTo(Persistent to); // For the need of the moveTo() method
 }
\ No newline at end of file
index 98fdf8abd4f9d67516c7ab9ae0db549a000c64ee..8d463946c5d92c09e5ec59165c766af7a7971240 100644 (file)
@@ -31,7 +31,7 @@ public abstract class ActorRelation extends Relation {
     protected ActorRelation () {
     }
 //  ActorRelation subclasses constructor
-    protected ActorRelation (Study from, User to) {
+    protected ActorRelation (final Study from, final User to) {
 //  ---------------------------------------------
       super(from);
       this.refer = to;
@@ -46,7 +46,8 @@ public abstract class ActorRelation extends Relation {
 //  --------------------
       return refer;
     }
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (User)to;
     }
index 1e79f757b27a7e715b739ab7992a85e412f098fc..b23f650308292cfbe765746dbb9f746c4bc1c577 100644 (file)
@@ -29,20 +29,22 @@ public class ConvertsRelation extends Relation {
       description = null;
     }
 //  Initialization constructors
-    protected ConvertsRelation (Document from, File to) {
+    protected ConvertsRelation (final Document from, final File to) {
 //  ---------------------------------------------------
       super(from);
       this.refer       = to;
       this.got         = true;
       this.description = null;          // Conversion not described
     }
-    public ConvertsRelation (Document from, File to, String description) {
+    public ConvertsRelation (final Document from, final File to, final String description) {
 //  -----------------------------------------------------------------------
       super(from);
       this.refer       = to;
       this.got         = true;
       this.description = description;   // May be null
-      if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
+      if (description != null) {
+               this.setAttribute( new DescriptionAttribute(this, description) );
+       }
     }
 
 //  ==============================================================================================================================
@@ -53,17 +55,22 @@ public class ConvertsRelation extends Relation {
 //  -------------------------------
       if (!got) {
         DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
-        if (field != null) description = field.getValue();
+        if (field != null) {
+                       description = field.getValue();
+               }
         got = true;                     // Don't need to be modified later as set and remove attribute functions are private to this class
       }
       return description;               // May be null
     }
 
-    public File getTo () {
+    @Override
+       public File getTo () {
 //  --------------------
       return refer;
     }
-    protected void setTo (Persistent to) {
+    
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (File)to;
     }
index 4e285ecc6953d6b85465f63dadab82d4715cc0c0..d86176c0a018ab574c305764532524189d0238a2 100644 (file)
@@ -302,6 +302,8 @@ public class DocumentType extends Persistent {
                this.step = tprop.step;
                this.result = tprop.result;
                this.uses.clear();
-               this.uses.addAll(Arrays.asList(tprop.uses));
+               if (tprop.uses != null) {
+                       this.uses.addAll(Arrays.asList(tprop.uses));
+               }
        }
 }
\ No newline at end of file
index d5e6f08d04de5d574d9d4a8b95914d2b6f42d99c..c5a26d5868a6d06e4eb5c72c65a6694553da2186 100644 (file)
@@ -13,7 +13,7 @@
 <!-- Publication properties
   -->
     <!-- Document       mydoc -->    
-    <many-to-one  name="mydoc" column="doc"   access="field" not-null="true"/>
+    <many-to-one  name="mydoc" column="doc" cascade="merge"  access="field" not-null="true"/>
     
     <!-- ProjectElement owner -->    
     <many-to-one  name="owner" column="owner" access="field" not-null="true" />
index 6ec782e06d908f1c1fae299e16e9030ee8f1ec6a..5dd0fb7dd2cc957d49342e239b913a06629aab50 100644 (file)
 <!-- Uses relation
   -->
     <union-subclass name="org.splat.dal.bo.som.UsesRelation" extends="org.splat.dal.bo.kernel.Relation" table="uses_rel">
-               <many-to-one name="refer" column="refer" access="field" not-null="true" />
+               <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- UsedBy relation
   -->
     <union-subclass name="org.splat.dal.bo.som.UsedByRelation" extends="org.splat.dal.bo.kernel.Relation" table="usedby_rel">
-               <many-to-one name="refer" column="refer" access="field" not-null="true" />
+               <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Versions relation
   -->
     <union-subclass name="org.splat.dal.bo.som.VersionsRelation" extends="org.splat.dal.bo.kernel.Relation" table="versions_rel">
-        <many-to-one name="refer" column="refer" access="field" not-null="true" />
+        <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Converts relation
   -->
     <union-subclass name="org.splat.dal.bo.som.ConvertsRelation" extends="org.splat.dal.bo.kernel.Relation" table="converts_rel">
-        <many-to-one name="refer" column="refer" access="field" not-null="true" />
+        <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Contributor actor relation
   -->
     <union-subclass name="org.splat.dal.bo.som.ContributorRelation" extends="org.splat.dal.bo.kernel.Relation" table="contributor_rel">
-        <many-to-one name="refer" column="refer" access="field" not-null="true" />
+        <many-to-one cascade="merge" name="refer" column="refer" access="field" not-null="true" />
     </union-subclass>
 
 <!-- ValidationCycle relation
   -->
     <union-subclass name="org.splat.dal.bo.som.ValidationCycleRelation" extends="org.splat.dal.bo.kernel.Relation" table="cycle_rel">
 <!--       <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />-->
-               <many-to-one name="refer" column="refer" unique="true" access="field" not-null="true" />
+               <many-to-one cascade="merge" name="refer" column="refer" unique="true" access="field" not-null="true" />
     </union-subclass>
 
 <!-- Stamp relation
   -->
     <union-subclass name="org.splat.dal.bo.som.StampRelation" extends="org.splat.dal.bo.kernel.Relation" table="stamp_rel">
 <!--      <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />-->
-               <many-to-one name="refer" column="refer" unique="true" access="field" not-null="true" />
+               <many-to-one cascade="merge" name="refer" column="refer" unique="true" access="field" not-null="true" />
     </union-subclass>
 
 </hibernate-mapping>
\ No newline at end of file
index efad6f296c50f2e7698c1744c64e897a7fe64206..fb54359403f9a222ee8025a06beee411ca19ef9d 100644 (file)
@@ -11,7 +11,7 @@
   <union-subclass name="org.splat.dal.bo.som.Scenario" extends="org.splat.dal.bo.som.ProjectElement" table="scenario" lazy="false">
   
       <!-- Study owner                 -->    
-      <many-to-one name="owner" column="owner" insert="false" update="false" access="field" not-null="true" />
+      <many-to-one name="owner" column="owner" cascade="merge" insert="false" update="false" access="field" not-null="true" />
   
       <!-- int   sid                   -->
       <property    name="sid"   column="sid"   access="field" not-null="true" />    
index ef4cb1bf73c3562714ff84ad7aedc57d4c0f49b9..2b6162ddd94adaa4faeb75744e4d0904c957f3a5 100644 (file)
@@ -21,7 +21,7 @@ public class StampRelation extends Relation {
     protected StampRelation () {
     }
 //  Internal constructor
-    protected StampRelation (Document from, Timestamp to) {
+    protected StampRelation (final Document from, final Timestamp to) {
 //  -----------------------------------------------------
       super(from);
       this.refer = to;
@@ -31,7 +31,8 @@ public class StampRelation extends Relation {
 //  Public member functions
 //  ==============================================================================================================================
 
-    public Timestamp getTo () {
+    @Override
+       public Timestamp getTo () {
 //  -------------------------
       return refer;
     }
@@ -41,7 +42,8 @@ public class StampRelation extends Relation {
       return refer.getType();
     }
 
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
        refer = (Timestamp)to;
     }
index 1707b8ebd5b5e3e74f23af0d883fba03d993a97c..43d7a93c06a11dcf4d31209ac68c1788e6bdb5ec 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="delete-orphan" access="field">
+      <list name="scenarii" lazy="false" cascade="merge,delete-orphan" access="field">
         <key         column="owner" not-null="true" />
         <list-index  column="scendex"/>
         <one-to-many class="org.splat.dal.bo.som.Scenario" />
index b5dedd12b7846154d3886d3bb00754e3d1db43b9..5602fc9680c62d8a507d6c91f2be38be49470267 100644 (file)
@@ -21,14 +21,14 @@ public class UsedByRelation extends Relation {
     protected UsedByRelation () {
     }
 //  Initialization constructors
-    protected UsedByRelation (Document from, Document to) {
+    protected UsedByRelation (final Document from, final Document to) {
 //  -----------------------------------------------------
       super(from);
       this.refer   = to;
       this.reverse = new UsesRelation(this, to, from);
     }
 //  Internal constructor
-    protected UsedByRelation (Relation back, Document from, Document to) {
+    protected UsedByRelation (final Relation back, final Document from, final Document to) {
 //  --------------------------------------------------------------------
       super(from);
       this.refer   = to;
@@ -39,19 +39,23 @@ public class UsedByRelation extends Relation {
 //  Public member functions
 //  ==============================================================================================================================
 
-    public Class<? extends Relation> getReverseClass () {
+    @Override
+       public Class<? extends Relation> getReverseClass () {
 //  ---------------------------------------------------
       return UsesRelation.class;
     }
-    public Document getTo () {
+    @Override
+       public Document getTo () {
 //  -------------------------
       return refer;
     }
-    public boolean isBidirectional () {
+    @Override
+       public boolean isBidirectional () {
 //  ---------------------------------
       return true;
     }
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (Document)to;
     }
index e153992145ad3cddcdde1671cd1c8795a3a258be..2a71351e6fb43b4f5b83f8048eaa619dc90fa434 100644 (file)
@@ -21,14 +21,14 @@ public class UsesRelation extends Relation {
     protected UsesRelation () {
     }
 //  Initialization constructors
-    public UsesRelation (Document from, Document to) {
+    public UsesRelation (final Document from, final Document to) {
 //  ---------------------------------------------------
       super(from);
       this.refer   = to;
       this.reverse = new UsedByRelation(this, to, from);
     }
 //  Internal constructor
-    protected UsesRelation (Relation back, Document from, Document to) {
+    protected UsesRelation (final Relation back, final Document from, final Document to) {
 //  ------------------------------------------------------------------
       super(from);
       this.refer   = to;
@@ -39,20 +39,24 @@ public class UsesRelation extends Relation {
 //  Public member functions
 //  ==============================================================================================================================
 
-    public Class<? extends Relation> getReverseClass () {
+    @Override
+       public Class<? extends Relation> getReverseClass () {
 //  ---------------------------------------------------
       return UsedByRelation.class;
     }
 
-    public Document getTo () {
+    @Override
+       public Document getTo () {
 //  -------------------------
       return refer;
     }
-    public boolean isBidirectional () {
+    @Override
+       public boolean isBidirectional () {
 //  ---------------------------------
       return true;
     }
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (Document)to;
     }
index e3c4f15cbd37eb68d50bcfe57586b341e98499c2..007833d2e25e065dafb215c3f986fdd2ba6224d0 100644 (file)
@@ -21,7 +21,7 @@ public class ValidationCycleRelation extends Relation {
     protected ValidationCycleRelation () {
     }
 //  Internal constructor
-    protected ValidationCycleRelation (Study from, ValidationCycle to) {
+    protected ValidationCycleRelation (final Study from, final ValidationCycle to) {
 //  ------------------------------------------------------------------
       super(from);
       this.refer  = to;
@@ -42,12 +42,14 @@ public class ValidationCycleRelation extends Relation {
       return refer.getDocumentType();
     }
 
-    public ValidationCycle getTo () {
+    @Override
+       public ValidationCycle getTo () {
 //  -------------------------------
       return refer;
     }
 
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (ValidationCycle)to;
     }
index c4e92cfeb6e2a19e8021248d0b84927ba5faf6e1..b906cdf5f7694b10240a16d2b7e71b976a76e5a3 100644 (file)
@@ -29,20 +29,22 @@ public class VersionsRelation extends Relation {
       description = null;
     }
 //  Initialization constructors
-    public VersionsRelation (Document from, Document to) {
+    public VersionsRelation (final Document from, final Document to) {
 //  -------------------------------------------------------
       super(from);
       this.refer       = to;
       this.got         = true;
       this.description = null;          // Conversion not described
     }
-    public VersionsRelation (Document from, Document to, String description) {
+    public VersionsRelation (final Document from, final Document to, final String description) {
 //  ---------------------------------------------------------------------------
       super(from);
       this.refer       = to;
       this.got         = true;
       this.description = description;   // May be null
-      if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
+      if (description != null) {
+               this.setAttribute( new DescriptionAttribute(this, description) );
+       }
     }
 
 //  ==============================================================================================================================
@@ -53,17 +55,21 @@ public class VersionsRelation extends Relation {
 //  -------------------------------
       if (!got) {
         DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
-        if (field != null) description = field.getValue();
+        if (field != null) {
+                       description = field.getValue();
+               }
         got = true;                     // Don't need to be modified later as set and remove attribute functions are private to this class
       }
       return description;               // May be null
     }
 
-    public Document getTo () {
+    @Override
+       public Document getTo () {
 //  -------------------------
       return refer;
     }
-    protected void setTo (Persistent to) {
+    @Override
+       public void setTo (final Persistent to) {
 //  ------------------------------------
       refer = (Document)to;
     }
index bc93b46bddadf6233b091aa6f211c640019c72ce..95c1ccfd8f2ad8d80b0ecbe30b5c9aa997bc30ef 100644 (file)
@@ -161,15 +161,15 @@ public interface StepService {
        boolean remove(Step aStep, Publication oldoc);
 
        /**
-        * Remove a document from the given step.
+        * Remove a document from the given step and from the database if it is no more used.
         * 
         * @param aStep
         *            the study step
-        * @param doctag
-        *            the document publication
+        * @param docId
+        *            the document id
         * @return true if removing of the document succeeded
         */
-       boolean removeDocument(Step aStep, Publication doctag);
+       boolean removeDocument(Step aStep, long docId);
 
        /**
         * Get document types which are applicable for the given study step (activity).
index 4aae91f4cee24acfae520f79c0d1e411820784c6..c0e9e1f49f80724bbd607049ee506576dc9f5c6f 100644 (file)
@@ -13,7 +13,6 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
 import org.splat.dal.bo.kernel.Relation;
 import org.splat.dal.bo.som.ConvertsRelation;
@@ -28,9 +27,11 @@ import org.splat.dal.bo.som.SimulationContext;
 import org.splat.dal.bo.som.UsedByRelation;
 import org.splat.dal.bo.som.UsesRelation;
 import org.splat.dal.bo.som.VersionsRelation;
+import org.splat.dal.dao.kernel.RelationDAO;
 import org.splat.dal.dao.som.DocumentDAO;
 import org.splat.dal.dao.som.FileDAO;
 import org.splat.dal.dao.som.ProjectElementDAO;
+import org.splat.dal.dao.som.PublicationDAO;
 import org.splat.dal.dao.som.SimulationContextDAO;
 import org.splat.dal.dao.som.VersionsRelationDAO;
 import org.splat.kernel.InvalidPropertyException;
@@ -73,6 +74,10 @@ public class StepServiceImpl implements StepService {
         * Injected document DAO.
         */
        private DocumentDAO _documentDAO;
+       /**
+        * Injected relation DAO.
+        */
+       private RelationDAO _relationDAO;
        /**
         * Injected file DAO.
         */
@@ -97,6 +102,10 @@ public class StepServiceImpl implements StepService {
         * Injected project service.
         */
        private ProjectSettingsService _projectSettings;
+       /**
+        * Injected publication DAO.
+        */
+       private PublicationDAO _publicationDAO;
 
        /**
         * {@inheritDoc}
@@ -369,7 +378,7 @@ public class StepServiceImpl implements StepService {
                                                                aStep.getStep(), newFormat))) {
                        dprop.setFormat(newFormat);
                }
-               
+
                if (dprop.getAuthor() == null) {
                        dprop.setAuthor(previous.getAuthor());
                }
@@ -440,53 +449,68 @@ public class StepServiceImpl implements StepService {
         * @return true if removing of the publication succeeded
         */
        public boolean remove(final Step aStep, final Publication oldoc) {
-               boolean res = aStep.getOwner().remove(oldoc); // Updates the study in memory
-               if (res) {
-                       aStep.getDocuments().remove(oldoc); // Updates this step
-                       ProjectElement owner = aStep.getOwner();
-                       if (owner != null) {
-                               owner.remove(oldoc);
-                       }
-                       getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
-                       // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
+               aStep.getDocuments().remove(oldoc); // Updates this step
+               // Synchronize with database
+               ProjectElement owner = getProjectElementDAO().merge(aStep.getOwner());
+               if (owner != null) {
+                       aStep.getOwner().remove(oldoc); // in transient copy
+                       owner.remove(oldoc); // in persistent copy
                }
-               return res;
+               getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
+               // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
+               return true;
        }
 
        /**
-        * Remove a document from the given step.
+        * Remove a document from the given step and from the database if it is no more used.
         * 
         * @param aStep
         *            the study step
-        * @param doctag
-        *            the document publication
+        * @param docId
+        *            the document id
         * @return true if removing of the document succeeded
         */
        @Transactional
-       public boolean removeDocument(final Step aStep, final Publication doctag) {
-               Document value = doctag.value();
-               getDocumentDAO().update(value);
-               Publication torem = aStep.getDocument(value.getIndex());
-
+       public boolean removeDocument(final Step aStep, final long docId) {
+               Publication torem = aStep.getDocument(docId);
                boolean res = (torem != null);
                if (res) {
+                       torem = getPublicationDAO().merge(torem);
                        remove(aStep, torem);
-                       getProjectElementDAO().update(aStep.getOwner());
+                       Document value = torem.value();
                        if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
-                               Set<Relation> links = value.getAllRelations(); // Get all relation of the document to remove them
                                List<Document> using = new ArrayList<Document>();
-                               for (Iterator<Relation> i = links.iterator(); i.hasNext();) {
-                                       Relation link = i.next();
+                               List<Relation> converts = new ArrayList<Relation>();
+                               for (Relation link : value.getAllRelations()) {
                                        if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
-                                               getFileDAO().delete((File) link.getTo()); // The corresponding physical file is not removed from the vault
+                                               converts.add(link);
                                        } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
                                                using.add((Document) link.getTo());
                                        }
                                }
-                               for (Iterator<Document> i = using.iterator(); i.hasNext();) {
-                                       i.next().removeRelation(UsedByRelation.class, value); // TODO: RKV: don't use Database.getSession in removeRelation
+//                             value.getAllRelations().removeAll(converts);
+                               // Remove relations from depending documents
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Remove " + using.size() + " UsedByRelation(s).");
+                               }
+                               for (Document doc : using) {
+                                       if (LOG.isDebugEnabled()) {
+                                               LOG.debug("Remove UsedByRelation from "
+                                                               + doc.getTitle() + " to " + value.getTitle());
+                                       }
+                                       doc.removeRelation(UsedByRelation.class, value);
                                }
+                               // Synchronize deleted objects with the database to avoid hibernate exception
+                               // related with null value of not-nullable property because back reference from Document to Publication is not mapped:
+                               // org.hibernate.PropertyValueException: not-null property references a null or transient value:
+                               // org.splat.dal.bo.som.Publication.mydoc
+                               getDocumentDAO().flush(); // To show to the database that files from ConvertsRelation(s) are deleted already
                                getDocumentDAO().delete(value); // The corresponding physical file is not removed from the vault
+                               // Delete document's files
+                               for (Relation link : converts) {
+                                       File file = (File) link.getTo();
+                                       getFileDAO().delete(file); // The corresponding physical file is not removed from the vault
+                               }
                        }
                }
                return res;
@@ -686,4 +710,42 @@ public class StepServiceImpl implements StepService {
                        final ProjectSettingsService projectSettingsService) {
                _projectSettings = projectSettingsService;
        }
+
+       /**
+        * Get the publicationDAO.
+        * 
+        * @return the publicationDAO
+        */
+       public PublicationDAO getPublicationDAO() {
+               return _publicationDAO;
+       }
+
+       /**
+        * Set the publicationDAO.
+        * 
+        * @param publicationDAO
+        *            the publicationDAO to set
+        */
+       public void setPublicationDAO(final PublicationDAO publicationDAO) {
+               this._publicationDAO = publicationDAO;
+       }
+
+       /**
+        * Get the relationDAO.
+        * 
+        * @return the relationDAO
+        */
+       public RelationDAO getRelationDAO() {
+               return _relationDAO;
+       }
+
+       /**
+        * Set the relationDAO.
+        * 
+        * @param relationDAO
+        *            the relationDAO to set
+        */
+       public void setRelationDAO(final RelationDAO relationDAO) {
+               _relationDAO = relationDAO;
+       }
 }
index 201c9e57c973695ca1ba01b7dfd86d27c931c156..e8cbab3bb9dc66cfda96aaa091b6f59d8a15ccc6 100644 (file)
@@ -107,8 +107,10 @@ http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
 
        <bean id="stepService" class="org.splat.service.StepServiceImpl">
                <property name="indexService" ref="indexService" />
-               <property name="documentDAO" ref="documentDAO" />
-               <property name="fileDAO" ref="fileDAO" />
+        <property name="documentDAO" ref="documentDAO" />
+        <property name="relationDAO" ref="relationDAO" />
+        <property name="publicationDAO" ref="publicationDAO" />
+        <property name="fileDAO" ref="fileDAO" />
                <property name="documentService" ref="documentService" />
                <property name="documentTypeService" ref="documentTypeService" />
                <property name="simulationContextService"
diff --git a/Workspace/Siman-Common/src/test/splat/dao/TestStudyDAO.java b/Workspace/Siman-Common/src/test/splat/dao/TestStudyDAO.java
new file mode 100644 (file)
index 0000000..18e6b8f
--- /dev/null
@@ -0,0 +1,728 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   12 Oct 2012
+ * @author         $Author$
+ * @version        $Revision$
+ *****************************************************************************/
+package test.splat.dao;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Restrictions;
+import org.splat.dal.bo.kernel.User;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
+import org.splat.dal.bo.som.ProgressState;
+import org.splat.dal.bo.som.ProjectElement;
+import org.splat.dal.bo.som.Publication;
+import org.splat.dal.bo.som.Scenario;
+import org.splat.dal.bo.som.Study;
+import org.splat.dal.bo.som.Document.Properties;
+import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.StudyDAO;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.log.AppLogger;
+import org.splat.service.DocumentTypeService;
+import org.splat.service.PublicationService;
+import org.splat.service.StepService;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.ProjectSettingsService.Step;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.orm.hibernate3.HibernateTemplate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import test.splat.common.BaseTest;
+
+/**
+ * Test class for KnowledgeElementDAO.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ * 
+ */
+public class TestStudyDAO extends BaseTest {
+
+       /**
+        * Logger for the class.
+        */
+       private static final AppLogger LOG = AppLogger
+                       .getLogger(TestStudyDAO.class);
+
+       /**
+        * The tested StudyDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyDAO")
+       private transient StudyDAO _studyDAO;
+
+       /**
+        * The PublicationService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("publicationService")
+       private transient PublicationService _publicationService;
+
+       /**
+        * The StepService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("stepService")
+       private transient StepService _stepService;
+
+       /**
+        * The ProjectSettingsService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectSettings")
+       private transient ProjectSettingsService _projectSettings;
+
+       /**
+        * The DocumentTypeService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("documentTypeService")
+       private transient DocumentTypeService _documentTypeService;
+
+       /**
+        * Test creation of a study.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's create method for a good transient study.</i><BR>
+        * <i>2. call DAO's create method for a study with non-zero id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Object is created in the database successfully<BR>
+        * </li>
+        * <li>Another new object is created with new generated id<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testCreate() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testCreate()");
+               startNestedTransaction();
+
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               long id = _studyDAO.create(aStudy);
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               LOG.debug("Created id: " + id);
+
+               Study aStudyFound = getHibernateTemplate().get(Study.class, id);
+               _studyDAO.flush();
+
+               // Call DAO's create method for a study with non-zero id.
+               Study aBadStudy = new Study((new Study.Properties()).setTitle(
+                               "2.Bad test study").setManager(aStudy.getAuthor()).setDate(
+                               aStudy.getDate()).setReference("sid"));
+               aBadStudy.setIndex(aStudyFound.getIndex());
+
+               _studyDAO.flush();
+               List<Study> res = _studyDAO.getAll(Order.asc("rid"));
+
+               Assert.assertNotNull(res,
+                               "Method getFilteredList must not return null.");
+               Assert.assertEquals(res.size(), 1, "Number of found objects is wrong.");
+               Assert.assertEquals(aBadStudy.getIndex(), id, "Id must be equal.");
+
+               Assert.assertNotNull(aBadStudy.getIndex(),
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(aBadStudy.getIndex() > 0,
+                               "The new id is not a positive number.");
+
+               long id2 = _studyDAO.create(aBadStudy);
+
+               _studyDAO.flush();
+
+               LOG.debug("Created second id: " + id2);
+
+               res = _studyDAO.getAll();
+               _studyDAO.flush();
+
+               Assert.assertNotNull(res,
+                               "Method getFilteredList must not return null.");
+               Assert.assertNotNull(res.get(0),
+                               "Method getFilteredList must not return null.");
+               Assert.assertNotNull(res.get(1),
+                               "Method getFilteredList must not return null.");
+               Assert.assertEquals(res.size(), 2, "Number of found objects is wrong.");
+               Assert.assertEquals(res.get(0).getIndex(), id,
+                               "Sorting is incorrect or id of the first element is wrong.");
+               Assert.assertEquals(res.get(1).getIndex(), id2,
+                               "Sorting is incorrect or id of the second element is wrong.");
+               id = res.get(0).getIndex();
+               id2 = res.get(1).getIndex();
+               Assert.assertFalse(id == id2, "Ids of objects must not be duplicated.");
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testCreate()");
+       }
+
+       /**
+        * Test of getting a study.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to get it from the database.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's read method for an existing id.</i><BR>
+        * <i>2. call DAO's read method for a not existing id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Object is found in the database successfully<BR>
+        * </li>
+        * <li>Result of search is null<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testGet() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testGet()");
+               startNestedTransaction();
+
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = aStudy.getIndex();
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               // Call DAO's get method for an existing id.
+               _studyDAO.flush();
+               getHibernateTemplate().evict(aStudy);
+               getHibernateTemplate().clear();
+               Study aStudyFound = _studyDAO.get(id);
+
+               // Call DAO's get method for a not existing id.
+               aStudyFound = _studyDAO.get(-1L);
+               getHibernateTemplate().flush();
+               Assert.assertNull(aStudyFound,
+                               "A found object with not existing id must be null.");
+
+               aStudyFound = _studyDAO.get(0L);
+               getHibernateTemplate().flush();
+               Assert.assertNull(aStudyFound,
+                               "A found object with not existing id must be null.");
+
+               aStudyFound = _studyDAO.get(id + 1);
+               getHibernateTemplate().flush();
+               Assert.assertNull(aStudyFound,
+                               "A found object with not existing id must be null.");
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testGet()");
+       }
+
+       /**
+        * Test of updating a study.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to update it with another data.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's update method for an existing id.</i><BR>
+        * <i>2. call DAO's update method for a not existing id.</i><BR>
+        * <i>3. call DAO's update method for wrong data.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Object is update in the database successfully<BR>
+        * </li>
+        * <li>Exception is thrown<BR>
+        * </li>
+        * <li>Exception is thrown<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testUpdate() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testUpdate()");
+               startNestedTransaction();
+
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = _studyDAO.create(aStudy);
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+               // Call DAO's update method for an existing id.
+               Assert.assertTrue(aStudy.getProgressState() != ProgressState.APPROVED,
+                               "The initial state of the study should not be APPROVED.");
+               aStudy.setProgressState(ProgressState.APPROVED);
+               aStudy.setTitle(aStudy.getTitle() + " updated");
+               _studyDAO.update(aStudy);
+
+               // Check that the object has been updated.
+               Study aStudyFound = _studyDAO.get(id);
+
+               // Call DAO's create method for a study with non-zero id.
+               Study aBadStudy = new Study((new Study.Properties()).setTitle(
+                               "Test study").setManager(aStudy.getAuthor()).setDate(
+                               aStudy.getDate()));
+               // aBadKelm.setIndex(aKelmFound.getIndex());
+               try {
+                       _studyDAO.update(aBadStudy);
+                       getHibernateTemplate().flush();
+                       Assert.fail("Update with not existing id must be failed.");
+               } catch (Exception e) {
+                       LOG.debug("Expected exception is thrown: "
+                                       + e.getClass().getSimpleName() + ": " + e.getMessage());
+               }
+               // Call update with bad data (null title).
+               aBadStudy.setIndex(aStudyFound.getIndex());
+               aBadStudy.setTitle(null);
+               try {
+                       _studyDAO.update(aBadStudy);
+                       getHibernateTemplate().flush();
+                       Assert.fail("Update with null title must be failed.");
+               } catch (Exception e) {
+                       LOG.debug("Expected exception is thrown: "
+                                       + e.getClass().getSimpleName() + ": " + e.getMessage());
+               }
+               // Call update with bad data (null state).
+               aBadStudy.setTitle(aStudyFound.getTitle());
+               aBadStudy.setProgressState(null);
+               try {
+                       _studyDAO.update(aBadStudy);
+                       getHibernateTemplate().flush();
+                       Assert.fail("Update with null state must be failed.");
+               } catch (Exception e) {
+                       LOG.debug("Expected exception is thrown: "
+                                       + e.getClass().getSimpleName() + ": " + e.getMessage());
+               }
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testUpdate()");
+       }
+
+       /**
+        * Test of deleting a study.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and try to delete it.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call DAO's delete method for an existing id.</i><BR>
+        * <i>2. call DAO's delete method for a not existing id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Object is found in the database successfully<BR>
+        * </li>
+        * <li>Exception is thrown<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testDelete() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testDelete()");
+               startNestedTransaction();
+
+               Study aStudy = createStudy();
+               // Call DAO's create method for a good transient study.
+               Long id = aStudy.getIndex();//_studyDAO.create(aStudy);
+               Assert.assertNotNull(id,
+                               "Create method returns null instead of a new id.");
+               Assert.assertTrue(id > 0, "The new id is not a positive number.");
+               _studyDAO.flush();
+
+               // Call DAO's delete method for an existing id.
+               _studyDAO.merge(aStudy);
+               _studyDAO.delete(aStudy);
+
+               // Check that the object has been deleted.
+               Study aStudyFound = _studyDAO.get(id);
+
+               Assert.assertNull(aStudyFound, "Deleted object must not be found.");
+               // Call DAO's delete method for a not existing id.
+               getHibernateTemplate().flush();
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testDelete()");
+       }
+
+       /**
+        * Test of getting a filtered list of studys.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create two studys and try to get them from the database.</i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. Find objects with the given value of the property of a child object.</i><BR>
+        * <i>2. Get ordered list of objects with the given value of the property of a child object.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>Objects are found in the database successfully<BR>
+        * </li>
+        * <li>Objects are found in the database and sorted in the right order<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws SQLException
+        * @throws IOException
+        * 
+        */
+       @Test
+       public void testGetFilteredList() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testGetFilteredList()");
+               startNestedTransaction();
+
+               // Create several objects in the database
+               Study aStudy = createStudy();
+               long id = _studyDAO.create(aStudy);
+               Study aNewStudy = new Study((new Study.Properties()).setTitle(
+                               "TST_Study N2").setManager(aStudy.getAuthor()).setReference(
+                               "sid").setDate(aStudy.getDate()));
+               long id2 = _studyDAO.create(aNewStudy);
+
+               _studyDAO.flush();
+
+               // ////////////////////////////////////////////////////
+               // Call DAO's getFilteredList method without order parameter.
+               List<Study> res = _studyDAO.getFilteredList("manager", Restrictions.eq(
+                               "username", aStudy.getAuthor().getUsername()));
+
+               Assert.assertNotNull(res,
+                               "Method getFilteredList must not return null.");
+               Assert.assertEquals(res.size(), 2, "Number of found objects is wrong.");
+
+               // ////////////////////////////////////////////////////
+               // Call DAO's getFilteredList method with defined order parameter.
+               res = _studyDAO.getFilteredList("manager", Restrictions.eq("username",
+                               aStudy.getAuthor().getUsername()), Order.asc("title"));
+
+               Assert.assertNotNull(res,
+                               "Method getFilteredList must not return null.");
+               Assert.assertEquals(res.size(), 2, "Number of found objects is wrong.");
+               Assert.assertEquals(res.get(0).getIndex(), id,
+                               "Sorting of results is not correct.");
+               Assert.assertEquals(res.get(1).getIndex(), id2,
+                               "Sorting of results is not correct.");
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testGetFilteredList()");
+       }
+
+       /**
+        * Create a persistent scenario for tests.
+        * 
+        * @return a persistent scenario
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws IOException
+        *             if document creation is failed
+        * @throws SQLException
+        *             if project settings loading is failed
+        */
+       private Study createStudy() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               // Create a scenario for tests
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               // Load workflow customization
+               try {
+                       _projectSettings.configure(ClassLoader.getSystemResource(
+                                       "test/som.xml").getPath());
+               } catch (FileNotFoundException e) {
+                       Assert.fail("Can't find som.xml: ", e);
+               }
+               List<Step> steps = _projectSettings.getAllSteps();
+               Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+               // Create a test user
+               User.Properties uprop = new User.Properties();
+               uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+                               .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+                               .addRole("TST_user").setMailAddress(
+                                               "noreply@salome-platform.org");
+               uprop.disableCheck();
+               User anAuthor = new User(uprop);
+               ht.saveOrUpdate(anAuthor);
+
+               // Create a test study
+               Study.Properties stprops = new Study.Properties().setReference(
+                               "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
+               Study aStudy = new Study(stprops);
+               ht.saveOrUpdate(aStudy);
+
+               // Create a test scenario
+               Scenario.Properties sprops = new Scenario.Properties().setTitle(
+                               "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
+               Scenario aScenario = new Scenario(sprops);
+               aStudy.getScenariiList().add(aScenario);
+               ht.saveOrUpdate(anAuthor);
+               ht.saveOrUpdate(aStudy);
+               ht.saveOrUpdate(aScenario);
+
+               // Create documents for each scenario step
+               Document.Properties dprop = new Document.Properties().setAuthor(
+                               anAuthor).setDate(new Date());
+               int i = 0;
+               Publication usedPub = null;
+               Map<Long, Long> usedMap = new HashMap<Long, Long>();
+               for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
+                       Step step = _projectSettings.getStep(stepNum);
+                       LOG.debug("Create scenario step: " + stepNum);
+                       ProjectElement projElem;
+
+                       if (step.appliesTo(Study.class)) {
+                               projElem = aStudy;
+                       } else {
+                               projElem = aScenario;
+                       }
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+                       List<DocumentType> dtypes = _documentTypeService
+                                       .selectTypesOf(step);
+                       if (dtypes.size() > 0) {
+                               DocumentType dtype = dtypes.get(0);
+                               // Create a document published in the scenario
+                               // document<i>: document type[0] - first type used on the step
+                               // <source-file>.brep
+                               // <attached-file>.med
+                               i++;
+                               dprop.setName("document" + stepNum).setType(dtype);
+                               if (step.getNumber() > 3) {
+                                       dprop.setFormat("med");
+                               } else {
+                                       dprop.setFormat("py");
+                               }
+                               Publication pub = createDoc(projElem, aScStep, dprop, "med",
+                                               false);
+                               if (usedPub != null) {
+                                       pub.addDependency(usedPub);
+                                       LOG.debug("Add dependency: " + pub.value().getTitle()
+                                                       + " from " + usedPub.value().getTitle());
+                                       ht.saveOrUpdate(pub.value());
+                                       ht.flush();
+
+                                       usedMap.put(pub.getIndex(), usedPub.getIndex());
+                               }
+                               usedPub = pub;
+                       }
+                       if (dtypes.size() <= 0) {
+                               LOG.debug("No document types are found for scenario step " + i);
+                       }
+               }
+
+               // Check that the scenario and its documents have been created correctly.
+
+               Assert.assertNotNull(ht.find("from Document"),
+                               "No documents in the database.");
+               Assert.assertTrue(ht.find("from Document").size() > 0,
+                               "No documents in the database.");
+
+               Assert.assertNotNull(ht.find("from Publication where owner="
+                               + aScenario.getIndex()), "No publications in the database.");
+               Assert.assertTrue(
+                               ht.find("from Publication where owner=" + aScenario.getIndex())
+                                               .size() > 0, "No publications in the database.");
+
+               for (Publication p : (List<Publication>) ht
+                               .find("from Publication where owner=" + aScenario.getIndex())) {
+                       LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
+                                       + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
+                                       + "]");
+                       Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
+                                       "The publication was not attached to the scenario.");
+               }
+
+               // Remove the scenario from the current hibernate session.
+               ht.evict(aScenario);
+               // Check that the scenario is created in the database.
+               Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
+               Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
+               Assert.assertTrue(aScen.getDocums().size() > 0,
+                               "No publications in the scenario.");
+
+               Assert.assertTrue(i > 0,
+                               "More then one document must be in the database");
+
+               // Check created uses relations
+               Assert
+                               .assertTrue(usedMap.size() > 0,
+                                               "Uses relations must be created.");
+               boolean foundAny = false;
+               for (Long usingId : usedMap.keySet()) {
+                       for (Publication pub : aScen.getDocums()) {
+                               if (pub.getIndex() == usingId) {
+                                       boolean found = false;
+                                       for (Publication used : aScen.getDocums()) {
+                                               found = (used.getIndex() == usedMap.get(usingId));
+                                               if (found) {
+                                                       break;
+                                               }
+                                       }
+                                       if (!found) {
+                                               for (Publication used : aStudy.getDocums()) {
+                                                       found = (used.getIndex() == usedMap.get(usingId));
+                                                       if (found) {
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       Assert.assertTrue(found,
+                                                       "Uses relation was not created in the database.");
+                                       foundAny = foundAny || found;
+                               }
+                       }
+               }
+               Assert.assertTrue(foundAny,
+                               "No Uses relation was created in the database.");
+
+               return aScenario.getOwnerStudy();
+       }
+
+       /**
+        * Create a document published in the scenario. <BR>
+        * document:<BR>
+        * document type - type used on the step <BR>
+        * &lt;source-file&gt;.brep <BR>
+        * &lt;attached-file&gt;.med
+        * 
+        * @param aScenario
+        *            the scenario to add the document to
+        * @param aScStep
+        *            scenario step where the document to be published
+        * @param dprop
+        *            document properties
+        * @param attachedFileExt
+        *            extension of the secon attached (exported) file
+        * @param isOutdated
+        *            outdated document flag
+        * @return the publication of the created document
+        * @throws IOException
+        * @throws MultiplyDefinedException
+        * @throws InvalidPropertyException
+        * @throws MissedPropertyException
+        */
+       private Publication createDoc(final ProjectElement aScenario,
+                       final org.splat.som.Step aScStep, final Properties dprop,
+                       final String attachedFileExt, final boolean isOutdated)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException {
+               // Create a document published in the scenario
+               // document<i>: document type - type used on the step
+               // <source-file>.brep
+               // <attached-file>.med
+               Publication pub = _stepService.createDocument(aScStep, dprop);
+               Assert.assertNotNull(pub.getOwner(),
+                               "The publication must be attached to the scenario.");
+               Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
+                               "The publication was not attached to the scenario.");
+
+               if (isOutdated) {
+                       pub.setIsnew('O');
+               }
+               aScenario.add(pub);
+               HibernateTemplate ht = getHibernateTemplate();
+               ht.saveOrUpdate(pub);
+
+               // Attach a file
+               ht.save(pub.value());
+               ht.flush();
+               ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
+
+               return pub;
+       }
+}
diff --git a/Workspace/Siman-Common/src/test/splat/service/TestStepService.java b/Workspace/Siman-Common/src/test/splat/service/TestStepService.java
new file mode 100644 (file)
index 0000000..dd9b728
--- /dev/null
@@ -0,0 +1,548 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   12 Oct 2012
+ * @author         $Author$
+ * @version        $Revision$
+ *****************************************************************************/
+package test.splat.service;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.splat.dal.bo.kernel.User;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
+import org.splat.dal.bo.som.ProjectElement;
+import org.splat.dal.bo.som.Publication;
+import org.splat.dal.bo.som.Scenario;
+import org.splat.dal.bo.som.Study;
+import org.splat.dal.bo.som.UsedByRelation;
+import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.bo.som.Document.Properties;
+import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.ScenarioDAO;
+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.log.AppLogger;
+import org.splat.service.DocumentTypeService;
+import org.splat.service.KnowledgeElementTypeService;
+import org.splat.service.ProjectElementService;
+import org.splat.service.PublicationService;
+import org.splat.service.ScenarioService;
+import org.splat.service.SimulationContextService;
+import org.splat.service.StepService;
+import org.splat.service.StudyService;
+import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.RepositoryService;
+import org.splat.service.technical.ProjectSettingsService.Step;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.orm.hibernate3.HibernateTemplate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import test.splat.common.BaseTest;
+
+/**
+ * Test class for StepService.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ * 
+ */
+public class TestStepService extends BaseTest {
+
+       /**
+        * Logger for the class.
+        */
+       private static final AppLogger LOG = AppLogger
+                       .getLogger(TestStepService.class);
+
+       /**
+        * The StudyService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("studyService")
+       private transient StudyService _studyService;
+
+       /**
+        * The ScenarioService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("scenarioService")
+       private transient ScenarioService _scenarioService;
+
+       /**
+        * The ProjectElementService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectElementService")
+       private transient ProjectElementService _projectElementService;
+
+       /**
+        * The RepositoryService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("repositoryService")
+       private transient RepositoryService _repositoryService;
+
+       /**
+        * The Scenario DAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("scenarioDAO")
+       private transient ScenarioDAO _scenarioDAO;
+
+       /**
+        * The PublicationService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("publicationService")
+       private transient PublicationService _publicationService;
+
+       /**
+        * The StepService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("stepService")
+       private transient StepService _stepService;
+
+       /**
+        * The SimulationContextService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("simulationContextService")
+       private transient SimulationContextService _simulationContextService;
+
+       /**
+        * The ProjectSettingsService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("projectSettings")
+       private transient ProjectSettingsService _projectSettings;
+
+       /**
+        * The DocumentTypeService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("documentTypeService")
+       private transient DocumentTypeService _documentTypeService;
+
+       /**
+        * The KnowledgeElementTypeService. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("knowledgeElementTypeService")
+       private transient KnowledgeElementTypeService _knowledgeElementTypeService;
+
+       /**
+        * Test check-in scenario operation to be performed after SALOME session.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
+        * After check-in verify following points:
+        * <ul>
+        * <li>scenario is no more marked as checked out</li>
+        * <li>new document versions are created for checked in documents</li>
+        * <li>presentation of the previous version is removed</li>
+        * <li>uses relations are copied correctly</li>
+        * <li>files are moved correctly</li>
+        * <li>formats of files are new if they are according to the document's type on the study step</li>
+        * <li>new documents are created for new data</li>
+        * <li>new documents have correctly generated names</li>
+        * <li>uses relations are created correctly</li>
+        * <li>files are moved correctly</li>
+        * </ul>
+        * </i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call the method for an existing scenario id.</i><BR>
+        * <i>2. call the method for a not existing scenario id.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
+        * relations must be created.<BR>
+        * </li>
+        * <li>Exception is thrown<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws IOException
+        *             if scenario creation is failed
+        * @throws SQLException
+        *             if scenario creation is failed
+        * @throws NotApplicableException
+        *             if checkin failed
+        * @throws MismatchException
+        *             if checkin failed
+        */
+       @Test
+       public void testRemoveDocument() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException, MismatchException, NotApplicableException {
+               LOG.debug(">>>>> BEGIN testRemoveDocument()");
+               startNestedTransaction();
+
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               _projectSettings.configure(ClassLoader
+                               .getSystemResource("test/som.xml").getPath());
+               HibernateTemplate ht = getHibernateTemplate();
+               ht.flush();
+               long scenarioId = createScenario();
+               ht.flush();
+               _scenarioDAO.flush();
+               Scenario aScen = _scenarioDAO.get(scenarioId);
+
+               Assert.assertTrue(ht.find("from UsesRelation").size() > 0,
+                               "Uses relations were not created in the database.");
+
+               Assert.assertTrue(ht.find("from UsedByRelation").size() > 0,
+                               "UsedBy relations were not created in the database.");
+
+               // ////////////////////////////////////////////////////////
+               // Call removeDocument method for each document of the
+               // study/scenario starting from the last document.
+
+               ProjectElement projElem;
+               boolean ok;
+               long docId;
+               Step step;
+               for (int i = _projectSettings.getAllSteps().size(); i > 0; i--) {
+                       LOG.debug("Remove documents from the step " + i);
+                       step = _projectSettings.getStep(i);
+                       if (step.appliesTo(Study.class)) {
+                               projElem = _studyService.selectStudy(aScen.getOwnerStudy()
+                                               .getIndex());
+                       } else {
+                               projElem = aScen;
+                       }
+
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+
+                       if (aScStep.getDocuments().size() > 0) {
+                               docId = aScStep.getDocuments().get(0).value().getIndex();
+                               LOG.debug("Remove document "
+                                               + aScStep.getDocument(docId).value().getTitle());
+                               ht.flush();
+                               List<UsesRelation> uses = ht
+                                               .find("from UsesRelation where owner=" + docId);
+                               List<UsedByRelation> usedBy = ht
+                                               .find("from UsedByRelation where owner=" + docId);
+                               LOG.debug("From db: It uses following " + uses.size()
+                                               + " documents: ");
+                               for (UsesRelation rel : uses) {
+                                       LOG.debug(rel.getTo().getTitle());
+                               }
+                               LOG.debug("From step: It uses following "
+                                               + aScStep.getDocument(docId).getRelations(
+                                                               UsesRelation.class).size() + " documents: ");
+                               for (Publication rel : aScStep.getDocument(docId).getRelations(
+                                               UsesRelation.class)) {
+                                       LOG.debug(rel.value().getTitle());
+                               }
+                               LOG.debug("From db: It is used by following " + usedBy.size()
+                                               + " documents: ");
+                               for (UsedByRelation rel : usedBy) {
+                                       LOG.debug(rel.getTo().getTitle());
+                               }
+                               LOG.debug("From step: It is used by following "
+                                               + aScStep.getDocument(docId).getRelations(
+                                                               UsedByRelation.class).size() + " documents: ");
+                               for (Publication rel : aScStep.getDocument(docId).getRelations(
+                                               UsedByRelation.class)) {
+                                       LOG.debug(rel.value().getTitle());
+                               }
+                               ok = _stepService.removeDocument(aScStep, docId);
+
+                               Assert.assertTrue(ok, "Removing was failed.");
+                               _scenarioDAO.flush();
+                               ht.flush();
+                               Assert.assertEquals(ht.find(
+                                               "from UsesRelation where owner=" + docId).size(), 0,
+                                               "UsesRelation(s) were not removed from the database.");
+                               Assert
+                                               .assertEquals(ht.find(
+                                                               "from UsedByRelation where owner=" + docId)
+                                                               .size(), 0,
+                                                               "UsedByRelation(s) were not removed from the database.");
+                               Assert.assertEquals(ht.find(
+                                               "from UsesRelation where refer=" + docId).size(), 0,
+                                               "Referencing UsesRelation(s) were not removed from the database.");
+                               Assert
+                                               .assertEquals(ht.find(
+                                                               "from UsedByRelation where refer=" + docId)
+                                                               .size(), 0,
+                                                               "Referencing UsedByRelation(s) were not removed from the database.");
+                               Assert
+                               .assertEquals(ht.find(
+                                               "from ConvertsRelation where owner=" + docId)
+                                               .size(), 0,
+                                               "ConvertsRelation(s) were not removed from the database.");
+                       }
+               }
+
+               Assert.assertEquals(ht.find("from Document").size(), 0,
+                               "Documents were not removed from the database.");
+
+               Assert.assertEquals(ht.find(
+                               "from Publication where owner=" + aScen.getIndex()).size(), 0,
+                               "Publications were not removed from the database.");
+
+               Assert.assertEquals(ht.find("from UsesRelation").size(), 0,
+                               "Uses relations were not removed from the database.");
+
+               Assert.assertEquals(ht.find("from UsedByRelation").size(), 0,
+                               "UsedBy relations were not removed from the database.");
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testRemoveDocument()");
+       }
+
+       /**
+        * Create a persistent scenario for tests.
+        * 
+        * @return a persistent scenario
+        * @throws InvalidPropertyException
+        *             if an invalid property is used when creating objects
+        * @throws MultiplyDefinedException
+        *             when trying to create an object with already existing id
+        * @throws MissedPropertyException
+        *             if a mandatory property is not defined for an object to be created
+        * @throws IOException
+        *             if document creation is failed
+        * @throws SQLException
+        *             if project settings loading is failed
+        */
+       private long createScenario() throws InvalidPropertyException,
+                       MissedPropertyException, MultiplyDefinedException, IOException,
+                       SQLException {
+               // Create a scenario for tests
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               // Load workflow customization
+               try {
+                       _projectSettings.configure(ClassLoader.getSystemResource(
+                                       "test/som.xml").getPath());
+               } catch (FileNotFoundException e) {
+                       Assert.fail("Can't find som.xml: ", e);
+               }
+               List<Step> steps = _projectSettings.getAllSteps();
+               Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+               // Create a test user
+               User.Properties uprop = new User.Properties();
+               uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+                               .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+                               .addRole("TST_user").setMailAddress(
+                                               "noreply@salome-platform.org");
+               uprop.disableCheck();
+               User anAuthor = new User(uprop);
+               ht.saveOrUpdate(anAuthor);
+
+               // Create a test study
+               Study.Properties stprops = new Study.Properties().setReference(
+                               "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
+               Study aStudy = new Study(stprops);
+               ht.saveOrUpdate(aStudy);
+
+               // Create a test scenario
+               Scenario.Properties sprops = new Scenario.Properties().setTitle(
+                               "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
+               Scenario aScenario = new Scenario(sprops);
+               aStudy.getScenariiList().add(aScenario);
+               ht.saveOrUpdate(anAuthor);
+               ht.saveOrUpdate(aStudy);
+               ht.saveOrUpdate(aScenario);
+
+               // Create documents for each scenario step
+               Document.Properties dprop = new Document.Properties().setAuthor(
+                               anAuthor).setDate(new Date());
+               int i = 0;
+               Publication usedPub = null;
+               Map<Long, Long> usedMap = new HashMap<Long, Long>();
+               for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
+                       Step step = _projectSettings.getStep(stepNum);
+                       LOG.debug("Create scenario step: " + stepNum);
+                       ProjectElement projElem;
+
+                       if (step.appliesTo(Study.class)) {
+                               projElem = aStudy;
+                       } else {
+                               projElem = aScenario;
+                       }
+                       org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
+                       List<DocumentType> dtypes = _documentTypeService
+                                       .selectTypesOf(step);
+                       if (dtypes.size() > 0) {
+                               DocumentType dtype = dtypes.get(0);
+                               // Create a document published in the scenario
+                               // document<i>: document type[0] - first type used on the step
+                               // <source-file>.brep
+                               // <attached-file>.med
+                               i++;
+                               dprop.setName("document" + stepNum).setType(dtype);
+                               if (step.getNumber() > 3) {
+                                       dprop.setFormat("med");
+                               } else {
+                                       dprop.setFormat("py");
+                               }
+                               Publication pub = createDoc(projElem, aScStep, dprop, "med",
+                                               false);
+                               if (usedPub != null) {
+                                       pub.addDependency(usedPub);
+                                       LOG.debug("Add dependency: " + pub.value().getTitle()
+                                                       + " from " + usedPub.value().getTitle());
+                                       ht.saveOrUpdate(pub.value());
+                                       ht.flush();
+
+                                       usedMap.put(pub.getIndex(), usedPub.getIndex());
+                               }
+                               usedPub = pub;
+                       }
+                       if (dtypes.size() <= 0) {
+                               LOG.debug("No document types are found for scenario step " + i);
+                       }
+               }
+
+               // Check that the scenario and its documents have been created correctly.
+
+               Assert.assertNotNull(ht.find("from Document"),
+                               "No documents in the database.");
+               Assert.assertTrue(ht.find("from Document").size() > 0,
+                               "No documents in the database.");
+
+               Assert.assertNotNull(ht.find("from Publication where owner="
+                               + aScenario.getIndex()), "No publications in the database.");
+               Assert.assertTrue(
+                               ht.find("from Publication where owner=" + aScenario.getIndex())
+                                               .size() > 0, "No publications in the database.");
+
+               for (Publication p : (List<Publication>) ht
+                               .find("from Publication where owner=" + aScenario.getIndex())) {
+                       LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
+                                       + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
+                                       + "]");
+                       Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
+                                       "The publication was not attached to the scenario.");
+               }
+
+               // Remove the scenario from the current hibernate session.
+               ht.evict(aScenario);
+               // Check that the scenario is created in the database.
+               Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
+               Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
+               Assert.assertTrue(aScen.getDocums().size() > 0,
+                               "No publications in the scenario.");
+
+               Assert.assertTrue(i > 0,
+                               "More then one document must be in the database");
+
+               // Check created uses relations
+               Assert
+                               .assertTrue(usedMap.size() > 0,
+                                               "Uses relations must be created.");
+               boolean foundAny = false;
+               for (Long usingId : usedMap.keySet()) {
+                       for (Publication pub : aScen.getDocums()) {
+                               if (pub.getIndex() == usingId) {
+                                       boolean found = false;
+                                       for (Publication used : aScen.getDocums()) {
+                                               found = (used.getIndex() == usedMap.get(usingId));
+                                               if (found) {
+                                                       break;
+                                               }
+                                       }
+                                       if (!found) {
+                                               for (Publication used : aStudy.getDocums()) {
+                                                       found = (used.getIndex() == usedMap.get(usingId));
+                                                       if (found) {
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       Assert.assertTrue(found,
+                                                       "Uses relation was not created in the database.");
+                                       foundAny = foundAny || found;
+                               }
+                       }
+               }
+               Assert.assertTrue(foundAny,
+                               "No Uses relation was created in the database.");
+
+               return aScenario.getIndex();
+       }
+
+       /**
+        * Create a document published in the scenario. <BR>
+        * document:<BR>
+        * document type - type used on the step <BR>
+        * &lt;source-file&gt;.brep <BR>
+        * &lt;attached-file&gt;.med
+        * 
+        * @param aScenario
+        *            the scenario to add the document to
+        * @param aScStep
+        *            scenario step where the document to be published
+        * @param dprop
+        *            document properties
+        * @param attachedFileExt
+        *            extension of the secon attached (exported) file
+        * @param isOutdated
+        *            outdated document flag
+        * @return the publication of the created document
+        * @throws IOException
+        * @throws MultiplyDefinedException
+        * @throws InvalidPropertyException
+        * @throws MissedPropertyException
+        */
+       private Publication createDoc(final ProjectElement aScenario,
+                       final org.splat.som.Step aScStep, final Properties dprop,
+                       final String attachedFileExt, final boolean isOutdated)
+                       throws MissedPropertyException, InvalidPropertyException,
+                       MultiplyDefinedException, IOException {
+               // Create a document published in the scenario
+               // document<i>: document type - type used on the step
+               // <source-file>.brep
+               // <attached-file>.med
+               Publication pub = _stepService.createDocument(aScStep, dprop);
+               Assert.assertNotNull(pub.getOwner(),
+                               "The publication must be attached to the scenario.");
+               Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
+                               "The publication was not attached to the scenario.");
+
+               if (isOutdated) {
+                       pub.setIsnew('O');
+               }
+               aScenario.add(pub);
+               HibernateTemplate ht = getHibernateTemplate();
+               ht.saveOrUpdate(pub);
+
+               // Attach a file
+               ht.save(pub.value());
+               ht.flush();
+               ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
+
+               return pub;
+       }
+}
diff --git a/Workspace/Siman-Common/testng-stepService.xml b/Workspace/Siman-Common/testng-stepService.xml
new file mode 100644 (file)
index 0000000..bafa7e3
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Siman-Common">
+  <test verbose="2" name="test.splat.service.TestStepService" annotations="JDK">
+    <classes>
+      <class name="test.splat.service.TestStepService"/>
+    </classes>
+  </test>
+</suite>
diff --git a/Workspace/Siman/WebContent/WEB-INF/lib/jsonplugin-0.34.jar b/Workspace/Siman/WebContent/WEB-INF/lib/jsonplugin-0.34.jar
new file mode 100644 (file)
index 0000000..7edffda
Binary files /dev/null and b/Workspace/Siman/WebContent/WEB-INF/lib/jsonplugin-0.34.jar differ
index 8bb900a7675a03b441a569a5d38ec62b47d738e8..fe41638a56c0218490b740ba26b6902cd83f4352 100644 (file)
Binary files a/Workspace/Siman/WebContent/jap/splat-launcher.jar and b/Workspace/Siman/WebContent/jap/splat-launcher.jar differ
index f2a64e4b07b596017c197d1460ad8a100cb32c9d..b35d41ae2f00885db94cc5de0805e2353b39051a 100644 (file)
Binary files a/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar and b/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar differ
index 5d01a89502acf01d0efb389438d444031671f5eb..aa0f5278685fc437ff6e0bd578d7a11d46f37998 100644 (file)
@@ -25,6 +25,9 @@
     Action anAction = (Action)ActionContext.getContext().getActionInvocation().getAction();
        Menu menu = anAction.getLeftMenuSettings().getMenu();
     boolean submenu = false;
+%>
+<s:if test="leftMenuSettings.menu != null">
+<%    
     for (Iterator<MenuItem> listem = menu.asList().iterator(); listem.hasNext(); ) {
        MenuItem item  = listem.next();
        String   arrow = "image.hold.gif";
@@ -89,4 +92,5 @@
           </div>
 <%  }
 %>  
+</s:if>
   </div>
\ No newline at end of file
index b35caeeabf691d309e2b2ed09351559444fa4948..3de62f229ff3aac2bbc1ea5134053f5bd664dfdb 100644 (file)
                </td>
         </tr>
     </table>
-</body>
+<s:if test="message != ''">
+<div id="message"><p><s:property value="message"/></p></div>
+<script>
+    $(document).ready(function () {
+        $( "#message" ).dialog({
+            autoOpen: true,
+            width: 400,
+            buttons: [
+                {
+                    text: '<s:text name="button.ok"/>',
+                    click: function() {
+                        $( this ).dialog( "close" );
+                    }
+                }
+            ]
+        });
+    });
+</script>
+</s:if></body>
 
 </html>
\ No newline at end of file
index ff01292977d6063886630b5763a14b074f740a4a..35a2a639eb53f0c143266a9e78752c3dc0e6472b 100644 (file)
@@ -1,11 +1,5 @@
 <%@ 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">
-<html>
-
-  <head>
-    <link href=<s:url value="/skin/default.css"/> rel="stylesheet" type="text/css">
-    
     <script language="JavaScript">
 
     function checkin (message) {
       return false;
     }
     </script>
-  </head>
-
-  <body>
-
 <!-- Properties form
      =============================================================================================================================
   -->
@@ -77,6 +67,3 @@
 
         </div>
       </div>
-
-  </body>
-</html>
\ No newline at end of file
index 88cd755b12a0c7ce8d3115dee0c099a4c48e2f16..1d1587d5534755563e388c7bc1b2009ce52541fe 100644 (file)
@@ -1,4 +1,4 @@
-# Generated at 04/12/2012 01:42:16
+# Generated at 20/12/2012 09:31:13
 # Don't edit manually. See the source in D:\users\rkv\SIMAN\SIMAN_SRC\Workspace\Siman\conf\templates.
 # Connection properties
 connection.driver_class=com.mysql.jdbc.Driver
index ecfd593de1e81d2b79d67e4cdfdd6378c2ddde7a..cb7201fb08e85e69db396d160a9077b5217a267c 100644 (file)
@@ -1,4 +1,4 @@
-# Generated at 04/12/2012 01:42:16
+# Generated at 20/12/2012 09:31:13
 # Don't edit manually. See the source in D:\users\rkv\SIMAN\SIMAN_SRC\Workspace\Siman\conf\templates.
 # Connection properties
 connection.url=jdbc:mysql://localhost/simer
index ff3235524a018b4b2a0307789998e168a3dbbfba..16e0b27aacbee62d25460f81153108004aef73ab 100644 (file)
@@ -178,7 +178,8 @@ public class Action extends ActionSupport implements ServletRequestAware,
         * Remove the currently open knowledge from the session.
         */
        protected void closeKnowledge() {
-               AbstractOpenObject open = (AbstractOpenObject) _session.remove(KNOWLEDGE_OPEN);
+               AbstractOpenObject open = (AbstractOpenObject) _session
+                               .remove(KNOWLEDGE_OPEN);
                if ((open != null) && (_session.get(STUDY_OPEN) == null)) {
                        open.clearFacades(); // For eventually reopening the knowledge from a fresh context
                }
@@ -188,7 +189,8 @@ public class Action extends ActionSupport implements ServletRequestAware,
         * Remove the currently open study from the session.
         */
        protected void closeStudy() {
-               AbstractOpenObject open = (AbstractOpenObject) _session.remove(STUDY_OPEN);
+               AbstractOpenObject open = (AbstractOpenObject) _session
+                               .remove(STUDY_OPEN);
                if ((open != null) && (_session.get(KNOWLEDGE_OPEN) == null)) {
                        open.clearFacades(); // For eventually reopening the study from a fresh context
                }
@@ -386,8 +388,10 @@ public class Action extends ActionSupport implements ServletRequestAware,
                Menu menu = (Menu) _session.get("menu." + leftMenuProperty);
 
                getLeftMenuSettings().setMenu(menu);
-               getLeftMenuSettings().setMenuName(menu.getName());
-               getLeftMenuSettings().setMenuNamespace(menu.getNamespace());
+               if (menu != null) {
+                       getLeftMenuSettings().setMenuName(menu.getName());
+                       getLeftMenuSettings().setMenuNamespace(menu.getNamespace());
+               }
        }
 
        /**
@@ -403,7 +407,8 @@ public class Action extends ActionSupport implements ServletRequestAware,
 
                initializationContext();
 
-               AbstractOpenObject entity = (AbstractOpenObject) _session.get(titleProperty + ".open");
+               AbstractOpenObject entity = (AbstractOpenObject) _session
+                               .get(titleProperty + ".open");
 
                if (entity != null) {
                        getTitleBarSettings().setProgressState(
@@ -683,9 +688,10 @@ public class Action extends ActionSupport implements ServletRequestAware,
        public void setLeftMenuSettings(final LeftMenuSettings leftMenuSettings) {
                _leftMenuSettings = leftMenuSettings;
        }
-       
+
        /**
         * Get the actionType.
+        * 
         * @return the actionType
         */
        public String getActionType() {
@@ -694,7 +700,9 @@ public class Action extends ActionSupport implements ServletRequestAware,
 
        /**
         * Set the actionType.
-        * @param actionType the actionType to set
+        * 
+        * @param actionType
+        *            the actionType to set
         */
        public void setActionType(final String actionType) {
                _actionType = actionType;
@@ -702,6 +710,7 @@ public class Action extends ActionSupport implements ServletRequestAware,
 
        /**
         * Get the message.
+        * 
         * @return the message
         */
        public String getMessage() {
@@ -710,7 +719,9 @@ public class Action extends ActionSupport implements ServletRequestAware,
 
        /**
         * Set the message.
-        * @param message the message to set
+        * 
+        * @param message
+        *            the message to set
         */
        public void setMessage(final String message) {
                _message = message;
index cd4e68e5a05e5a35faf9b3302bd2f2c67ec8c4f1..7f9e3084c4292caf9841a0f511f1da9c1452bb41 100644 (file)
@@ -53,40 +53,40 @@ public class ApplicationSettings {
        /**
         * JNDI context for launching converters.
         */
-       private transient static final Properties _jndprops;
+       private transient static final Properties _JNDPROPS;
        /**
         * Siman web application name.
         */
-       private transient static String _wappname;
+       private transient static String wappname;
        /**
         * General properties from the application properties files.
         */
-       private transient static final Properties _wapprops = new Properties();
+       private transient static final Properties _WAPPROPS = new Properties();
        /**
         * Siman web application root path on the server.
         */
-       private transient static String _wapproot;
+       private transient static String wapproot;
        /**
         * Available template files.
         */
-       private transient static Map<String, String> _tempfile;
+       private transient static Map<String, String> tempfile;
        /**
         * List of file extensions mapped to a viewer.
         */
-       private transient static String[] _viewermap;
+       private transient static String[] viewermap;
        /**
         * Available document format converters.
         */
-       private transient static Map<String, Converter> _convertmap;
+       private transient static Map<String, Converter> convertmap;
 
        static {
-               synchronized (_wapprops) {
+               synchronized (_WAPPROPS) {
                        // Do common configuration for all users
 
-                       _jndprops = new Properties();
-                       _tempfile = new HashMap<String, String>();
-                       _viewermap = new String[0];
-                       _convertmap = new HashMap<String, Converter>();
+                       _JNDPROPS = new Properties();
+                       tempfile = new HashMap<String, String>();
+                       viewermap = new String[0];
+                       convertmap = new HashMap<String, Converter>();
 
                        ClassLoader cloader = Thread.currentThread()
                                        .getContextClassLoader();
@@ -94,15 +94,15 @@ public class ApplicationSettings {
                                        .currentRequestAttributes()).getRequest();
                        String appname = curRequest.getContextPath();
                        if (appname.startsWith("/")) {
-                               _wappname = appname.substring(1);
+                               wappname = appname.substring(1);
                        }
                        // Set local path on the server to the application root.
-                       _wapproot = curRequest.getSession().getServletContext()
-                                       .getRealPath("/");
+                       wapproot = curRequest.getSession().getServletContext().getRealPath(
+                                       "/");
 
                        try {
-                               _jndprops.load(cloader.getResourceAsStream("jndi.properties"));
-                               _wapprops.load(cloader.getResourceAsStream(_wappname
+                               _JNDPROPS.load(cloader.getResourceAsStream("jndi.properties"));
+                               _WAPPROPS.load(cloader.getResourceAsStream(wappname
                                                + ".properties"));
                        } catch (IOException e) {
                                LOG.info(
@@ -111,11 +111,11 @@ public class ApplicationSettings {
                        }
 
                        // Configure login security
-                       System.setProperty("java.security.auth.login.config", _wapproot
+                       System.setProperty("java.security.auth.login.config", wapproot
                                        + ApplicationSettings.getApplicationProperty("wapp.login"));
 
                        // Customization (must be done after above default settings)
-                       File config = new File(_wapproot
+                       File config = new File(wapproot
                                        + getApplicationProperty("wapp.customization"));
                        if (config.exists()) {
                                loadCustomization(config); // Sets default document types, installed modules and available templates
@@ -228,11 +228,15 @@ public class ApplicationSettings {
        /**
         * Rename menu item name.
         */
-       private static final String MNU_NAME_RENAME = "menu.rename";    
+       private static final String MNU_NAME_RENAME = "menu.rename";
        /**
-        * Publish menu item name.
+        * Mark as reference menu item name.
+        */
+       private static final String MNU_MARK_AS_REFERENCE = "markasreference";
+       /**
+        * Mark as reference menu item label key.
         */
-       private static final String MNU_MARK_AS_REFERENCE = "menu.markasreference";
+       private static final String MNU_NAME_MARK_AS_REFERENCE = "menu.markasreference";
        /**
         * Not yet implemented action name.
         */
@@ -289,7 +293,7 @@ public class ApplicationSettings {
                                + curRequest.getServerPort();
 
                LOG.info("Application server is set to " + _wappserver);
-               LOG.info("Application name is set to " + _wappname);
+               LOG.info("Application name is set to " + wappname);
        }
 
        /**
@@ -319,10 +323,10 @@ public class ApplicationSettings {
                                        "select?menu=create&item=new-empty");
                        addItem("new-copy", new MenuItem("menu.new.copy")
                                        .icon("image.copy.png"));
-                       /*addItem("new-instance", new MenuItem("menu.new.instance")
-                                       .icon(IMG_HOLD));
-                       addItem("new-import", new MenuItem("menu.new.import")
-                                       .icon("icon.upload.png"));*/
+                       /*
+                        * addItem("new-instance", new MenuItem("menu.new.instance") .icon(IMG_HOLD)); addItem("new-import", new
+                        * MenuItem("menu.new.import") .icon("icon.upload.png"));
+                        */
                        this.selects("new-empty");
                }
        }
@@ -344,9 +348,9 @@ public class ApplicationSettings {
                private PropertiesMenu() {
                        super("configuration");
                        addItem("prop-general", "menu.prop.general", IMG_HOLD,
-                                       "select?menu=properties&item=prop-general");
+                                       "select?menu=configuration&item=prop-general");
                        addItem("prop-scenario", "menu.prop.scenario", IMG_HOLD,
-                                       "select?menu=properties&item=prop-scenario");
+                                       "select?menu=configuration&item=prop-scenario");
                        // These menu items will not be implemented in the current version.
                        /*
                         * addItem("prop-timestamp", new MenuItem("menu.prop.timestamp") .icon("image.stamp.png")); addItem("prop-comlog", new
@@ -379,8 +383,74 @@ public class ApplicationSettings {
                }
        }
 
+       /**
+        * Menu items enumeration.
+        */
        private enum Item {
-               publish, accept, approve, promote, demote, undo, rename, attach, edit, script, version, replace, export, remove, purge
+               /**
+                * Publish the study.
+                */
+               publish,
+               /**
+                * Accept the document.
+                */
+               accept, 
+               /**
+                * Approve the document.
+                */
+               approve, 
+               /**
+                * Promote the document.
+                */
+               promote, 
+               /**
+                * Demote the docuemnt.
+                */
+               demote, 
+               /**
+                * Undo the last operation.
+                */
+               undo, 
+               /**
+                * Rename the document.
+                */
+               rename, 
+               /**
+                * Attach a file to the document.
+                */
+               attach, 
+               /**
+                * Edit the document.
+                */
+               edit, 
+               /**
+                * script
+                */
+               script, 
+               /**
+                * Version the document.
+                */
+               version, 
+               /**
+                * replace
+                */
+               replace, 
+               /**
+                * export
+                */
+               export, 
+               /**
+                * Remove the document.
+                */
+               remove, 
+               /**
+                * purge
+                */
+               purge, 
+               /**
+                * Mark the study as reference.
+                */
+               markasreference
        };
 
        // Resources relative to studies
@@ -389,31 +459,35 @@ public class ApplicationSettings {
 
                private EditableStudyPopup() {
                        super();
-                       addItem(MNU_MARK_AS_REFERENCE, new PopupItem(MNU_MARK_AS_REFERENCE)
-                                       .action(ACT_NOT_YET_IMPLEMENTED)
-                                       .confirmation("message.markasreference.study"));
+                       addItem(MNU_MARK_AS_REFERENCE, new PopupItem(MNU_NAME_MARK_AS_REFERENCE)
+                                       .action(ACT_NOT_YET_IMPLEMENTED).confirmation(
+                                                       "message.markasreference.study"));
                        addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PUBLISH).icon(
                                        "image.publish.png").action("edit-study?action=publish")
                                        .confirmation("message.publish.study"));
-                       /*addItem(MNU_PROMOTE, new PopupItem("menu.archive"));*/
+                       /* addItem(MNU_PROMOTE, new PopupItem("menu.archive")); */
                        addSeparator();
                        addItem(MNU_EDIT, new PopupItem("menu.properties").icon(
                                        "icon.ed.png").action("../select?menu=properties"));
                        addSeparator();
                        addItem(MNU_SCRIPT, new PopupItem(MNU_NAME_SCRIPT)
                                        .action("add-scenario"));
-                       /*addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
-                                       IMG_VERSION).action(ACT_NOT_YET_IMPLEMENTED));*/
+                       /*
+                        * addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon( IMG_VERSION).action(ACT_NOT_YET_IMPLEMENTED));
+                        */
                        addSeparator();
-                       /*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(IMG_DELETE)
-                                       .action(ACT_NOT_YET_IMPLEMENTED).confirmation(
-                                                       "message.delete.study"));
+                       /*
+                        * 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(
+                                       IMG_DELETE).action(ACT_NOT_YET_IMPLEMENTED).confirmation(
+                                       "message.delete.study"));
                }
 
+               /** 
+                * {@inheritDoc}
+                * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
+                */
                @Override
                public boolean isEnabled(final String name) {
                        boolean res = (_user != null);
@@ -688,7 +762,7 @@ public class ApplicationSettings {
         */
        private static class ApprovedPopup extends PopupMenu {
                private ApprovedPopup() {
-                       super(); 
+                       super();
                        addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
                                        .action(ACT_ATTACH));
                        addSeparator();
@@ -731,7 +805,7 @@ public class ApplicationSettings {
                                                break;
                                        case version:
                                                res = _user.canVersion();
-                                               break;  
+                                               break;
                                        case replace:
                                                res = _user.canReplace();
                                                break;
@@ -939,7 +1013,7 @@ public class ApplicationSettings {
                                if (dtype != null) {
                                        docname = dtype.getName();
                                }
-                               if (_tempfile.get(docname) == null) { // No available template
+                               if (tempfile.get(docname) == null) { // No available template
                                        String tool = parsed[parsed.length - 1];
                                        String icon = name[0];
                                        if ("index".equals(icon)) {
@@ -974,17 +1048,17 @@ public class ApplicationSettings {
        }
 
        public static String getApplicationProperty(final String name) {
-               return _wapprops.getProperty(name); // May be null
+               return _WAPPROPS.getProperty(name); // May be null
        }
 
        public static String getApplicationRootPath() {
                // The property is supposed including the Web application name
-               return _wapproot;
+               return wapproot;
        }
 
        public String getApplicationURL() {
                StringBuffer url = new StringBuffer("http://").append(_wappserver)
-                               .append("/").append(_wappname);
+                               .append("/").append(wappname);
                return url.toString();
        }
 
@@ -997,7 +1071,7 @@ public class ApplicationSettings {
        }
 
        static public Properties getNamingProperties() {
-               return _jndprops;
+               return _JNDPROPS;
        }
 
        // ==============================================================================================================================
@@ -1018,7 +1092,7 @@ public class ApplicationSettings {
 
        public static Converter getConverter(final DocumentType type,
                        final String format) {
-               return _convertmap.get(format + type.getName()); // May be null;
+               return convertmap.get(format + type.getName()); // May be null;
        }
 
        public DocumentType getDefaultDocumentType(final Step step,
@@ -1052,7 +1126,7 @@ public class ApplicationSettings {
        }
 
        public static Locale[] getSupportedLocales() {
-               String[] code = _wapprops.getProperty("locale.supported").split(",");
+               String[] code = _WAPPROPS.getProperty("locale.supported").split(",");
                Locale[] result = new Locale[code.length];
                for (int i = 0; i < code.length; i++) {
                        result[i] = new Locale(code[i]);
@@ -1061,7 +1135,7 @@ public class ApplicationSettings {
        }
 
        public static String[] getViewersMapping() {
-               return _viewermap;
+               return viewermap;
        }
 
        public static String getWebSiteURL() {
@@ -1123,11 +1197,11 @@ public class ApplicationSettings {
                        NamedNodeMap natr = child.getAttributes();
                        String dext = natr.getNamedItem("extension").getNodeValue();
                        String exec = natr.getNamedItem("executable").getNodeValue();
-                       _wapprops.put("executable." + dext, exec);
+                       _WAPPROPS.put("executable." + dext, exec);
                }
                // Viewer mappings tag
                child = children.get("viewers");
-               _viewermap = child.getAttributes().getNamedItem("extension")
+               viewermap = child.getAttributes().getNamedItem("extension")
                                .getNodeValue().split(",");
        }
 
@@ -1148,7 +1222,7 @@ public class ApplicationSettings {
                                String from = natr.getNamedItem("from").getNodeValue();
                                String to = natr.getNamedItem("to").getNodeValue();
                                String exec = natr.getNamedItem("executable").getNodeValue();
-                               _convertmap.put(from + "geometry", new Converter("geometry",
+                               convertmap.put(from + "geometry", new Converter("geometry",
                                                from, to, exec));
                        }
                }
@@ -1172,7 +1246,7 @@ public class ApplicationSettings {
                        NamedNodeMap natr = child.getAttributes();
                        String type = natr.getNamedItem("type").getNodeValue();
                        String file = natr.getNamedItem("file").getNodeValue();
-                       _tempfile.put(type, file);
+                       tempfile.put(type, file);
                }
        }
 
index 42020b5dc3503b72f6f9d0535c74b2e5a82a72a5..4f0531691a246336740b33b9499c5dcbb4f8b3c9 100644 (file)
@@ -126,7 +126,7 @@ public class ConnectionAction extends Action {
                                initializationScreenContext(Constants.NONE);
 
                                res = _backmenu;
-                               if (res == null || "null".equals(res)) {
+                               if (res == null || "null".equals(res) || res.isEmpty()) {
                                        res = Constants.NONE;
                                }
                        } catch (FailedLoginException error) {
index af2237dd2c4b0e6f58797a3d2a4630fbeeb9c892..816b40a1768ad538aa0510a9b094ff1da23ceb9e 100644 (file)
@@ -4,6 +4,7 @@ import java.io.File;
 
 import javax.jms.Connection;
 import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
 import javax.jms.Message;
 import javax.jms.MessageConsumer;
 import javax.jms.MessageListener;
@@ -17,90 +18,108 @@ import org.splat.dal.bo.som.Document;
 import org.splat.dal.bo.som.Publication;
 import org.splat.kernel.MismatchException;
 
-
 public class Converter implements MessageListener {
 
        /**
         * Converter logger.
         */
-    final static private Logger LOG = Logger.getLogger(Converter.class);
-
-    private final String  type;     // Type of document to be converted (e.g. geometry, model)
-    private final String  from;     // Source format (e.g. py, sldprt)
-    private final String  to;       // Target format (e.g. brep)
-    private final String  exec;     // Command line launching the actual converter
-    private String  fname;    // Absolute path of the source file to be converted
-
-//  ==============================================================================================================================
-//  Constructor
-//  ==============================================================================================================================
-
-    protected Converter (final String type, final String from, final String to, final String exec) {
-//  ----------------------------------------------------------------------
-      this.type  = type;
-      this.from  = from;
-      this.to    = to;
-      this.exec  = exec;
-      this.fname = null;
-      
-    }
-
-//  ==============================================================================================================================
-//  Public member functions
-//  ==============================================================================================================================
-
-    public void converts (final Publication source) throws MismatchException {
-//  -----------------------------------------
-      Document  sdoc = source.value();
-
-      if (!sdoc.getType().getName().equals(type)) {
-               throw new MismatchException();
-       }
-      if (!sdoc.getFormat().equals(from)) {
-               throw new MismatchException();
+       final static private Logger LOG = Logger.getLogger(Converter.class);
+
+       private final String _type; // Type of document to be converted (e.g. geometry, model)
+       private final String _from; // Source format (e.g. py, sldprt)
+       private final String _to; // Target format (e.g. brep)
+       private final String _exec; // Command line launching the actual converter
+       private String _fname; // Absolute path of the source file to be converted
+
+       // ==============================================================================================================================
+       // Constructor
+       // ==============================================================================================================================
+
+       protected Converter(final String type, final String from, final String to,
+                       final String exec) {
+               // ----------------------------------------------------------------------
+               this._type = type;
+               this._from = from;
+               this._to = to;
+               this._exec = exec;
+               this._fname = null;
+
        }
-      try {
-//      Initialization of the asynchronous communication with the actual converter
-        Context             context  = new InitialContext(ApplicationSettings.getNamingProperties());
-        ConnectionFactory   factory  = (javax.jms.QueueConnectionFactory)context.lookup("QueueConnectionFactory");
-        Connection          connex   = factory.createConnection();
-        Session             session  = connex.createSession(false, Session.AUTO_ACKNOWLEDGE);
-        Queue               queue    = session.createQueue("conversion");
-        MessageConsumer     consum   = session.createConsumer(queue);
-
-//      Listen for arriving messages
-        consum.setMessageListener(this);
-        connex.start();
-
-//      Start the conversion
-        String command    = ApplicationSettings.getApplicationPluginPath() + "converter.jar";
-        String option     = "-Dresource.dir=\"" + ApplicationSettings.getApplicationResourcePath() + "\"";
-        File   executable = new File(command);
-        if   (!executable.exists()) {
-                       throw new NoSuchMethodException();
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       public void converts(final Publication source) throws MismatchException {
+               // -----------------------------------------
+               Document sdoc = source.value();
+
+               if (!sdoc.getType().getName().equals(_type)) {
+                       throw new MismatchException();
                }
+               if (!sdoc.getFormat().equals(_from)) {
+                       throw new MismatchException();
+               }
+               Connection connex = null;
+               try {
+                       // Initialization of the asynchronous communication with the actual converter
+                       Context context = new InitialContext(ApplicationSettings
+                                       .getNamingProperties());
+                       ConnectionFactory factory = (javax.jms.QueueConnectionFactory) context
+                                       .lookup("QueueConnectionFactory");
+                       connex = factory.createConnection();
+                       Session session = connex.createSession(false,
+                                       Session.AUTO_ACKNOWLEDGE);
+                       Queue queue = session.createQueue("conversion");
+                       MessageConsumer consum = session.createConsumer(queue);
+
+                       // Listen for arriving messages
+                       consum.setMessageListener(this);
+                       connex.start();
+
+                       // Start the conversion
+                       String command = ApplicationSettings.getApplicationPluginPath()
+                                       + "converter.jar";
+                       String option = "-Dresource.dir=\""
+                                       + ApplicationSettings.getApplicationResourcePath() + "\"";
+                       File executable = new File(command);
+                       if (!executable.exists()) {
+                               throw new NoSuchMethodException();
+                       }
+
+                       File sfile = sdoc.getSourceFile().asFile();
+                       String args;
+
+                       _fname = sfile.getAbsolutePath();
+                       args = "\"" + _exec + "\" \"" + _fname + "\"";
+                       if (LOG.isInfoEnabled()) {
+                               LOG.info("Launching the conversion of " + sfile.getName()
+                                               + " to " + _to.toUpperCase() + " format using "
+                                               + command);
+                       }
+                       Runtime.getRuntime().exec(
+                                       "\"C:/Program Files/Java/jre6/bin/java.exe\" -jar "
+                                                       + option + " \"" + command + "\" " + args);
+               } catch (Exception error) {
+                       LOG.error("Reason: ", error);
+               } finally {
+                       if (connex != null) {
+                               try {
+                                       connex.close();
+                               } catch (JMSException e) {
+                                       LOG.error("Can't close the connection: ", e);
+                               }
+                       }
+               }
+
+       }
+
+       // ==============================================================================================================================
+       // Messages
+       // ==============================================================================================================================
 
-        File   sfile = sdoc.getSourceFile().asFile();
-        String args;
-
-        fname = sfile.getAbsolutePath();
-        args  = "\"" + exec + "\" \"" + fname + "\"";
-        if (LOG.isInfoEnabled()) {
-          LOG.info("Launching the conversion of " + sfile.getName() + " to " + to.toUpperCase() + " format using " + command);
-        }
-        Runtime.getRuntime().exec("\"C:/Program Files/Java/jre6/bin/java.exe\" -jar " + option + " \"" + command + "\" " + args);
-      }
-      catch (Exception error) {
-       LOG.error("Reason: ", error);
-      }
-    }
-
-//  ==============================================================================================================================
-//  Messages
-//  ==============================================================================================================================
-
-    public void onMessage (final Message msg) {
-      String  result = msg.toString();
-      LOG.info("Notification of availability of " + result);
+       public void onMessage(final Message msg) {
+               String result = msg.toString();
+               LOG.info("Notification of availability of " + result);
        }
 }
\ No newline at end of file
index b2197aac3e4486101f772389022c708329a58333..c4260d8d71ebb82ad5b2acb5deb96d2208b8760d 100644 (file)
@@ -140,21 +140,14 @@ public class EditDocumentAction extends DisplayStudyStepAction {
        public String doDeleteDocument() {
 
                setMenu();
+               _openStudy = getOpenStudy();
+               Step step = _openStudy.getSelectedStep();
+               Publication doctag = step.getDocument(Integer.valueOf(_index));
 
-               try {
-                       _openStudy = getOpenStudy();
-
-                       Step step = _openStudy.getSelectedStep();
-                       Publication doctag = step.getDocument(Integer.valueOf(_index));
-
-                       getStepService().removeDocument(step, doctag); // Updates the data structure
-
+               if (getStepService().removeDocument(step, Long.valueOf(_index))) { // Updates the data structure
                        _openStudy.remove(doctag); // Updates the presentation
-                       return SUCCESS;
-               } catch (RuntimeException saverror) {
-                       LOG.error("Reason:", saverror);
-                       return ERROR;
                }
+               return SUCCESS;
        }
 
        // ==============================================================================================================================
index 577b185609bd19b907da7e5db11467a6ae96c129..bf4804c7446927c01dcf18e8b68389050d04d431 100644 (file)
@@ -18,26 +18,20 @@ public class EditStudyAction extends DisplayStudyStepAction {
        // ==============================================================================================================================
 
        public String doEdition() {
-               try {
-                       _openStudy = getOpenStudy();
-
-                       Execute todo = Execute.valueOf(_action);
-                       Study study = _openStudy.getStudyObject();
-
-                       if (todo == Execute.publish) {
-                               getStudyService().moveToPublic(study);
-                       } else if (todo == Execute.promote) {
-                               getStudyService().moveToReference(study);
-                       }
-                       _openStudy.getPopup().setContext("study",
-                                       _openStudy.getStudyRights()); // The context has changed
-
-                       setMenu();
-
-                       return SUCCESS;
-               } catch (RuntimeException saverror) {
-                       LOG.error("Reason:", saverror);
-                       return ERROR;
+               _openStudy = getOpenStudy();
+
+               Execute todo = Execute.valueOf(_action);
+               Study study = _openStudy.getStudyObject();
+
+               if (todo == Execute.publish) {
+                       getStudyService().moveToPublic(study);
+               } else if (todo == Execute.promote) {
+                       getStudyService().moveToReference(study);
                }
+               _openStudy.getPopup().setContext("study", _openStudy.getStudyRights()); // The context has changed
+
+               setMenu();
+
+               return SUCCESS;
        }
 }
\ No newline at end of file
diff --git a/Workspace/Siman/src/org/splat/simer/ExceptionAction.java b/Workspace/Siman/src/org/splat/simer/ExceptionAction.java
new file mode 100644 (file)
index 0000000..ce18106
--- /dev/null
@@ -0,0 +1,217 @@
+/*****************************************************************************
+ * Company         OPEN CASCADE
+ * Application     SIMAN
+ * File            $Id$ 
+ * Creation date   13.12.2012
+ * @author         $Author$
+ * @version        $Revision$
+ * @copyright      OPEN CASCADE 2012
+ *****************************************************************************/
+
+package org.splat.simer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.struts2.ServletActionContext;
+import org.splat.exception.BusinessException;
+import org.splat.i18n.I18nUtils;
+import org.splat.log.AppLogger;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * The action for exception processing.
+ * 
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
+ */
+public class ExceptionAction extends ActionSupport {
+
+       /**
+        * The serial id.
+        */
+       private static final long serialVersionUID = 4818006367988105560L;
+
+       /**
+        * The action logger.
+        */
+       private final static AppLogger LOG = AppLogger
+                       .getLogger(ExceptionAction.class);
+
+       /**
+        * User interface message.
+        */
+       protected String _message;
+
+       /**
+        * the unexpected error i18n key.
+        */
+       private final static String UNEXPECTED_ERROR_KEY = "message.error.internal";
+
+       /**
+        * The name of the param in the http header.
+        */
+       private final static String PARAM_X_REQUESTED_WITH = "x-requested-with";
+
+       /**
+        * The value of a ajax request.
+        */
+       private final static String VALUE_AJAX_REQUEST = "XMLHttpRequest";
+
+       /**
+        * Process the exception.
+        * <ul>
+        * <li>log the exception</li>
+        * <li>display an unexpected error screen. This is configured in the struts config file</li>
+        * </ul>
+        * 
+        * @return the struts mapping
+        */
+       public String doProcess() {
+               ValueStack valueStack = null;
+               try {
+                       valueStack = ActionContext.getContext().getValueStack();
+                       Object obj = valueStack.findValue("exception");
+                       if (obj instanceof BusinessException) {
+                               BusinessException bex = (BusinessException) obj;
+                               LOG.error(bex.getMessageKey(), bex, bex.getContext());
+
+                               try {
+                                       this._message = I18nUtils.getMessage(ActionContext
+                                                       .getContext().getLocale(), bex.getMessageKey(), bex
+                                                       .getContext());
+                               } catch (RuntimeException e) {
+                                       this._message = e.getMessage();
+                               }
+
+                       }/*
+                                * else if (obj instanceof TechnicalException) { TechnicalException tex = (TechnicalException) obj;
+                                * LOG.error(tex.getMessageKey(), tex, tex.getContext());
+                                * 
+                                * try { this._uiMessage = I18nUtils.getMessage(ActionContext.getContext().getLocale(),tex.getMessageKey(),
+                                * tex.getContext()); } catch (RuntimeException e) { this._uiMessage = e.getMessage(); } } else if (obj instanceof
+                                * DAORequestTimeoutException) { this._uiMessage =
+                                * I18nUtils.getMessage(ActionContext.getContext().getLocale(),"err.a.request.timeout"); LOG.errorMsg(this._uiMessage,
+                                * (Exception)obj); }
+                                */
+                       else {
+
+                               Exception exc = (Exception) obj;
+                               StringBuffer msg = new StringBuffer();
+                               if (exc.getMessage() != null) {
+                                       msg.append(exc.getMessage());
+                                       LOG.errorMsg(exc.getMessage(), exc);
+                               }
+                               Throwable cause = exc.getCause();
+                               if (null != cause) {
+                                       LOG.errorMsg(cause.getMessage(), (Exception) cause);
+                                       msg.append(" ").append(cause.getMessage());
+                               }
+                               try {
+                                       this._message = getText(ExceptionAction.UNEXPECTED_ERROR_KEY);
+                               } catch (RuntimeException e) {
+                                       this._message = e.getMessage();
+                               }
+                               if (LOG.isDebugEnabled()) {
+                                       this._message += " " + exc.getClass().getSimpleName() + ": " + msg.toString();
+                                       LOG.debug("ExceptionAction: " + exc.getMessage(), exc);
+                               }
+                       }
+               } catch (RuntimeException e) {
+                       LOG.errorMsg(e.getMessage(), e);
+                       this._message = e.getMessage();
+                       Throwable cause = e.getCause();
+                       if (null != cause) {
+                               LOG.errorMsg(cause.getMessage(), (Exception) cause);
+                               this._message = cause.getMessage();
+                       }
+               }
+
+               return getResult(valueStack);
+       }
+
+       /**
+        * Define the result name: error for ajax request and sub-action, otherwise return success.
+        * 
+        * @param valueStack
+        *            struts context value stack
+        * @return action result name
+        */
+       protected String getResult(final ValueStack valueStack) {
+               String result;
+               // If subaction or ajaxRequest
+               if (checkIfSubAction(valueStack)
+                               || (VALUE_AJAX_REQUEST.equalsIgnoreCase(ServletActionContext
+                                               .getRequest().getHeader(PARAM_X_REQUESTED_WITH)))) {
+                       result = ERROR;
+               } else {
+                       result = SUCCESS;
+               }
+               return result;
+       }
+
+       /**
+        * Check if the exception is raised inside sub action.
+        * 
+        * @param valueStack
+        *            the action value stack
+        * @return true if the exception is raised inside sub action, return false otherwise
+        */
+       private boolean checkIfSubAction(final ValueStack valueStack) {
+               Set<ActionSupport> actionSet = new HashSet<ActionSupport>();
+
+               if (valueStack != null && valueStack.getContext() != null) {
+                       // checks if the action is a chainActionResult. In that case, return false
+                       Object test = valueStack.getContext().get("CHAIN_HISTORY");
+
+                       if (test == null) {
+                               int nValueStackSize = valueStack.size();
+                               for (int i = 0; i < nValueStackSize; i++) {
+                                       String key = "[" + i + "]";
+                                       Object obj = valueStack.findValue(key);
+                                       if (obj instanceof ActionSupport
+                                                       && !(obj instanceof ExceptionAction)) {
+                                               actionSet.add((ActionSupport) obj);
+                                       }
+
+                                       if (obj instanceof com.opensymphony.xwork2.util.CompoundRoot) {
+                                               com.opensymphony.xwork2.util.CompoundRoot root = (com.opensymphony.xwork2.util.CompoundRoot) obj;
+                                               int nSize = root.size();
+                                               for (int j = 0; j < nSize; j++) {
+                                                       obj = root.get(j);
+                                                       if ((obj instanceof ActionSupport)
+                                                                       && !(obj instanceof ExceptionAction)) {
+                                                               actionSet.add((ActionSupport) obj);
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else {
+                               actionSet.clear();
+                       }
+               }
+               return (actionSet.size() > 1);
+       }
+
+       /**
+        * Get the ui message.
+        * 
+        * @return the message
+        */
+       public String getMessage() {
+               return _message;
+       }
+
+       /**
+        * Set the user interface message.
+        * 
+        * @param aMessage
+        *            the user interface message
+        */
+       public void setMessage(final String aMessage) {
+               _message = aMessage;
+       }
+
+}
index be785bcef57662c0654c90282a4dc83f93c0eb1f..3462674ad4452886d2394cc41ab7148e147b704d 100644 (file)
@@ -284,7 +284,8 @@ public class StudyPropertiesAction extends DisplayStudyStepAction {
                        try {
                                getStudyService().update(study, sprop.setTitle(_stitle));
                        } catch (InvalidPropertyException e) {
-                               // TODO
+                               // TODO:
+                               LOG.error(e.getMessage(), e);
                        }
                } else if (_tosave == Save.contributor) {
 
index 68674115cbcb2bb46db2d6db44613ed456d43db2..1225c736ac3e01e36ed2ba0b6560fe6795f9fa15 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
@@ -16,22 +17,26 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
        <!-- configuration i18n -->
        <bean id="i18nUtils" class="org.splat.i18n.I18nUtils">
-               <property name="resourceBundleMessageSource" ref="messageSource" />
+               <property name="resourceBundleMessageSource"
+                       ref="messageSource" />
        </bean>
 
        <bean id="messageSource"
                class="org.springframework.context.support.ResourceBundleMessageSource">
                <property name="basenames">
                        <list>
-                <value>conf/log-messages</value>
+                               <value>conf/log-messages</value>
                        </list>
                </property>
        </bean>
        <!-- ref 'baseMessageSource' into Siman-common\src\spring\globalContext.xml -->
        <!-- property name="parentMessageSource" ref="baseMessageSource"/ -->
 
-       <bean id="applicationSettings" class="org.splat.simer.ApplicationSettings"
-               scope="session">
+       <bean id="exceptionAction" class="org.splat.simer.ExceptionAction"
+               scope="prototype" />
+
+       <bean id="applicationSettings"
+               class="org.splat.simer.ApplicationSettings" scope="session">
                <property name="projectSettings" ref="projectSettings" />
                <property name="documentTypeService" ref="documentTypeService" />
        </bean>
@@ -53,12 +58,13 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        </bean>
 
        <bean id="slidMenu" scope="session" abstract="true">
-               <property name="projectElementService" ref="projectElementService" />
+               <property name="projectElementService"
+                       ref="projectElementService" />
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
-       <bean id="studyMenu" class="org.splat.simer.StudyMenu" scope="session"
-               parent="slidMenu" />
+       <bean id="studyMenu" class="org.splat.simer.StudyMenu"
+               scope="session" parent="slidMenu" />
 
        <bean id="newScenarioMenu" class="org.splat.simer.NewScenarioMenu"
                scope="session" parent="slidMenu" />
@@ -66,14 +72,17 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <bean id="openObject" abstract="true"
                class="org.splat.simer.AbstractOpenObject" scope="session">
                <property name="applicationSettings" ref="applicationSettings" />
-               <property name="projectElementService" ref="projectElementService" />
+               <property name="projectElementService"
+                       ref="projectElementService" />
                <property name="projectSettings" ref="projectSettings" />
-               <property name="knowledgeElementTypeService" ref="knowledgeElementTypeService" />
+               <property name="knowledgeElementTypeService"
+                       ref="knowledgeElementTypeService" />
        </bean>
 
-       <bean id="openStudy" class="org.splat.simer.OpenStudy" parent="openObject"
-               scope="session">
-               <property name="projectElementService" ref="projectElementService" />
+       <bean id="openStudy" class="org.splat.simer.OpenStudy"
+               parent="openObject" scope="session">
+               <property name="projectElementService"
+                       ref="projectElementService" />
                <property name="publicationService" ref="publicationService" />
                <property name="studyService" ref="studyService" />
                <property name="stepService" ref="stepService" />
@@ -87,8 +96,8 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                parent="openObject" scope="session">
        </bean>
 
-       <bean id="baseAction" class="org.splat.simer.Action" scope="prototype"
-               abstract="true">
+       <bean id="baseAction" class="org.splat.simer.Action"
+               scope="prototype" abstract="true">
                <property name="applicationSettings" ref="applicationSettings" />
                <property name="openStudy" ref="openStudy" />
                <property name="openKnowledge" ref="openKnowledge" />
@@ -102,13 +111,16 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
        <bean id="newStudyAction" class="org.splat.simer.NewStudyAction"
                parent="baseAction" scope="prototype">
-               <property name="simulationContextService" ref="simulationContextService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
-       <bean id="newScenarioAction" class="org.splat.simer.NewScenarioAction"
-               parent="baseAction" scope="prototype">
-               <property name="projectElementService" ref="projectElementService" />
+       <bean id="newScenarioAction"
+               class="org.splat.simer.NewScenarioAction" parent="baseAction"
+               scope="prototype">
+               <property name="projectElementService"
+                       ref="projectElementService" />
                <property name="scenarioService" ref="scenarioService" />
                <property name="menu" ref="newScenarioMenu" />
        </bean>
@@ -118,8 +130,9 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
-       <bean id="importDocumentAction" class="org.splat.simer.ImportDocumentAction"
-               scope="prototype" parent="baseAction">
+       <bean id="importDocumentAction"
+               class="org.splat.simer.ImportDocumentAction" scope="prototype"
+               parent="baseAction">
                <property name="stepService" ref="stepService" />
                <property name="projectSettings" ref="projectSettings" />
                <property name="publicationService" ref="publicationService" />
@@ -128,15 +141,17 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="documentTypeService" ref="documentTypeService" />
        </bean>
 
-       <bean id="displayStudyStepAction" class="org.splat.simer.DisplayStudyStepAction"
-               parent="baseAction" scope="prototype">
+       <bean id="displayStudyStepAction"
+               class="org.splat.simer.DisplayStudyStepAction" parent="baseAction"
+               scope="prototype">
                <property name="studyService" ref="studyService" />
        </bean>
 
        <!--========= Inherited from displayStudyStepAction ========= -->
 
-       <bean id="studyPropertiesAction" class="org.splat.simer.StudyPropertiesAction"
-               scope="prototype" parent="displayStudyStepAction">
+       <bean id="studyPropertiesAction"
+               class="org.splat.simer.StudyPropertiesAction" scope="prototype"
+               parent="displayStudyStepAction">
                <property name="documentTypeService" ref="documentTypeService" />
                <property name="userService" ref="userService" />
        </bean>
@@ -145,37 +160,46 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                scope="prototype" parent="displayStudyStepAction">
        </bean>
 
-       <bean id="editScenarioPropertiesAction" class="org.splat.simer.EditScenarioPropertiesAction"
-               scope="prototype" parent="displayStudyStepAction">
-               <property name="projectElementService" ref="projectElementService" />
+       <bean id="editScenarioPropertiesAction"
+               class="org.splat.simer.EditScenarioPropertiesAction" scope="prototype"
+               parent="displayStudyStepAction">
+               <property name="projectElementService"
+                       ref="projectElementService" />
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
-       <bean id="editSimulationContextAction" class="org.splat.simer.EditSimulationContextAction"
-               scope="prototype" parent="displayStudyStepAction">
+       <bean id="editSimulationContextAction"
+               class="org.splat.simer.EditSimulationContextAction" scope="prototype"
+               parent="displayStudyStepAction">
                <property name="stepService" ref="stepService" />
-               <property name="simulationContextService" ref="simulationContextService" />
-               <property name="simulationContextTypeService" ref="simulationContextTypeService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
+               <property name="simulationContextTypeService"
+                       ref="simulationContextTypeService" />
        </bean>
 
-       <bean id="editDocumentAction" class="org.splat.simer.EditDocumentAction"
-               scope="prototype" parent="displayStudyStepAction">
+       <bean id="editDocumentAction"
+               class="org.splat.simer.EditDocumentAction" scope="prototype"
+               parent="displayStudyStepAction">
                <property name="stepService" ref="stepService" />
                <property name="publicationService" ref="publicationService" />
                <property name="repositoryService" ref="repositoryService" />
        </bean>
 
-       <bean id="editKnowledgeElementAction" class="org.splat.simer.EditKnowledgeElementAction"
-               scope="prototype" parent="displayStudyStepAction">
-               <property name="knowledgeElementService" ref="knowledgeElementService" />
-               <property name="knowledgeElementTypeService" ref="knowledgeElementTypeService" />
+       <bean id="editKnowledgeElementAction"
+               class="org.splat.simer.EditKnowledgeElementAction" scope="prototype"
+               parent="displayStudyStepAction">
+               <property name="knowledgeElementService"
+                       ref="knowledgeElementService" />
+               <property name="knowledgeElementTypeService"
+                       ref="knowledgeElementTypeService" />
                <property name="scenarioService" ref="scenarioService" />
        </bean>
 
        <!-- End of Inherited from displayStudyStepAction -->
 
-       <bean id="startAction" class="org.splat.simer.StartAction" scope="prototype"
-               parent="baseAction">
+       <bean id="startAction" class="org.splat.simer.StartAction"
+               scope="prototype" parent="baseAction">
                <property name="applicationSettings" ref="applicationSettings" />
                <property name="projectSettings" ref="projectSettings" />
        </bean>
@@ -183,37 +207,45 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                scope="prototype" parent="baseAction">
        </bean>
 
-       <bean id="menuAction" class="org.splat.simer.MenuAction" scope="prototype"
-               parent="baseAction">
+       <bean id="menuAction" class="org.splat.simer.MenuAction"
+               scope="prototype" parent="baseAction">
        </bean>
 
-       <bean id="notYetImplementedAction" class="org.splat.simer.NotYetImplementedAction"
-               scope="prototype" parent="baseAction">
+       <bean id="notYetImplementedAction"
+               class="org.splat.simer.NotYetImplementedAction" scope="prototype"
+               parent="baseAction">
        </bean>
 
-       <bean id="searchStudyAction" class="org.splat.simer.SearchStudyAction"
-               scope="prototype" parent="baseAction">
+       <bean id="searchStudyAction"
+               class="org.splat.simer.SearchStudyAction" scope="prototype"
+               parent="baseAction">
                <property name="projectSettings" ref="projectSettings" />
                <property name="searchService" ref="searchService" />
-               <property name="simulationContextService" ref="simulationContextService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
                <property name="userService" ref="userService" />
        </bean>
 
-       <bean id="searchKnowledgeAction" class="org.splat.simer.SearchKnowledgeAction"
-               scope="prototype" parent="baseAction">
+       <bean id="searchKnowledgeAction"
+               class="org.splat.simer.SearchKnowledgeAction" scope="prototype"
+               parent="baseAction">
                <property name="searchService" ref="searchService" />
-               <property name="simulationContextService" ref="simulationContextService" />
-               <property name="knowledgeElementTypeService" ref="knowledgeElementTypeService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
+               <property name="knowledgeElementTypeService"
+                       ref="knowledgeElementTypeService" />
                <property name="userService" ref="userService" />
        </bean>
 
-       <bean id="searchDocumentAction" class="org.splat.simer.SearchDocumentAction"
-               scope="prototype">
+       <bean id="searchDocumentAction"
+               class="org.splat.simer.SearchDocumentAction" scope="prototype">
        </bean>
 
-       <bean id="displayKnowledgeAction" class="org.splat.simer.DisplayKnowledgeAction"
-               scope="prototype" parent="baseAction">
-               <property name="knowledgeElementService" ref="knowledgeElementService" />
+       <bean id="displayKnowledgeAction"
+               class="org.splat.simer.DisplayKnowledgeAction" scope="prototype"
+               parent="baseAction">
+               <property name="knowledgeElementService"
+                       ref="knowledgeElementService" />
        </bean>
 
        <bean id="uploadAction" class="org.splat.simer.UploadAction"
@@ -221,49 +253,58 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                <property name="repositoryService" ref="repositoryService" />
        </bean>
 
-       <bean id="uploadStudyAction" class="org.splat.simer.UploadStudyAction"
-               scope="prototype" parent="baseAction">
+       <bean id="uploadStudyAction"
+               class="org.splat.simer.UploadStudyAction" scope="prototype"
+               parent="baseAction">
        </bean>
 
-       <bean id="versionDocumentAction" class="org.splat.simer.VersionDocumentAction"
-               scope="prototype" parent="baseAction">
+       <bean id="versionDocumentAction"
+               class="org.splat.simer.VersionDocumentAction" scope="prototype"
+               parent="baseAction">
                <property name="projectSettings" ref="projectSettings" />
                <property name="publicationService" ref="publicationService" />
                <property name="stepService" ref="stepService" />
                <property name="repositoryService" ref="repositoryService" />
        </bean>
 
-       <bean id="databaseIndexingAction" class="org.splat.simer.admin.DatabaseIndexingAction"
-               scope="prototype" parent="baseAction">
+       <bean id="databaseIndexingAction"
+               class="org.splat.simer.admin.DatabaseIndexingAction" scope="prototype"
+               parent="baseAction">
                <property name="searchService" ref="searchService" />
        </bean>
 
-       <bean id="importUserAction" class="org.splat.simer.admin.ImportUserAction"
-               scope="prototype" parent="baseAction">
+       <bean id="importUserAction"
+               class="org.splat.simer.admin.ImportUserAction" scope="prototype"
+               parent="baseAction">
                <property name="repositoryService" ref="repositoryService" />
                <property name="userService" ref="userService" />
        </bean>
 
-       <bean id="simulationContextAction" class="org.splat.simer.admin.SimulationContextAction"
+       <bean id="simulationContextAction"
+               class="org.splat.simer.admin.SimulationContextAction"
                scope="prototype" parent="baseAction">
-               <property name="knowledgeElementService" ref="knowledgeElementService" />
+               <property name="knowledgeElementService"
+                       ref="knowledgeElementService" />
                <property name="searchService" ref="searchService" />
                <property name="projectSettings" ref="projectSettings" />
-               <property name="simulationContextService" ref="simulationContextService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
        </bean>
 
-       <bean id="knowledgeElementAction" class="org.splat.simer.admin.KnowledgeElementAction"
+       <bean id="knowledgeElementAction"
+               class="org.splat.simer.admin.KnowledgeElementAction"
                scope="prototype">
        </bean>
 
-       <bean id="saveDocumentAction" class="org.splat.module.SaveDocumentAction"
-               scope="prototype">
+       <bean id="saveDocumentAction"
+               class="org.splat.module.SaveDocumentAction" scope="prototype">
                <property name="documentTypeService" ref="documentTypeService" />
                <property name="publicationService" ref="publicationService" />
                <property name="repositoryService" ref="repositoryService" />
                <property name="scenarioService" ref="scenarioService" />
                <property name="stepService" ref="stepService" />
-               <property name="simulationContextService" ref="simulationContextService" />
+               <property name="simulationContextService"
+                       ref="simulationContextService" />
        </bean>
 
 </beans>
index bc90fe82e5e54ef260427a2b0ff3259e81f7d34e..d60b1b9a750324ad5de305bb6a7b9fda956a3d6e 100644 (file)
 
 <struts>
        <constant name="struts.objectFactory" value="spring" />
-    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
-    <constant name="struts.devMode" value="true" />
-    <constant name="struts.custom.i18n.resources" value="log-messages,labels,som" />
-    <constant name="struts.i18n.encoding" value="ISO-8859-1" />
-    <constant name="struts.multipart.maxSize" value="100485760" />
-
-    <package name="simer-default" namespace="/" extends="struts-default">
-    </package>
-
-    <package name="default" namespace="/" extends="simer-default">
-       
-       <result-types>
-               <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
-       </result-types>
-
-        <default-action-ref name="index" />
-
-        <action name="index" class="startAction" method="initialize">
-            <result name="success" type="tiles">page.welcome</result>
-            <result name="error" type="tiles">page.exception</result>
-        </action>        
-        <action name="login" class="connectionAction" method="login">
-            <result name="none" type="tiles">page.home</result>
-            <result name="open"      type="redirectAction">select?menu=search</result>
-            <result name="study"     type="redirectAction">study/step-study</result>
-            <result name="knowledge" type="redirectAction">study/step-knowledge</result>
-            <!--result name="input">/login.jsp</result-->
-            <result name="input" type="tiles">page.login</result>
-            <result name="error" type="tiles">page.home</result>
-        </action>
-        <action name="logout" class="connectionAction" method="logout">
-            <result name="none" type="tiles">page.home</result>
-            <result name="create" type="tiles">page.home</result>
-            <result name="open"      type="redirectAction">select?menu=search</result>
-            <result name="study"     type="redirectAction">study/step-study</result>
-            <result name="knowledge" type="redirectAction">study/step-knowledge</result>
-            <result name="datadmin" type="tiles">page.home</result>
-            <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="search-study"     type="redirectAction">study/search-study</result>
-            <result name="search-knowledge" type="redirectAction">study/search-knowledge</result>
-            <result name="search-document"  type="redirectAction">study/search-document</result>
-            <result name="prop-general"     type="redirectAction">study/prop-study</result>
-            <result name="prop-scenario"    type="redirectAction">study/prop-scenario</result>
-            <result name="admin-indexing"   type="redirectAction">sadmin/indexing</result>
-            <result name="admin-importuser" type="redirectAction">sadmin/select-file?nextAction=importuser</result>
-            <result name="admin-scontext"   type="redirectAction">sadmin/scontext</result>
-            <result name="admin-knowelm"    type="redirectAction">sadmin/knowlelm</result>
-            <!-- If no menu item is selected then go to home page -->
-            <result name="none" type="tiles">page.home</result>
-        </action>
-
-    </package>
-
-    <package name="study" namespace="/study" extends="simer-default">
-    
-        <result-types>
-               <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
-       </result-types>
-
-        <action name="notyetimplemented" class="notYetImplementedAction" method="initialize">
-            <result name="success" type="tiles">page.error.study</result>
-        </action>
-
-        <action name="checkout" class="checkoutAction" method="checkout">
-            <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">
-            <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>
-
-        <!-- Search for studies, knowledge elements and documents
-          -->
-        <action name="search-study" class="searchStudyAction" method="initialize">
-            <result name="success" type="tiles">page.searchstudy</result>
-            <result name="error" type="tiles">page.home</result>
-        </action>
-        <action name="refresh-study" class="searchStudyAction" method="submitForm">
-            <result name="selectype" type="tiles">page.searchstudy</result>
-            <result name="refresh" type="tiles">page.searchstudy</result>
-            <result name="wait" type="tiles">page.searchstudy</result>
-            <result name="error" type="redirectAction">search-study</result>
-        </action>
-
-        <action name="search-knowledge" class="searchKnowledgeAction" method="initialize">
-            <result name="success" type="tiles">page.searchknowledge</result>
-        </action>
-        <action name="refresh-knowledge" class="searchKnowledgeAction" method="submitForm">
-            <result name="selectype" type="tiles">page.searchknowledge</result>
-            <result name="refresh" type="tiles">page.searchknowledge</result>
-            <result name="wait" type="tiles">page.searchknowledge</result>
-            <result name="error" type="redirectAction">search-knowledge</result>
-        </action>
-
-        <action name="search-document" class="searchDocumentAction" method="initialize">
-            <result name="success">/study/searchDocument.jsp</result>
-        </action>
-
-        <!-- Display of studies
-          -->
-        <action name="open-study" class="displayStudyStepAction" method="open">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="step-study" class="displayStudyStepAction" method="selectStep">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="document-study" class="displayStudyStepAction" method="selectDocument">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="knowledge-study" class="displayStudyStepAction" method="selectKnowledge">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="close-study" class="displayStudyStepAction" method="close">
-            <result name="success" type="tiles">page.home</result>
-        </action>
-        <action name="prop-study" class="studyPropertiesAction" method="initialize">
-            <result name="display" type="tiles">page.displaystudyproperties</result>
-            <result name="edit" type="tiles">page.editstudyproperties</result>
-        </action>
-
-        <!-- Display of knowledge elements
-          -->        
-        <action name="open-knowledge" class="displayKnowledgeAction" method="open">
-            <result name="success" type="tiles">page.displayknowledge</result>
-        </action>
-        <action name="step-knowledge" class="displayKnowledgeAction" method="selectStep">
-            <result name="success" type="tiles">page.displayknowledge</result>
-        </action>
-        <action name="document-knowledge" class="displayKnowledgeAction" method="selectDocument">
-            <result name="success" type="tiles">page.displayknowledge</result>
-        </action>
-        <action name="knowledge-knowledge" class="displayKnowledgeAction" method="selectKnowledge">
-            <result name="success" type="tiles">page.displayknowledge</result>
-        </action>
-        <action name="close-knowledge" class="displayKnowledgeAction" method="close">
-            <result name="success" type="tiles">page.home</result>
-        </action>
-
-        <!-- Edition of study
-          -->        
-        <action name="edit-study" class="editStudyAction" method="edition">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="add-scenario" class="newScenarioAction" method="initialize">
-            <result name="success" type="tiles">page.newscenario</result>
-        </action>
-        <action name="edit-title" class="studyPropertiesAction" method="editTitle">
-            <result name="success" type="tiles">page.editstudyproperties</result>
-        </action>
-        <action name="edit-contributor" class="studyPropertiesAction" method="editContributors">
-            <result name="success" type="tiles">page.editstudyproperties</result>
-        </action>
-        <action name="edit-cycle" class="studyPropertiesAction" method="editCycle">
-            <result name="success" type="tiles">page.editstudyproperties</result>
-        </action>
-        <action name="select-step" class="newScenarioAction" method="selectStep">
-            <result name="success" type="tiles">page.newscenario</result>
-        </action>
-        <action name="valid-add" class="newScenarioAction" method="create">
-            <result name="cancel"  type="redirectAction">step-study</result>
-            <result name="success" type="redirectAction">step-study</result>
-           <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="valid-edit" class="studyPropertiesAction" method="edition">
-            <result name="success" type="tiles">page.editstudyproperties</result>
-        </action>
-        <action name="prop-scenario" class="editScenarioPropertiesAction" method="initialize">
-            <result name="success" type="tiles">page.editscenarioproperties</result>
-        </action>
-
-        <!-- Edition of scenario
-          -->
-        <action name="checkin-scenario" class="editScenarioPropertiesAction" method="checkin">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-
-        <!-- Edition of simulation contexts
-          -->        
-        <action name="add-context" class="editSimulationContextAction" method="initialize">
-            <result name="create" type="tiles">page.newcontext</result>
-            <result name="select" type="tiles">page.selectcontext</result>
-        </action>
-        <action name="selectContext" class="editSimulationContextAction" method="selectContext">
-            <result name="create" type="tiles">page.newcontext</result>
-            <result name="set"    type="tiles">page.setcontext</result>
-        </action>
-        <action name="newContext" class="editSimulationContextAction" method="createContext">
-            <result name="success" type="tiles">page.displaystudy</result>
-            <result name="input" type="tiles">page.newcontext</result>
-            <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="setContext" class="editSimulationContextAction" method="setContext">
-            <result name="success" type="tiles">page.displaystudy</result>
-            <result name="input" type="tiles">page.setcontext</result>
-            <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="remove-context" class="editSimulationContextAction" method="deleteContext">
-            <result name="success" type="tiles">page.displaystudy</result>
-            <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-
-        <!-- Edition of documents
-          -->
-        <action name="select-file" class="uploadAction" method="initialize">
-            <result name="success" type="tiles">page.uploadstudy</result>
-        </action>
-        <action name="upload" class="uploadAction" method="upload">
-            <result name="cancel"  type="redirectAction">step-study</result>
-            <result name="import"  type="redirectAction">import-document?fileName=%{fileName}</result>
-            <result name="version" type="redirectAction">version-document?index=%{index}&amp;fileName=%{fileName}</result>
-            <result name="attach"  type="redirectAction">attach-document?index=%{index}&amp;fileName=%{fileName}</result>
-            <result name="outofmemory" type="tiles">page.error.study</result>
-        </action>
-        <action name="import-document" class="importDocumentAction" method="initialize">
-            <result name="success" type="tiles">page.importdocument</result>
-            <result name="error" type="tiles">page.importerror</result>
-        </action>
-        <action name="valid-import" class="importDocumentAction" method="import">
-            <result name="success" type="redirectAction">step-study</result>
-            <result name="cancel"  type="redirectAction">step-study</result>
-            <result name="error" type="tiles">page.importerror</result>
-        </action>
-        <action name="version-document" class="versionDocumentAction" method="initialize">
-            <result name="success" type="tiles">page.versiondocument</result>
-            <result name="error" type="tiles">page.importerror</result>
-        </action>
-        <action name="valid-version" class="versionDocumentAction" method="version">
-            <result name="success" type="redirectAction">step-study</result>
-            <result name="cancel"  type="redirectAction">step-study</result>
-            <result name="error" type="tiles">page.importerror</result>
-        </action>
-        <action name="attach-document" class="editDocumentAction" method="attach">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="edit-document" class="editDocumentAction" method="initialize">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="setDocument" class="editDocumentAction" method="setDocument">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="remove-document" class="editDocumentAction" method="deleteDocument">
-            <result name="success" type="tiles">page.displaystudy</result>
-            <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-
-        <!-- Edition of knowledge elements
-          -->        
-        <action name="add-knowledge" class="editKnowledgeElementAction" method="initialize">
-<!--             <result name="success">/study/displayStudy.jsp?action=addKnowledge&amp;index=%{knowledgeType}</result>-->
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="edit-knowledge" class="editKnowledgeElementAction" method="initialize">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="setKnowledge" class="editKnowledgeElementAction" method="setKnowledge">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="remove-knowledge" class="editKnowledgeElementAction" method="deleteKnowledge">
-            <result name="success" type="tiles">page.displaystudy</result>
-            <result name="error" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="promote-knowledge" class="editKnowledgeElementAction" method="promoteKnowledge">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-        <action name="demote-knowledge" class="editKnowledgeElementAction" method="demoteKnowledge">
-            <result name="success" type="tiles">page.displaystudy</result>
-        </action>
-
-    </package>
-
-
-    <package name="sadmin" namespace="/sadmin" extends="simer-default">
-    
-        <result-types>
-               <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
-       </result-types>
-
-        <!-- Menus of database administration
-          -->        
-        <action name="indexing" class="databaseIndexingAction" method="initialize">
-            <result name="success" type="tiles">page.indexstudies</result>
-        </action>
-        <action name="valid-indexing" class="databaseIndexingAction" method="indexing">
-            <result name="success" type="redirectAction">../study/search-study</result>
-        </action>
-        <action name="select-file" class="uploadAction" method="initialize">
-            <result name="success" type="tiles">page.uploadsadmin</result>
-        </action>
-        <action name="upload"      class="uploadAction" method="upload">
-            <result name="cancel" type="tiles">page.home</result>
-            <result name="importuser" type="redirectAction">importuser?fileName=%{fileName}</result>
-        </action>
-        <action name="importuser" class="importUserAction" method="import">
-            <result name="success" type="tiles">page.displayuser</result>
-        </action>
-
-        <!-- Menus of knowledge administration
-          -->        
-        <action name="scontext" class="simulationContextAction" method="initialize">
-            <result name="success">/sadmin/approveSContext.jsp</result>
-        </action>
-        <action name="scontext-edit" class="simulationContextAction" method="select">
-            <result name="success">/sadmin/approveSContext.jsp</result>
-        </action>
-        <action name="knowelm"  class="knowledgeElementAction" method="initialize">
-            <result name="success">/sadmin/approveKnowelm.jsp</result>
-        </action>
-    </package>
-
-    <package name="sgeom" namespace="/sgeom" extends="simer-default">
-    
-       <result-types>
-               <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
-       </result-types>
-
-        <action name="valid-save"    class="saveDocumentAction" method="save">
-            <result name="success">/sgeom/index.jsp</result>
-        </action>
-        <action name="valid-update"  class="saveDocumentAction" method="update">
-            <result name="success">/sgeom/index.jsp</result>
-        </action>
-        <action name="valid-version" class="saveDocumentAction" method="version">
-            <result name="success">/sgeom/index.jsp</result>
-        </action>
-
-    </package>
-
-
-    <package name="smesh" namespace="/smesh" extends="simer-default">
-    
-        <result-types>
-               <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
-       </result-types>
-
-        <action name="valid-save"    class="saveDocumentAction" method="save">
-            <result name="success">/smesh/index.jsp</result>
-        </action>
-        <action name="valid-update"  class="saveDocumentAction" method="update">
-            <result name="success">/smesh/index.jsp</result>
-        </action>
-        <action name="valid-version" class="saveDocumentAction" method="version">
-            <result name="success">/smesh/index.jsp</result>
-        </action>
-
-    </package>
+       <constant name="struts.enable.DynamicMethodInvocation"
+               value="false" />
+       <constant name="struts.devMode" value="true" />
+       <constant name="struts.custom.i18n.resources"
+               value="log-messages,labels,som" />
+       <constant name="struts.i18n.encoding" value="ISO-8859-1" />
+       <constant name="struts.multipart.maxSize" value="100485760" />
+
+       <package name="simer-default" namespace="/"
+               extends="struts-default">
+
+               <result-types>
+                       <result-type name="tiles"
+                               class="org.apache.struts2.views.tiles.TilesResult" />
+               </result-types>
+
+               <global-results>
+                       <result name="exception" type="chain">
+                               exceptionAction
+                       </result>
+               </global-results>
+
+               <global-exception-mappings>
+                       <exception-mapping exception="java.lang.Exception"
+                               result="exception" />
+               </global-exception-mappings>
+
+
+               <action name="exceptionAction" class="exceptionAction"
+                       method="process">
+                       <interceptor-ref name="exception" />
+                       <interceptor-ref name="basicStack" />
+                       <result name="error" type="tiles">page.home</result>
+                       <result name="success" type="tiles">page.home</result>
+               </action>
+       </package>
+
+
+       <package name="default" namespace="/" extends="simer-default">
+
+               <default-action-ref name="index" />
+
+               <!-- 
+                       <action name="test.exception.page" class="testExceptionAction" method="throwException">
+                       <result name="success" type="tiles">page.test.exception</result>
+                       </action>
+                       <action name="test.json.exception.page">
+                       <result name="success" type="tiles">page.test.json.exception</result>
+                       </action>
+               -->
+               <action name="index" class="startAction" method="initialize">
+                       <result name="success" type="tiles">page.welcome</result>
+                       <result name="error" type="tiles">page.exception</result>
+               </action>
+               <action name="login" class="connectionAction" method="login">
+                       <result name="none" type="tiles">page.home</result>
+                       <result name="open" type="redirectAction">
+                               select?menu=search
+                       </result>
+                       <result name="study" type="redirectAction">
+                               study/step-study
+                       </result>
+                       <result name="knowledge" type="redirectAction">
+                               study/step-knowledge
+                       </result>
+                       <!--result name="input">/login.jsp</result-->
+                       <result name="input" type="tiles">page.login</result>
+                       <result name="error" type="tiles">page.home</result>
+               </action>
+               <action name="logout" class="connectionAction"
+                       method="logout">
+                       <result name="none" type="tiles">page.home</result>
+                       <result name="create" type="tiles">page.home</result>
+                       <result name="open" type="redirectAction">
+                               select?menu=search
+                       </result>
+                       <result name="study" type="redirectAction">
+                               study/step-study
+                       </result>
+                       <result name="knowledge" type="redirectAction">
+                               study/step-knowledge
+                       </result>
+                       <result name="datadmin" type="tiles">page.home</result>
+                       <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="search-study" type="redirectAction">
+                               study/search-study
+                       </result>
+                       <result name="search-knowledge" type="redirectAction">
+                               study/search-knowledge
+                       </result>
+                       <result name="search-document" type="redirectAction">
+                               study/search-document
+                       </result>
+                       <result name="prop-general" type="redirectAction">
+                               study/prop-study
+                       </result>
+                       <result name="prop-scenario" type="redirectAction">
+                               study/prop-scenario
+                       </result>
+                       <result name="admin-indexing" type="redirectAction">
+                               sadmin/indexing
+                       </result>
+                       <result name="admin-importuser" type="redirectAction">
+                               sadmin/select-file?nextAction=importuser
+                       </result>
+                       <result name="admin-scontext" type="redirectAction">
+                               sadmin/scontext
+                       </result>
+                       <result name="admin-knowelm" type="redirectAction">
+                               sadmin/knowlelm
+                       </result>
+                       <!-- If no menu item is selected then go to home page -->
+                       <result name="none" type="tiles">page.home</result>
+               </action>
+
+       </package>
+
+       <package name="study" namespace="/study" extends="simer-default">
+
+               <result-types>
+                       <result-type name="tiles"
+                               class="org.apache.struts2.views.tiles.TilesResult" />
+               </result-types>
+
+               <action name="notyetimplemented" class="notYetImplementedAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.error.study
+                       </result>
+               </action>
+
+               <action name="checkout" class="checkoutAction"
+                       method="checkout">
+                       <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">
+                       <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>
+
+               <!-- Search for studies, knowledge elements and documents
+               -->
+               <action name="search-study" class="searchStudyAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.searchstudy
+                       </result>
+                       <result name="error" type="tiles">page.home</result>
+               </action>
+               <action name="refresh-study" class="searchStudyAction"
+                       method="submitForm">
+                       <result name="selectype" type="tiles">
+                               page.searchstudy
+                       </result>
+                       <result name="refresh" type="tiles">
+                               page.searchstudy
+                       </result>
+                       <result name="wait" type="tiles">page.searchstudy</result>
+                       <result name="error" type="redirectAction">
+                               search-study
+                       </result>
+               </action>
+
+               <action name="search-knowledge" class="searchKnowledgeAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.searchknowledge
+                       </result>
+               </action>
+               <action name="refresh-knowledge" class="searchKnowledgeAction"
+                       method="submitForm">
+                       <result name="selectype" type="tiles">
+                               page.searchknowledge
+                       </result>
+                       <result name="refresh" type="tiles">
+                               page.searchknowledge
+                       </result>
+                       <result name="wait" type="tiles">
+                               page.searchknowledge
+                       </result>
+                       <result name="error" type="redirectAction">
+                               search-knowledge
+                       </result>
+               </action>
+
+               <action name="search-document" class="searchDocumentAction"
+                       method="initialize">
+                       <result name="success">/study/searchDocument.jsp</result>
+               </action>
+
+               <!-- Display of studies
+               -->
+               <action name="open-study" class="displayStudyStepAction"
+                       method="open">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="step-study" class="displayStudyStepAction"
+                       method="selectStep">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="document-study" class="displayStudyStepAction"
+                       method="selectDocument">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="knowledge-study" class="displayStudyStepAction"
+                       method="selectKnowledge">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="close-study" class="displayStudyStepAction"
+                       method="close">
+                       <result name="success" type="tiles">page.home</result>
+               </action>
+               <action name="prop-study" class="studyPropertiesAction"
+                       method="initialize">
+                       <result name="display" type="tiles">
+                               page.displaystudyproperties
+                       </result>
+                       <result name="edit" type="tiles">
+                               page.editstudyproperties
+                       </result>
+               </action>
+
+               <!-- Display of knowledge elements
+               -->
+               <action name="open-knowledge" class="displayKnowledgeAction"
+                       method="open">
+                       <result name="success" type="tiles">
+                               page.displayknowledge
+                       </result>
+               </action>
+               <action name="step-knowledge" class="displayKnowledgeAction"
+                       method="selectStep">
+                       <result name="success" type="tiles">
+                               page.displayknowledge
+                       </result>
+               </action>
+               <action name="document-knowledge" class="displayKnowledgeAction"
+                       method="selectDocument">
+                       <result name="success" type="tiles">
+                               page.displayknowledge
+                       </result>
+               </action>
+               <action name="knowledge-knowledge"
+                       class="displayKnowledgeAction" method="selectKnowledge">
+                       <result name="success" type="tiles">
+                               page.displayknowledge
+                       </result>
+               </action>
+               <action name="close-knowledge" class="displayKnowledgeAction"
+                       method="close">
+                       <result name="success" type="tiles">page.home</result>
+               </action>
+
+               <!-- Edition of study
+               -->
+               <action name="edit-study" class="editStudyAction"
+                       method="edition">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="add-scenario" class="newScenarioAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.newscenario
+                       </result>
+               </action>
+               <action name="edit-title" class="studyPropertiesAction"
+                       method="editTitle">
+                       <result name="success" type="tiles">
+                               page.editstudyproperties
+                       </result>
+               </action>
+               <action name="edit-contributor" class="studyPropertiesAction"
+                       method="editContributors">
+                       <result name="success" type="tiles">
+                               page.editstudyproperties
+                       </result>
+               </action>
+               <action name="edit-cycle" class="studyPropertiesAction"
+                       method="editCycle">
+                       <result name="success" type="tiles">
+                               page.editstudyproperties
+                       </result>
+               </action>
+               <action name="select-step" class="newScenarioAction"
+                       method="selectStep">
+                       <result name="success" type="tiles">
+                               page.newscenario
+                       </result>
+               </action>
+               <action name="valid-add" class="newScenarioAction"
+                       method="create">
+                       <result name="cancel" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="success" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+               <action name="valid-edit" class="studyPropertiesAction"
+                       method="edition">
+                       <result name="success" type="tiles">
+                               page.editstudyproperties
+                       </result>
+               </action>
+               <action name="prop-scenario"
+                       class="editScenarioPropertiesAction" method="initialize">
+                       <result name="success" type="tiles">
+                               page.editscenarioproperties
+                       </result>
+               </action>
+
+               <!-- Edition of scenario
+               -->
+               <action name="checkin-scenario"
+                       class="editScenarioPropertiesAction" method="checkin">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+
+               <!-- Edition of simulation contexts
+               -->
+               <action name="add-context" class="editSimulationContextAction"
+                       method="initialize">
+                       <result name="create" type="tiles">page.newcontext</result>
+                       <result name="select" type="tiles">
+                               page.selectcontext
+                       </result>
+               </action>
+               <action name="selectContext" class="editSimulationContextAction"
+                       method="selectContext">
+                       <result name="create" type="tiles">page.newcontext</result>
+                       <result name="set" type="tiles">page.setcontext</result>
+               </action>
+               <action name="newContext" class="editSimulationContextAction"
+                       method="createContext">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+                       <result name="input" type="tiles">page.newcontext</result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+               <action name="setContext" class="editSimulationContextAction"
+                       method="setContext">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+                       <result name="input" type="tiles">page.setcontext</result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+               <action name="remove-context"
+                       class="editSimulationContextAction" method="deleteContext">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+
+               <!-- Edition of documents
+               -->
+               <action name="select-file" class="uploadAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.uploadstudy
+                       </result>
+               </action>
+               <action name="upload" class="uploadAction" method="upload">
+                       <result name="cancel" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="import" type="redirectAction">
+                               import-document?fileName=%{fileName}
+                       </result>
+                       <result name="version" type="redirectAction">
+                               version-document?index=%{index}&amp;fileName=%{fileName}
+                       </result>
+                       <result name="attach" type="redirectAction">
+                               attach-document?index=%{index}&amp;fileName=%{fileName}
+                       </result>
+                       <result name="outofmemory" type="tiles">
+                               page.error.study
+                       </result>
+               </action>
+               <action name="import-document" class="importDocumentAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.importdocument
+                       </result>
+                       <result name="error" type="tiles">page.importerror</result>
+               </action>
+               <action name="valid-import" class="importDocumentAction"
+                       method="import">
+                       <result name="success" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="cancel" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="error" type="tiles">page.importerror</result>
+               </action>
+               <action name="version-document" class="versionDocumentAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.versiondocument
+                       </result>
+                       <result name="error" type="tiles">page.importerror</result>
+               </action>
+               <action name="valid-version" class="versionDocumentAction"
+                       method="version">
+                       <result name="success" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="cancel" type="redirectAction">
+                               step-study
+                       </result>
+                       <result name="error" type="tiles">page.importerror</result>
+               </action>
+               <action name="attach-document" class="editDocumentAction"
+                       method="attach">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="edit-document" class="editDocumentAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="setDocument" class="editDocumentAction"
+                       method="setDocument">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="remove-document" class="editDocumentAction"
+                       method="deleteDocument">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+
+               <!-- Edition of knowledge elements
+               -->
+               <action name="add-knowledge" class="editKnowledgeElementAction"
+                       method="initialize">
+                       <!--             <result name="success">/study/displayStudy.jsp?action=addKnowledge&amp;index=%{knowledgeType}</result>-->
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="edit-knowledge" class="editKnowledgeElementAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="setKnowledge" class="editKnowledgeElementAction"
+                       method="setKnowledge">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="remove-knowledge"
+                       class="editKnowledgeElementAction" method="deleteKnowledge">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+                       <result name="error" type="tiles">page.displaystudy</result>
+               </action>
+               <action name="promote-knowledge"
+                       class="editKnowledgeElementAction" method="promoteKnowledge">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+               <action name="demote-knowledge"
+                       class="editKnowledgeElementAction" method="demoteKnowledge">
+                       <result name="success" type="tiles">
+                               page.displaystudy
+                       </result>
+               </action>
+
+       </package>
+
+
+       <package name="sadmin" namespace="/sadmin"
+               extends="simer-default">
+
+               <result-types>
+                       <result-type name="tiles"
+                               class="org.apache.struts2.views.tiles.TilesResult" />
+               </result-types>
+
+               <!-- Menus of database administration
+               -->
+               <action name="indexing" class="databaseIndexingAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.indexstudies
+                       </result>
+               </action>
+               <action name="valid-indexing" class="databaseIndexingAction"
+                       method="indexing">
+                       <result name="success" type="redirectAction">
+                               ../study/search-study
+                       </result>
+               </action>
+               <action name="select-file" class="uploadAction"
+                       method="initialize">
+                       <result name="success" type="tiles">
+                               page.uploadsadmin
+                       </result>
+               </action>
+               <action name="upload" class="uploadAction" method="upload">
+                       <result name="cancel" type="tiles">page.home</result>
+                       <result name="importuser" type="redirectAction">
+                               importuser?fileName=%{fileName}
+                       </result>
+               </action>
+               <action name="importuser" class="importUserAction"
+                       method="import">
+                       <result name="success" type="tiles">
+                               page.displayuser
+                       </result>
+               </action>
+
+               <!-- Menus of knowledge administration
+               -->
+               <action name="scontext" class="simulationContextAction"
+                       method="initialize">
+                       <result name="success">/sadmin/approveSContext.jsp</result>
+               </action>
+               <action name="scontext-edit" class="simulationContextAction"
+                       method="select">
+                       <result name="success">/sadmin/approveSContext.jsp</result>
+               </action>
+               <action name="knowelm" class="knowledgeElementAction"
+                       method="initialize">
+                       <result name="success">/sadmin/approveKnowelm.jsp</result>
+               </action>
+       </package>
+
+       <package name="sgeom" namespace="/sgeom" extends="simer-default">
+
+               <action name="valid-save" class="saveDocumentAction"
+                       method="save">
+                       <result name="success">/sgeom/index.jsp</result>
+               </action>
+               <action name="valid-update" class="saveDocumentAction"
+                       method="update">
+                       <result name="success">/sgeom/index.jsp</result>
+               </action>
+               <action name="valid-version" class="saveDocumentAction"
+                       method="version">
+                       <result name="success">/sgeom/index.jsp</result>
+               </action>
+
+       </package>
+
+
+       <package name="smesh" namespace="/smesh" extends="simer-default">
+
+               <action name="valid-save" class="saveDocumentAction"
+                       method="save">
+                       <result name="success">/smesh/index.jsp</result>
+               </action>
+               <action name="valid-update" class="saveDocumentAction"
+                       method="update">
+                       <result name="success">/smesh/index.jsp</result>
+               </action>
+               <action name="valid-version" class="saveDocumentAction"
+                       method="version">
+                       <result name="success">/smesh/index.jsp</result>
+               </action>
+
+       </package>
 </struts>
\ No newline at end of file