From: rkv Date: Fri, 21 Dec 2012 09:01:38 +0000 (+0000) Subject: Fix: document removing is fixed. Unit tests for StudyDAO and StepService.removeDocume... X-Git-Tag: Root_Delivery2_2013_04_22~196 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=146cac3b56c2f851a5ddb9bbbb8e730844703cb4;p=tools%2Fsiman.git Fix: document removing is fixed. Unit tests for StudyDAO and StepService.removeDocument() are created. --- diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java index c66a7ce..bb8f0d4 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Entity.java @@ -1,4 +1,5 @@ package org.splat.dal.bo.kernel; + /** * Abstract root class of persistent objects supporting relations to other persistent objects.
* Relations are instances of concrete subclasses of Relation that are assigned to Entity objects at run time.
@@ -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 relations = new HashSet(); - -// ============================================================================================================================== -// 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 type) { -// ----------------------------------------------------------------- - for (Iterator 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 relations = new HashSet(); // 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 type) { + Relation found = null; + for (Relation link : relations) { + if (link.getClass().equals(type)) { + found = link; + } } - } - return null; - } - - public List getRelations (final Class type) { - List result = new Vector(); - - for (Iterator 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 getRelations(final Class type) { + List result = new ArrayList(); + + for (Relation link : relations) { + if (link.getClass().equals(type)) { + result.add(link); + } } - } - return result; - } - -// ============================================================================================================================== -// Protected services -// ============================================================================================================================== - - public Set 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 type, final Persistent to) { - for (Iterator 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 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 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 diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.hbm.xml index a4a9ef9..bd34d98 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Persistent.hbm.xml @@ -16,5 +16,10 @@ 1000 + \ No newline at end of file diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.hbm.xml index 2ffa7f5..b8a52df 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.hbm.xml @@ -15,5 +15,8 @@ + \ No newline at end of file diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.java index 1ee3833..c5bc21e 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/kernel/Relation.java @@ -1,10 +1,10 @@ package org.splat.dal.bo.kernel; + + /** - * Base implementation of relations between entities.
- * 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.
- * This Relation base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses - * by: + * Base implementation of relations between entities.
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.
This Relation + * base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses by: *
    *
  • overriding the isBidirectional() and getReverseClass() methods,
  • *
  • creating the reverse relation in constructors.
  • @@ -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 type = this.getReverseClass(); - Entity to = (Entity)this.getTo(); // Bidirectional relations are necessarily between Entities - - for (Iterator 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 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 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 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 diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ActorRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ActorRelation.java index 98fdf8a..8d46394 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ActorRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ActorRelation.java @@ -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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ConvertsRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ConvertsRelation.java index 1e79f75..b23f650 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ConvertsRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ConvertsRelation.java @@ -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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/DocumentType.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/DocumentType.java index 4e285ec..d86176c 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/DocumentType.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/DocumentType.java @@ -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 diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml index d5e6f08..c5a26d5 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Publication.hbm.xml @@ -13,7 +13,7 @@ - + diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml index 6ec782e..5dd0fb7 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Relations.hbm.xml @@ -13,45 +13,45 @@ - + - + - + - + - + - + - + \ No newline at end of file diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.hbm.xml index efad6f2..fb54359 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Scenario.hbm.xml @@ -11,7 +11,7 @@ - + diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/StampRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/StampRelation.java index ef4cb1b..2b6162d 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/StampRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/StampRelation.java @@ -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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml index 1707b8e..43d7a93 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/Study.hbm.xml @@ -31,7 +31,7 @@ - + diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsedByRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsedByRelation.java index b5dedd1..5602fc9 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsedByRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsedByRelation.java @@ -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 getReverseClass () { + @Override + public Class 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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsesRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsesRelation.java index e153992..2a71351 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsesRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/UsesRelation.java @@ -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 getReverseClass () { + @Override + public Class 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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycleRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycleRelation.java index e3c4f15..007833d 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycleRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ValidationCycleRelation.java @@ -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; } diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/VersionsRelation.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/VersionsRelation.java index c4e92cf..b906cdf 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/VersionsRelation.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/VersionsRelation.java @@ -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; } diff --git a/Workspace/Siman-Common/src/org/splat/service/StepService.java b/Workspace/Siman-Common/src/org/splat/service/StepService.java index bc93b46..95c1ccf 100644 --- a/Workspace/Siman-Common/src/org/splat/service/StepService.java +++ b/Workspace/Siman-Common/src/org/splat/service/StepService.java @@ -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). diff --git a/Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java b/Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java index 4aae91f..c0e9e1f 100644 --- a/Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java @@ -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 links = value.getAllRelations(); // Get all relation of the document to remove them List using = new ArrayList(); - for (Iterator i = links.iterator(); i.hasNext();) { - Relation link = i.next(); + List converts = new ArrayList(); + 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 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; + } } diff --git a/Workspace/Siman-Common/src/spring/businessServiceContext.xml b/Workspace/Siman-Common/src/spring/businessServiceContext.xml index 201c9e5..e8cbab3 100644 --- a/Workspace/Siman-Common/src/spring/businessServiceContext.xml +++ b/Workspace/Siman-Common/src/spring/businessServiceContext.xml @@ -107,8 +107,10 @@ http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - - + + + + Roman Kozlov (RKV) + * + */ +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.
    + * Description :
    + * Create a study.
    + * Action :
    + * 1. call DAO's create method for a good transient study.
    + * 2. call DAO's create method for a study with non-zero id.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • Object is created in the database successfully
      + *
    • + *
    • Another new object is created with new generated id
      + *
    • + *
    + *
    + * + * @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 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.
    + * Description :
    + * Create a study and try to get it from the database.
    + * Action :
    + * 1. call DAO's read method for an existing id.
    + * 2. call DAO's read method for a not existing id.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • Object is found in the database successfully
      + *
    • + *
    • Result of search is null
      + *
    • + *
    + *
    + * + * @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.
    + * Description :
    + * Create a study and try to update it with another data.
    + * Action :
    + * 1. call DAO's update method for an existing id.
    + * 2. call DAO's update method for a not existing id.
    + * 3. call DAO's update method for wrong data.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • Object is update in the database successfully
      + *
    • + *
    • Exception is thrown
      + *
    • + *
    • Exception is thrown
      + *
    • + *
    + *
    + * + * @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.
    + * Description :
    + * Create a study and try to delete it.
    + * Action :
    + * 1. call DAO's delete method for an existing id.
    + * 2. call DAO's delete method for a not existing id.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • Object is found in the database successfully
      + *
    • + *
    • Exception is thrown
      + *
    • + *
    + *
    + * + * @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.
    + * Description :
    + * Create two studys and try to get them from the database.
    + * Action :
    + * 1. Find objects with the given value of the property of a child object.
    + * 2. Get ordered list of objects with the given value of the property of a child object.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • Objects are found in the database successfully
      + *
    • + *
    • Objects are found in the database and sorted in the right order
      + *
    • + *
    + *
    + * + * @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 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 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 usedMap = new HashMap(); + 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 dtypes = _documentTypeService + .selectTypesOf(step); + if (dtypes.size() > 0) { + DocumentType dtype = dtypes.get(0); + // Create a document published in the scenario + // document: document type[0] - first type used on the step + // .brep + // .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) 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.
    + * document:
    + * document type - type used on the step
    + * <source-file>.brep
    + * <attached-file>.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: document type - type used on the step + // .brep + // .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 index 0000000..dd9b728 --- /dev/null +++ b/Workspace/Siman-Common/src/test/splat/service/TestStepService.java @@ -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 Roman Kozlov (RKV) + * + */ +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.
    + * Description :
    + * Create a scenario and try to check-in it with some simulated SALOME results data.
    + * After check-in verify following points: + *
      + *
    • scenario is no more marked as checked out
    • + *
    • new document versions are created for checked in documents
    • + *
    • presentation of the previous version is removed
    • + *
    • uses relations are copied correctly
    • + *
    • files are moved correctly
    • + *
    • formats of files are new if they are according to the document's type on the study step
    • + *
    • new documents are created for new data
    • + *
    • new documents have correctly generated names
    • + *
    • uses relations are created correctly
    • + *
    • files are moved correctly
    • + *
    + *

    + * Action :
    + * 1. call the method for an existing scenario id.
    + * 2. call the method for a not existing scenario id.
    + * Test data :
    + * no input parameters
    + * no input parameters
    + * + * Outcome results:
    + * + *
      + *
    • New version of existing documents must be created and new documents must be imported for documents with zero id. Correct + * relations must be created.
      + *
    • + *
    • Exception is thrown
      + *
    • + *
    + *
    + * + * @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 uses = ht + .find("from UsesRelation where owner=" + docId); + List 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 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 usedMap = new HashMap(); + 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 dtypes = _documentTypeService + .selectTypesOf(step); + if (dtypes.size() > 0) { + DocumentType dtype = dtypes.get(0); + // Create a document published in the scenario + // document: document type[0] - first type used on the step + // .brep + // .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) 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.
    + * document:
    + * document type - type used on the step
    + * <source-file>.brep
    + * <attached-file>.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: document type - type used on the step + // .brep + // .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 index 0000000..bafa7e3 --- /dev/null +++ b/Workspace/Siman-Common/testng-stepService.xml @@ -0,0 +1,8 @@ + + + + + + + + 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 index 0000000..7edffda Binary files /dev/null and b/Workspace/Siman/WebContent/WEB-INF/lib/jsonplugin-0.34.jar differ diff --git a/Workspace/Siman/WebContent/jap/splat-launcher.jar b/Workspace/Siman/WebContent/jap/splat-launcher.jar index 8bb900a..fe41638 100644 Binary files a/Workspace/Siman/WebContent/jap/splat-launcher.jar and b/Workspace/Siman/WebContent/jap/splat-launcher.jar differ diff --git a/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar b/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar index f2a64e4..b35d41a 100644 Binary files a/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar and b/Workspace/Siman/WebContent/jap/splat-signedlauncher.jar differ diff --git a/Workspace/Siman/WebContent/jsp/menuitem.jsp b/Workspace/Siman/WebContent/jsp/menuitem.jsp index 5d01a89..aa0f527 100644 --- a/Workspace/Siman/WebContent/jsp/menuitem.jsp +++ b/Workspace/Siman/WebContent/jsp/menuitem.jsp @@ -25,6 +25,9 @@ Action anAction = (Action)ActionContext.getContext().getActionInvocation().getAction(); Menu menu = anAction.getLeftMenuSettings().getMenu(); boolean submenu = false; +%> + +<% for (Iterator listem = menu.asList().iterator(); listem.hasNext(); ) { MenuItem item = listem.next(); String arrow = "image.hold.gif"; @@ -89,4 +92,5 @@ <% } %> + \ No newline at end of file diff --git a/Workspace/Siman/WebContent/layout/homeLayout.jsp b/Workspace/Siman/WebContent/layout/homeLayout.jsp index b35caee..3de62f2 100644 --- a/Workspace/Siman/WebContent/layout/homeLayout.jsp +++ b/Workspace/Siman/WebContent/layout/homeLayout.jsp @@ -32,6 +32,24 @@ - + +

    + +
    \ No newline at end of file diff --git a/Workspace/Siman/WebContent/study/editScenarioProperties.jsp b/Workspace/Siman/WebContent/study/editScenarioProperties.jsp index ff01292..35a2a63 100644 --- a/Workspace/Siman/WebContent/study/editScenarioProperties.jsp +++ b/Workspace/Siman/WebContent/study/editScenarioProperties.jsp @@ -1,11 +1,5 @@ <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags"%> - - - - - rel="stylesheet" type="text/css"> - - - - - @@ -77,6 +67,3 @@ - - - \ No newline at end of file diff --git a/Workspace/Siman/src/hibernate.properties b/Workspace/Siman/src/hibernate.properties index 88cd755..1d1587d 100644 --- a/Workspace/Siman/src/hibernate.properties +++ b/Workspace/Siman/src/hibernate.properties @@ -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 diff --git a/Workspace/Siman/src/jdbc.properties b/Workspace/Siman/src/jdbc.properties index ecfd593..cb7201f 100644 --- a/Workspace/Siman/src/jdbc.properties +++ b/Workspace/Siman/src/jdbc.properties @@ -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 diff --git a/Workspace/Siman/src/org/splat/simer/Action.java b/Workspace/Siman/src/org/splat/simer/Action.java index ff32355..16e0b27 100644 --- a/Workspace/Siman/src/org/splat/simer/Action.java +++ b/Workspace/Siman/src/org/splat/simer/Action.java @@ -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; diff --git a/Workspace/Siman/src/org/splat/simer/ApplicationSettings.java b/Workspace/Siman/src/org/splat/simer/ApplicationSettings.java index cd4e68e..7f9e308 100644 --- a/Workspace/Siman/src/org/splat/simer/ApplicationSettings.java +++ b/Workspace/Siman/src/org/splat/simer/ApplicationSettings.java @@ -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 _tempfile; + private transient static Map 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 _convertmap; + private transient static Map convertmap; static { - synchronized (_wapprops) { + synchronized (_WAPPROPS) { // Do common configuration for all users - _jndprops = new Properties(); - _tempfile = new HashMap(); - _viewermap = new String[0]; - _convertmap = new HashMap(); + _JNDPROPS = new Properties(); + tempfile = new HashMap(); + viewermap = new String[0]; + convertmap = new HashMap(); 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); } } diff --git a/Workspace/Siman/src/org/splat/simer/ConnectionAction.java b/Workspace/Siman/src/org/splat/simer/ConnectionAction.java index 42020b5..4f05316 100644 --- a/Workspace/Siman/src/org/splat/simer/ConnectionAction.java +++ b/Workspace/Siman/src/org/splat/simer/ConnectionAction.java @@ -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) { diff --git a/Workspace/Siman/src/org/splat/simer/Converter.java b/Workspace/Siman/src/org/splat/simer/Converter.java index af2237d..816b40a 100644 --- a/Workspace/Siman/src/org/splat/simer/Converter.java +++ b/Workspace/Siman/src/org/splat/simer/Converter.java @@ -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 diff --git a/Workspace/Siman/src/org/splat/simer/EditDocumentAction.java b/Workspace/Siman/src/org/splat/simer/EditDocumentAction.java index b2197aa..c4260d8 100644 --- a/Workspace/Siman/src/org/splat/simer/EditDocumentAction.java +++ b/Workspace/Siman/src/org/splat/simer/EditDocumentAction.java @@ -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; } // ============================================================================================================================== diff --git a/Workspace/Siman/src/org/splat/simer/EditStudyAction.java b/Workspace/Siman/src/org/splat/simer/EditStudyAction.java index 577b185..bf4804c 100644 --- a/Workspace/Siman/src/org/splat/simer/EditStudyAction.java +++ b/Workspace/Siman/src/org/splat/simer/EditStudyAction.java @@ -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 index 0000000..ce18106 --- /dev/null +++ b/Workspace/Siman/src/org/splat/simer/ExceptionAction.java @@ -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 Roman Kozlov (RKV) + */ +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. + *
      + *
    • log the exception
    • + *
    • display an unexpected error screen. This is configured in the struts config file
    • + *
    + * + * @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 actionSet = new HashSet(); + + 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; + } + +} diff --git a/Workspace/Siman/src/org/splat/simer/StudyPropertiesAction.java b/Workspace/Siman/src/org/splat/simer/StudyPropertiesAction.java index be785bc..3462674 100644 --- a/Workspace/Siman/src/org/splat/simer/StudyPropertiesAction.java +++ b/Workspace/Siman/src/org/splat/simer/StudyPropertiesAction.java @@ -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) { diff --git a/Workspace/Siman/src/spring/applicationContext.xml b/Workspace/Siman/src/spring/applicationContext.xml index 6867411..1225c73 100644 --- a/Workspace/Siman/src/spring/applicationContext.xml +++ b/Workspace/Siman/src/spring/applicationContext.xml @@ -1,6 +1,7 @@ - + - conf/log-messages + conf/log-messages - + + + @@ -53,12 +58,13 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + - + @@ -66,14 +72,17 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + - + - - + + @@ -87,8 +96,8 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> parent="openObject" scope="session"> - + @@ -102,13 +111,16 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + - - + + @@ -118,8 +130,9 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + @@ -128,15 +141,17 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + - + @@ -145,37 +160,46 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> scope="prototype" parent="displayStudyStepAction"> - - + + - + - - + + - + - - - + + + - + @@ -183,37 +207,45 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> scope="prototype" parent="baseAction"> - + - + - + - + - + - - + + - + - - + + - + - + - + - + - - + - + - - + - + diff --git a/Workspace/Siman/src/struts.xml b/Workspace/Siman/src/struts.xml index bc90fe8..d60b1b9 100644 --- a/Workspace/Siman/src/struts.xml +++ b/Workspace/Siman/src/struts.xml @@ -6,359 +6,609 @@ - - - - - - - - - - - - - - - - - - - page.welcome - page.exception - - - page.home - select?menu=search - study/step-study - study/step-knowledge - - page.login - page.home - - - page.home - page.home - select?menu=search - study/step-study - study/step-knowledge - page.home - page.home - - - study/new-empty - study/search-study - study/search-knowledge - study/search-document - study/prop-study - study/prop-scenario - sadmin/indexing - sadmin/select-file?nextAction=importuser - sadmin/scontext - sadmin/knowlelm - - page.home - - - - - - - - - - - - page.error.study - - - - /study/jsonCheckoutRes.jsp - - - - - page.newstudy - - - open-study?selection=0.1 - page.newstudy - page.home - - - - - page.searchstudy - page.home - - - page.searchstudy - page.searchstudy - page.searchstudy - search-study - - - - page.searchknowledge - - - page.searchknowledge - page.searchknowledge - page.searchknowledge - search-knowledge - - - - /study/searchDocument.jsp - - - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - - - page.home - - - page.displaystudyproperties - page.editstudyproperties - - - - - page.displayknowledge - - - page.displayknowledge - - - page.displayknowledge - - - page.displayknowledge - - - page.home - - - - - page.displaystudy - - - page.newscenario - - - page.editstudyproperties - - - page.editstudyproperties - - - page.editstudyproperties - - - page.newscenario - - - step-study - step-study - page.displaystudy - - - page.editstudyproperties - - - page.editscenarioproperties - - - - - page.displaystudy - - - - - page.newcontext - page.selectcontext - - - page.newcontext - page.setcontext - - - page.displaystudy - page.newcontext - page.displaystudy - - - page.displaystudy - page.setcontext - page.displaystudy - - - page.displaystudy - page.displaystudy - - - - - page.uploadstudy - - - step-study - import-document?fileName=%{fileName} - version-document?index=%{index}&fileName=%{fileName} - attach-document?index=%{index}&fileName=%{fileName} - page.error.study - - - page.importdocument - page.importerror - - - step-study - step-study - page.importerror - - - page.versiondocument - page.importerror - - - step-study - step-study - page.importerror - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - page.displaystudy - - - - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - - - page.displaystudy - page.displaystudy - - - page.displaystudy - - - page.displaystudy - - - - - - - - - - - - - - page.indexstudies - - - ../study/search-study - - - page.uploadsadmin - - - page.home - importuser?fileName=%{fileName} - - - page.displayuser - - - - - /sadmin/approveSContext.jsp - - - /sadmin/approveSContext.jsp - - - /sadmin/approveKnowelm.jsp - - - - - - - - - - - /sgeom/index.jsp - - - /sgeom/index.jsp - - - /sgeom/index.jsp - - - - - - - - - - - - - /smesh/index.jsp - - - /smesh/index.jsp - - - /smesh/index.jsp - - - + + + + + + + + + + + + + + + exceptionAction + + + + + + + + + + + + page.home + page.home + + + + + + + + + + + page.welcome + page.exception + + + page.home + + select?menu=search + + + study/step-study + + + study/step-knowledge + + + page.login + page.home + + + page.home + page.home + + select?menu=search + + + study/step-study + + + study/step-knowledge + + page.home + page.home + + + + study/new-empty + + + study/search-study + + + study/search-knowledge + + + study/search-document + + + study/prop-study + + + study/prop-scenario + + + sadmin/indexing + + + sadmin/select-file?nextAction=importuser + + + sadmin/scontext + + + sadmin/knowlelm + + + page.home + + + + + + + + + + + + + page.error.study + + + + + /study/jsonCheckoutRes.jsp + + + + + page.newstudy + + + + open-study?selection=0.1 + + page.newstudy + page.home + + + + + + page.searchstudy + + page.home + + + + page.searchstudy + + + page.searchstudy + + page.searchstudy + + search-study + + + + + + page.searchknowledge + + + + + page.searchknowledge + + + page.searchknowledge + + + page.searchknowledge + + + search-knowledge + + + + + /study/searchDocument.jsp + + + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + + + page.home + + + + page.displaystudyproperties + + + page.editstudyproperties + + + + + + + page.displayknowledge + + + + + page.displayknowledge + + + + + page.displayknowledge + + + + + page.displayknowledge + + + + page.home + + + + + + page.displaystudy + + + + + page.newscenario + + + + + page.editstudyproperties + + + + + page.editstudyproperties + + + + + page.editstudyproperties + + + + + page.newscenario + + + + + step-study + + + step-study + + page.displaystudy + + + + page.editstudyproperties + + + + + page.editscenarioproperties + + + + + + + page.displaystudy + + + + + + page.newcontext + + page.selectcontext + + + + page.newcontext + page.setcontext + + + + page.displaystudy + + page.newcontext + page.displaystudy + + + + page.displaystudy + + page.setcontext + page.displaystudy + + + + page.displaystudy + + page.displaystudy + + + + + + page.uploadstudy + + + + + step-study + + + import-document?fileName=%{fileName} + + + version-document?index=%{index}&fileName=%{fileName} + + + attach-document?index=%{index}&fileName=%{fileName} + + + page.error.study + + + + + page.importdocument + + page.importerror + + + + step-study + + + step-study + + page.importerror + + + + page.versiondocument + + page.importerror + + + + step-study + + + step-study + + page.importerror + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + page.displaystudy + + + + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + + + + page.displaystudy + + page.displaystudy + + + + page.displaystudy + + + + + page.displaystudy + + + + + + + + + + + + + + + + page.indexstudies + + + + + ../study/search-study + + + + + page.uploadsadmin + + + + page.home + + importuser?fileName=%{fileName} + + + + + page.displayuser + + + + + + /sadmin/approveSContext.jsp + + + /sadmin/approveSContext.jsp + + + /sadmin/approveKnowelm.jsp + + + + + + + /sgeom/index.jsp + + + /sgeom/index.jsp + + + /sgeom/index.jsp + + + + + + + + + /smesh/index.jsp + + + /smesh/index.jsp + + + /smesh/index.jsp + + + \ No newline at end of file