From cdee843ecc21f9f9c544f2e49563d35b3dfc2c7c Mon Sep 17 00:00:00 2001 From: rkv Date: Tue, 27 Nov 2012 10:57:20 +0000 Subject: [PATCH] Uses relations for new documents are created during checkin. Unit test is improved to check that. --- .../org/splat/dal/bo/som/ProjectElement.java | 279 ++++++++++-------- .../splat/service/ScenarioServiceImpl.java | 18 +- .../splat/service/TestScenarioService.java | 154 ++++++++-- 3 files changed, 299 insertions(+), 152 deletions(-) diff --git a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java index 71c5402..97511b3 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java +++ b/Workspace/Siman-Common/src/org/splat/dal/bo/som/ProjectElement.java @@ -1,4 +1,5 @@ package org.splat.dal.bo.som; + /** * * @author Daniel Brunier-Coulin @@ -21,164 +22,184 @@ import org.splat.kernel.MultiplyDefinedException; import org.splat.kernel.ObjectProperties; import org.splat.som.Step; - public abstract class ProjectElement extends Entity { -// Persistent fields - protected String title; - protected User manager; - protected Date credate; // Object creation date - protected Date lasdate; // Object Last modification date - private final List contex = new Vector(); // Structured by the Step transient class - private final Set docums = new LinkedHashSet(); // Structured by the Step transient class + // Persistent fields + protected String title; + protected User manager; + protected Date credate; // Object creation date + protected Date lasdate; // Object Last modification date + private final List contex = new Vector(); // Structured by the Step transient class + private final Set docums = new LinkedHashSet(); // Structured by the Step transient class - /** - * Transient array of steps (folders). - */ - private Step[] folders; + /** + * Transient array of steps (folders). + */ + private Step[] folders; - /** + /** * Set the transient array of steps (folders). - * @param folders the steps to set + * + * @param folders + * the steps to set */ public void setFolders(final Step[] folders) { this.folders = folders; } + /** * Get the transient array of steps (folders). + * * @return the array of steps */ public Step[] getFolders() { return folders; } -// ============================================================================================================================== -// Constructors -// ============================================================================================================================== - - /** - * Database fetch constructor. - */ - protected ProjectElement () { - super(); - folders = null; - } - /** - * Initialization constructor. - * @param oprop - * @throws MissedPropertyException - * @throws InvalidPropertyException - * @throws MultiplyDefinedException - */ - protected ProjectElement (final ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException { - super(oprop); // Throws one of the above exception if not valid - title = null; // Initialized by subclasses - credate = null; // Initialized by subclasses - lasdate = null; // Initialized by subclasses -//RKV docums = new LinkedHashSet(); -//RKV contex = new Vector(); - - folders = null; - } - -// ============================================================================================================================== -// Public member functions -// ============================================================================================================================== - - public User getAuthor () { - return manager; - } + // ============================================================================================================================== + // Constructors + // ============================================================================================================================== -/** - * Returns the creation date of this Project Element. - */ - public Date getDate () { - return credate; - } - - public String getDescription () { - String summary = null; - DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class); - if (field != null) { - summary = field.getValue(); - } - return summary; // May be null - } - - public Date getLastModificationDate () { - return lasdate; - } - - public void setLastModificationDate (final Date aDate) { - lasdate = aDate; - } - - /** - * Returns the publication into this Project Element of the given document version, if exists. - * If exists, a document publication id unique in a given ProjectElement. - * - * @param doc a document version published into this Project Element - * @return the publication of the document version, or null if the given document version is not published into this Project Element - */ - public Publication getPublication (final Document doc) { - long index = doc.getIndex(); - for (Iterator i=docums.iterator(); i.hasNext(); ) { - Publication found = i.next(); - if (found.value().getIndex() == index) { - return found; // A document publication is unique in a given ProjectElement + /** + * Database fetch constructor. + */ + protected ProjectElement() { + super(); + folders = null; + } + + /** + * Initialization constructor. + * + * @param oprop + * @throws MissedPropertyException + * @throws InvalidPropertyException + * @throws MultiplyDefinedException + */ + protected ProjectElement(final ObjectProperties oprop) + throws MissedPropertyException, InvalidPropertyException, + MultiplyDefinedException { + super(oprop); // Throws one of the above exception if not valid + title = null; // Initialized by subclasses + credate = null; // Initialized by subclasses + lasdate = null; // Initialized by subclasses + // RKV docums = new LinkedHashSet(); + // RKV contex = new Vector(); + + folders = null; + } + + // ============================================================================================================================== + // Public member functions + // ============================================================================================================================== + + public User getAuthor() { + return manager; + } + + /** + * Returns the creation date of this Project Element. + */ + public Date getDate() { + return credate; + } + + public String getDescription() { + String summary = null; + DescriptionAttribute field = (DescriptionAttribute) this + .getAttribute(DescriptionAttribute.class); + if (field != null) { + summary = field.getValue(); } - } - return null; - } - - public String getTitle () { - return title; - } - - public void setTitle (final String aTitle) { - title = aTitle; - } - - public boolean publishes (final Document doc) { - long index = doc.getIndex(); - for (Iterator i=docums.iterator(); i.hasNext(); ) { - Document found = i.next().value(); - if (found.getIndex() == index) { - return true; + return summary; // May be null + } + + public Date getLastModificationDate() { + return lasdate; + } + + public void setLastModificationDate(final Date aDate) { + lasdate = aDate; + } + + /** + * Returns the publication into this Project Element of the given document version, if exists. If exists, a document publication id + * unique in a given ProjectElement. + * + * @param doc + * a document version published into this Project Element + * @return the publication of the document version, or null if the given document version is not published into this Project Element + */ + public Publication getPublication(final Document doc) { + long index = doc.getIndex(); + for (Iterator i = docums.iterator(); i.hasNext();) { + Publication found = i.next(); + if (found.value().getIndex() == index) { + return found; // A document publication is unique in a given ProjectElement + } } - } - return false; - } + return null; + } - public Iterator PublicationIterator () { - return Collections.unmodifiableSet(docums).iterator(); - } + public String getTitle() { + return title; + } - public Iterator SimulationContextIterator () { - return Collections.unmodifiableList(contex).iterator(); - } + public void setTitle(final String aTitle) { + title = aTitle; + } -// ============================================================================================================================== -// Protected member functions -// ============================================================================================================================== + /** + * Check if the given document is published in the scenario. + * + * @param doc + * the document + * @return true if the document is published in the scenario + */ + public boolean publishes(final Document doc) { + boolean res = false; + long index = doc.getIndex(); + for (Iterator i = docums.iterator(); i.hasNext();) { + Document found = i.next().value(); + res = (found.getIndex() == index); + if (res) { + break; + } + } + return res; + } + + public Iterator PublicationIterator() { + return Collections.unmodifiableSet(docums).iterator(); + } + + public Iterator SimulationContextIterator() { + return Collections.unmodifiableList(contex).iterator(); + } - public boolean add (final Publication newdoc) { - return docums.add(newdoc); - } + // ============================================================================================================================== + // Protected member functions + // ============================================================================================================================== - public boolean add (final SimulationContext newdoc) { - return contex.add(newdoc); - } + public boolean add(final Publication newdoc) { + return docums.add(newdoc); + } + + public boolean add(final SimulationContext newdoc) { + return contex.add(newdoc); + } - public boolean remove (final Publication oldoc) { - return docums.remove(oldoc); // The removed tag becoming orphan, it is supposed automatically deleted from the data store - } + public boolean remove(final Publication oldoc) { + return docums.remove(oldoc); // The removed tag becoming orphan, it is supposed automatically deleted from the data store + } + + public boolean remove(final SimulationContext oldoc) { + return contex.remove(oldoc); + } - public boolean remove (final SimulationContext oldoc) { - return contex.remove(oldoc); - } /** * Get the docums. + * * @return the docums */ public Set getDocums() { diff --git a/Workspace/Siman-Common/src/org/splat/service/ScenarioServiceImpl.java b/Workspace/Siman-Common/src/org/splat/service/ScenarioServiceImpl.java index 470504c..659d5bd 100644 --- a/Workspace/Siman-Common/src/org/splat/service/ScenarioServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/ScenarioServiceImpl.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.splat.common.properties.MessageKeyEnum; import org.splat.dal.bo.kernel.Relation; @@ -536,13 +537,20 @@ public class ScenarioServiceImpl implements ScenarioService { // For each new document create uses relation to the last versions of // results of the previous step. - for (Publication newDoc : newDocs) { + for (Publication newPub : newDocs) { // Find used document type according to the configuration. + Set usedTypes = newPub.value().getType() + .getDefaultUses(); // Find documents of used type in the previous study step. - - // Create uses relation from the new document - // to the found document in the previous step. - // newDoc.addDependency(to); + for (Publication pub : aScenario.getDocums()) { + if ((pub.getStep().getNumber() <= newPub.getStep().getNumber()) + && (!pub.isOutdated()) + && usedTypes.contains(pub.value().getType())) { + // Create uses relation from the new document + // to the found document in the previous step. + newPub.addDependency(pub); + } + } } // Mark the scenario as checked in diff --git a/Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java b/Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java index 39d000f..f455c4e 100644 --- a/Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java +++ b/Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java @@ -15,15 +15,20 @@ import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; +import org.splat.dal.bo.kernel.Relation; import org.splat.dal.bo.kernel.User; import org.splat.dal.bo.som.Document; -import org.splat.dal.bo.som.Document.Properties; import org.splat.dal.bo.som.DocumentType; 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.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; @@ -40,8 +45,8 @@ import org.splat.service.dto.DocumentDTO; import org.splat.service.dto.FileDTO; import org.splat.service.dto.StepDTO; import org.splat.service.technical.ProjectSettingsService; -import org.splat.service.technical.ProjectSettingsService.Step; 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; @@ -303,7 +308,7 @@ public class TestScenarioService extends BaseTest { * @throws MismatchException * if checkin failed */ - @Test(groups = {"checkin", "sevice", "functional", "business"}) + @Test(groups = { "checkin", "sevice", "functional", "business" }) public void testCheckin() throws InvalidPropertyException, MissedPropertyException, MultiplyDefinedException, IOException, SQLException, MismatchException, NotApplicableException { @@ -364,21 +369,33 @@ public class TestScenarioService extends BaseTest { + ") is not found in the scenario."); // Check that presentation of the previous version is removed Assert.assertFalse(aScen.publishes(prevDoc)); - // Check that files are moved correctly - for (int j = 0; j < docDTO.getFiles().size(); j++) { - FileDTO fileDTO = docDTO.getFiles().get(j); - Assert - .assertFalse( - new File(fileDTO.getPath()).exists(), - "File" - + fileDTO.getPath() - + " was not removed from downloads directory."); - String format = fileDTO.getPath().substring( - fileDTO.getPath().lastIndexOf('.') + 1); - } - // Check file by its internal content + checkFiles(docDTO, newPub); // Check that uses relations are copied correctly + // 1. Get all uses relations of the previous document version + for (Relation rel : prevDoc + .getRelations(UsesRelation.class)) { + Document used = ((UsesRelation) rel).getTo(); + // 2.1. Get the latest version of the document published in this scenario + Publication toBeUsed = aScen.getPublication(used); + if (toBeUsed == null) { + // Find the latest published version + for (Publication lastPub : aScen.getDocums()) { + if ((lastPub.value().getPreviousVersion() != null) + && (lastPub.value() + .getPreviousVersion() + .getIndex() == used.getIndex())) { + toBeUsed = lastPub; + break; + } + } + } + if ((toBeUsed != null) && (!toBeUsed.isOutdated())) { + // 2.2. For each used document check that its latest not outdated version + // is used by the new checked in document version. + checkUsesRelation(newPub, toBeUsed); + } + } } else { // Check that new documents are created for new data boolean found = false; @@ -397,8 +414,23 @@ public class TestScenarioService extends BaseTest { "New document is not created for checked in document \"" + docDTO.getTitle() + "\"."); // Check that uses relations are created correctly - // Check that files are moved correctly + // 1. Find the document type used by this document type + Set usedTypes = newPub.value().getType() + .getDefaultUses(); + // 2. Find documents of used types in the current study step and previous study steps + for (Publication pub : aScen.getDocums()) { + if ((pub.getStep().getNumber() <= step.getNumber()) + && (!pub.isOutdated()) + && usedTypes.contains(pub.value().getType())) { + // 3. Check that there is uses relation to the found document + // if it is not outdated. + checkUsesRelation(newPub, pub); + } + } + + // Check that files are moved correctly + checkFiles(docDTO, newPub); } } } @@ -417,6 +449,58 @@ public class TestScenarioService extends BaseTest { LOG.debug(">>>>> END testCheckin()"); } + /** + * Check if there is uses relation from the newPub to pub. + * + * @param newPub + * the new publication + * @param pub + * the publication to be used + */ + private void checkUsesRelation(final Publication newPub, + final Publication pub) { + boolean uses = false; + boolean usesExist = false; + for (Publication usesPub : newPub.getRelations(UsesRelation.class)) { + usesExist = true; + uses = (usesPub.equals(pub)); + if (uses) { + break; + } + } + Assert.assertTrue(usesExist && uses, "The created document " + + newPub.value().getTitle() + "(" + + newPub.value().getType().getName() + ")" + + " has no uses relation to the document " + + pub.value().getTitle() + "(" + + pub.value().getType().getName() + ")"); + } + + /** + * Check that files are moved correctly. + * + * @param docDTO + * checked in document DTO + * @param newPub + * the created document publication + */ + private void checkFiles(final DocumentDTO docDTO, final Publication newPub) { + // Check that original files are deleted + for (int j = 0; j < docDTO.getFiles().size(); j++) { + FileDTO fileDTO = docDTO.getFiles().get(j); + Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File" + + fileDTO.getPath() + + " was not removed from downloads directory."); + String format = fileDTO.getPath().substring( + fileDTO.getPath().lastIndexOf('.') + 1); + } + // TODO:Check file by its internal content + Assert.assertTrue(newPub.getSourceFile().exists(), "File " + + newPub.getSourceFile().asFile().getAbsolutePath() + + " for the document " + docDTO.getTitle() + + " was not created."); + } + /** * Prepare a document with a file for check-in. * @@ -573,6 +657,8 @@ public class TestScenarioService extends BaseTest { Document.Properties dprop = new Document.Properties().setAuthor( anAuthor).setDate(new Date()); int i = 0; + Publication usedPub = null; + Map usedMap = new HashMap(); for (Step step : steps) { LOG.debug("Create scenario step: " + i); @@ -590,7 +676,15 @@ public class TestScenarioService extends BaseTest { } else { dprop.setFormat("brep"); } - createDoc(aScenario, aScStep, dprop, "med", false); + Publication pub = createDoc(aScenario, aScStep, dprop, "med", + false); + if (usedPub != null) { + pub.addDependency(usedPub); + ht.saveOrUpdate(pub.value()); + + usedMap.put(pub.getIndex(), usedPub.getIndex()); + } + usedPub = pub; // Create another document with outdated publication dprop.setName("document" + i++).setType(dtype) @@ -636,6 +730,30 @@ public class TestScenarioService extends BaseTest { 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; + } + } + 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(); } -- 2.39.2