Salome HOME
Fix for some problems with definition uses.
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / service / TestPublicationService.java
index ae20269c529c28c3c7faf66e83331ae29cdf57e7..0df8754270c99e69435ebeda3a357f44433a4405 100644 (file)
@@ -8,20 +8,27 @@
  *****************************************************************************/
 package test.splat.service;
 
+import java.io.BufferedReader;
+import java.io.DataInputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.sql.SQLException;
+import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Calendar;
 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.ConvertsRelation;
 import org.splat.dal.bo.som.Document;
 import org.splat.dal.bo.som.DocumentType;
 import org.splat.dal.bo.som.ProgressState;
@@ -30,8 +37,14 @@ import org.splat.dal.bo.som.Publication;
 import org.splat.dal.bo.som.Scenario;
 import org.splat.dal.bo.som.Study;
 import org.splat.dal.bo.som.Document.Properties;
+import org.splat.dal.bo.som.UsedByRelation;
+import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.dao.kernel.UserDAO;
 import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.som.ScenarioDAO;
 import org.splat.dal.dao.som.StudyDAO;
+import org.splat.exception.BusinessException;
+import org.splat.exception.IncompatibleDataException;
 import org.splat.kernel.InvalidPropertyException;
 import org.splat.kernel.MissedPropertyException;
 import org.splat.kernel.MultiplyDefinedException;
@@ -52,6 +65,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import test.splat.common.BaseTest;
+import test.splat.util.TestEntitiesGenerator;
 
 /**
  * Test class for PublicationService.
@@ -123,6 +137,20 @@ public class TestPublicationService extends BaseTest {
        @Qualifier("repositoryService")
        private transient RepositoryService _repositoryService;
 
+       /**
+        * The UserDAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("userDAO")
+       private transient UserDAO _userDAO;
+
+       /**
+        * The Scenario DAO. Later injected by Spring.
+        */
+       @Autowired
+       @Qualifier("scenarioDAO")
+       private transient ScenarioDAO _scenarioDAO;
+
        /**
         * Create a persistent scenario for tests.
         * 
@@ -148,8 +176,7 @@ public class TestPublicationService extends BaseTest {
                _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
                // Load workflow customization
                try {
-                       _projectSettings.configure(ClassLoader.getSystemResource(
-                                       "test/som.xml").getPath());
+                       _projectSettings.configure("classpath:test/som.xml");
                } catch (FileNotFoundException e) {
                        Assert.fail("Can't find som.xml: ", e);
                }
@@ -353,18 +380,137 @@ public class TestPublicationService extends BaseTest {
        }
 
        /**
-        * Test of generating a study document index.<BR>
+     * Test of generating a study document index.<BR>
+     * <B>Description :</B> <BR>
+     * <i>Create a study and try to generate the next document index.</i><BR>
+     * <B>Action : </B><BR>
+     * <i>1. call DAO's read method for an existing id.</i><BR>
+     * <B>Test data : </B><BR>
+     * <i>no input parameters</i><BR>
+     * 
+     * <B>Outcome results:</B><BR>
+     * <i>
+     * <ul>
+     * <li>The new index must be equal to the incremented old one and saved into the database<BR>
+     * </li>
+     * </ul>
+     * </i>
+     * 
+     * @throws InvalidPropertyException
+     *             if an invalid property is used when creating objects
+     * @throws MultiplyDefinedException
+     *             when trying to create an object with already existing id
+     * @throws MissedPropertyException
+     *             if a mandatory property is not defined for an object to be created
+     * @throws SQLException
+     *             if test study creation is failed
+     * @throws IOException
+     *             if test study creation is failed
+     * @throws ParseException
+     * @throws InterruptedException
+     * @throws NotApplicableException
+     * 
+     */
+       @Test
+    public void testCreateDoc() throws InvalidPropertyException,
+            MissedPropertyException, MultiplyDefinedException, IOException,
+            SQLException, NotApplicableException, InterruptedException,
+            ParseException {
+        LOG.debug(">>>>> BEGIN testCreateDoc()");
+        startNestedTransaction();
+
+        HibernateTemplate ht = getHibernateTemplate();
+        Study aStudy = createStudy();
+        // Call DAO's create method for a good transient study.
+        Long id = aStudy.getIndex();
+        Assert.assertNotNull(id,
+                "Create method returns null instead of a new id.");
+        Assert.assertTrue(id > 0, "The new id is not a positive number.");
+
+        // Call DAO's get method for an existing id.
+        _studyDAO.flush();
+        getHibernateTemplate().evict(aStudy);
+        getHibernateTemplate().clear();
+        Study aStudyFound = _studyDAO.get(id);
+        ht.evict(aStudyFound);
+
+        long userId = aStudyFound.getAuthor().getIndex();
+        org.splat.som.Step[] studySteps = _projectElementService
+                .getSteps(aStudyFound);
+        org.splat.som.Step[] scSteps = _projectElementService
+                .getSteps(aStudyFound.getScenarii()[0]);
+
+        List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
+        steps.addAll(Arrays.asList(studySteps));
+        steps.addAll(Arrays.asList(scSteps));
+        steps.addAll(Arrays.asList(studySteps));
+        DecimalFormat tostring = new DecimalFormat(Document.suformat);
+        for (org.splat.som.Step step : steps) {
+            LOG.debug("Create a document for the step " + step.getNumber());
+
+            List<DocumentType> dtypes = _documentTypeService.selectTypesOf(step
+                    .getStep());
+            if (dtypes.size() > 0) {
+                DocumentType dtype = dtypes.get(0);
+                int oldInd = ht.get(Study.class, aStudyFound.getIndex())
+                        .getLastLocalIndex();
+
+                // Create a file in the download directory
+                String fname = "filename" + step.getNumber() + ".py";
+                String filePath = getDownloadPath(aStudyFound.getAuthor())
+                        + fname;
+                LOG.debug(step.getStep().getKey() + ": "
+                        + step.getOwner().getClass().getSimpleName()
+                        + ": Create test file: " + filePath);
+                FileWriter fw = new FileWriter(filePath);
+                fw
+                        .write("Simulation of filename.py file for creating a new document at "
+                                + new Date());
+                fw.close();
+
+                Publication addoc = _publicationService.createDoc(aStudyFound
+                        .getIndex(), step, dtype.getIndex(), userId, fname,
+                        "tstdoc", ProgressState.inWORK, "", "", new Date(),
+                        null);
+
+                _studyDAO.flush();
+                ht.flush();
+
+                int ind = ht.get(Study.class, aStudyFound.getIndex())
+                        .getLastLocalIndex();
+
+                LOG.debug("Previous index: " + oldInd + ", new index: " + ind);
+                Assert.assertEquals(ht.get(Study.class, aStudyFound.getIndex())
+                        .getLastLocalIndex(), oldInd + 1,
+                        "Incremented index must be saved in the database.");
+                aStudy = (Study) ht.find(
+                        "from Study where rid = " + aStudyFound.getIndex())
+                        .get(0);
+                Assert.assertEquals(aStudy.getLastLocalIndex(), oldInd + 1,
+                        "Incremented index must be saved in the database.");
+                Assert.assertEquals(addoc.getSourceFile().getName(), tostring
+                        .format(aStudy.getLastLocalIndex())
+                        + "_" + fname, "The generated file name is incorrect.");
+            }
+        }
+
+        rollbackNestedTransaction();
+        LOG.debug(">>>>> END testCreateDoc()");
+    }
+
+       /**
+        * Test of file attaching to a study document.<BR>
         * <B>Description :</B> <BR>
-        * <i>Create a study and try to generate the next document index.</i><BR>
+        * <i>Create a study and try to attach a new file to its each document.</i><BR>
         * <B>Action : </B><BR>
-        * <i>1. call DAO's read method for an existing id.</i><BR>
+        * <i>1. call attach method for each document publication of the study.</i><BR>
         * <B>Test data : </B><BR>
         * <i>no input parameters</i><BR>
         * 
         * <B>Outcome results:</B><BR>
         * <i>
         * <ul>
-        * <li>The new index must be equal to the incremented old one and saved into the database<BR>
+        * <li>The new ConvertsRelation and the new File object must be created in the database.<BR>
         * </li>
         * </ul>
         * </i>
@@ -385,11 +531,11 @@ public class TestPublicationService extends BaseTest {
         * 
         */
        @Test
-       public void testCreateDoc() throws InvalidPropertyException,
+       public void testAttach() throws InvalidPropertyException,
                        MissedPropertyException, MultiplyDefinedException, IOException,
                        SQLException, NotApplicableException, InterruptedException,
                        ParseException {
-               LOG.debug(">>>>> BEGIN testCreateDoc()");
+               LOG.debug(">>>>> BEGIN testAttach()");
                startNestedTransaction();
 
                HibernateTemplate ht = getHibernateTemplate();
@@ -405,6 +551,7 @@ public class TestPublicationService extends BaseTest {
                getHibernateTemplate().evict(aStudy);
                getHibernateTemplate().clear();
                Study aStudyFound = _studyDAO.get(id);
+               ht.clear();
                ht.evict(aStudyFound);
 
                long userId = aStudyFound.getAuthor().getIndex();
@@ -417,54 +564,56 @@ public class TestPublicationService extends BaseTest {
                steps.addAll(Arrays.asList(studySteps));
                steps.addAll(Arrays.asList(scSteps));
                steps.addAll(Arrays.asList(studySteps));
-               for (org.splat.som.Step step: steps) {
-                       LOG.debug("Create a document for the step " + step.getNumber());
+               for (org.splat.som.Step step : steps) {
+                       LOG.debug("Attach a new .py file to documents of the step "
+                                       + step.getNumber() + ": " + step.getStep().getKey() + ": "
+                                       + step.getOwner().getClass().getSimpleName());
 
-                       List<DocumentType> dtypes = _documentTypeService
-                                       .selectTypesOf(step.getStep());
-                       if (dtypes.size() > 0) {
-                               DocumentType dtype = dtypes.get(0);
-                               int oldInd = ht.get(Study.class, aStudyFound.getIndex())
-                                               .getLastLocalIndex();
-
-                               // Create a file in the download directory
-                               String fname = "filename" + step.getNumber() + ".py";
-                               String filePath = getDownloadPath(aStudyFound.getAuthor())
-                                               + fname;
-                               LOG.debug(step.getStep().getKey() + ": "
-                                               + step.getOwner().getClass().getSimpleName()
-                                               + ": Create test file: " + filePath);
-                               FileWriter fw = new FileWriter(filePath);
-                               fw
-                                               .write("Simulation of filename.py file for creating a new document at "
-                                                               + new Date());
-                               fw.close();
-
-                               Publication addoc = _publicationService.createDoc(aStudyFound
-                                               .getIndex(), step, dtype.getIndex(), userId, fname,
-                                               "tstdoc", ProgressState.inWORK, "", "", new Date(),
-                                               null);
+                       for (Publication pub : step.getAllDocuments()) {
+
+                               ht.evict(step.getOwner());
+                               ht.evict(pub);
+                               ht.evict(pub.value());
+                               int nbConverts = ht.find("from ConvertsRelation").size();
+                               int nbDocConverts = ht.find(
+                                               "from ConvertsRelation where owner="
+                                                               + pub.value().getIndex()).size();
+                               int nbFiles = ht.find("from File").size();
+
+                               ConvertsRelation rel = _publicationService.attach(pub, "py");
 
                                _studyDAO.flush();
                                ht.flush();
-
-                               int ind = ht.get(Study.class, aStudyFound.getIndex())
-                                               .getLastLocalIndex();
-
-                               LOG.debug("Previous index: " + oldInd + ", new index: " + ind);
-                               Assert.assertEquals(ht.get(Study.class, aStudyFound.getIndex())
-                                               .getLastLocalIndex(), oldInd + 1,
-                                               "Incremented index must be saved in the database.");
-                               aStudy = (Study) ht.find(
-                                               "from Study where rid = " + aStudyFound.getIndex())
-                                               .get(0);
-                               Assert.assertEquals(aStudy.getLastLocalIndex(), oldInd + 1,
-                                               "Incremented index must be saved in the database.");
+                               Assert.assertNotNull(rel,
+                                               "Returned ConvertsRelation must not be null.");
+                               Assert
+                                               .assertTrue(rel.isSaved(),
+                                                               "Returned ConvertsRelation must be saved in the database.");
+                               Assert.assertEquals(ht.find(
+                                               "from ConvertsRelation where owner="
+                                                               + pub.value().getIndex()).size(),
+                                               nbDocConverts + 1,
+                                               "Number of created ConvertsRelations must be 1.");
+                               Assert.assertEquals(ht.find("from ConvertsRelation").size(),
+                                               nbConverts + 1,
+                                               "Number of created ConvertsRelations must be 1.");
+                               Assert.assertNotNull(rel.getTo(),
+                                               "Attached File must not be null.");
+                               Assert.assertTrue(rel.isSaved(),
+                                               "Attached File must be saved in the database.");
+                               Assert
+                                               .assertEquals(ht
+                                                               .find(
+                                                                               "from File where rid="
+                                                                                               + rel.getTo().getIndex())
+                                                               .size(), 1, "Number of created File must be 1.");
+                               Assert.assertEquals(ht.find("from File").size(), nbFiles + 1,
+                                               "Number of created Files must be 1.");
                        }
                }
 
                rollbackNestedTransaction();
-               LOG.debug(">>>>> END testCreateDoc()");
+               LOG.debug(">>>>> END testAttach()");
        }
 
        /**
@@ -486,4 +635,379 @@ public class TestPublicationService extends BaseTest {
                return tmpDir.getAbsolutePath() + "/";
        }
 
-}
+       /**
+        * Test testReplace method for a published document.<BR>
+        * <B>Description :</B> <BR>
+        * <i>Create a study and a scenario with documents and try to replace source files.<BR>
+        * </i><BR>
+        * <B>Action : </B><BR>
+        * <i>1. call the method for a document in the status inDRAFT.</i><BR>
+        * <i>2. call the method for a document in the status inCHECK.</i><BR>
+        * <i>3. call the method for a document in the status APPROVED.</i><BR>
+        * <i>4. call the method for an Extern document published in the study step.</i><BR>
+        * <i>5. call the method for an inWork document published in the scenario step.</i><BR>
+        * <B>Test data : </B><BR>
+        * <i>no input parameters</i><BR>
+        * 
+        * <B>Outcome results:</B><BR>
+        * <i>
+        * <ul>
+        * <li>1-3: Exception must be thrown. The document source file content must not be replaced.<BR>
+        * </li>
+        * <li>4: The document source file content in the study must be replaced.<BR>
+        * </li>
+        * <li>5: The document source file content in the scenario must be replaced.<BR>
+        * </li>
+        * </ul>
+        * </i>
+        * 
+        * @throws BusinessException
+        *             if test data creation is failed
+        * @throws IOException
+        *             if application configuration loading or test data creation is failed
+        * @throws SQLException
+        *             if application configuration loading or test data creation is failed
+        */
+       @Test
+       public void testReplace() throws BusinessException, IOException,
+                       SQLException {
+               LOG.debug(">>>>> BEGIN testReplace()");
+               startNestedTransaction();
+
+               HibernateTemplate ht = getHibernateTemplate();
+
+               Database.getInstance().reset();
+               _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
+               _projectSettings.configure("classpath:test/som.xml");
+
+               User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
+               _userDAO.create(goodUser);
+
+               // Create private study
+               Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
+               aStudy.setTitle("0.This is private study");
+               Long studyId = _studyDAO.create(aStudy);
+
+               // Add a scenario to the study
+               Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
+               Long scenId = _scenarioDAO.create(scen);
+               ht.flush();
+
+               DocumentType dtype = _documentTypeService.selectType("minutes");
+
+               // Add documents to the first study activity
+               // Add a converts relations
+               Map<Integer, org.splat.som.Step> stSteps = _projectElementService
+                               .getStepsMap(aStudy);
+               org.splat.som.Step aStep = stSteps.get(1);
+               Publication pub0inDraft = addDoc(aStudy, aStep, "document0indraft",
+                               dtype);
+               pub0inDraft.value().setProgressState(ProgressState.inDRAFT);
+               Publication pub0inCheck = addDoc(aStudy, aStep, "document0incheck",
+                               dtype);
+               pub0inCheck.value().setProgressState(ProgressState.inCHECK);
+               Publication pub0approved = addDoc(aStudy, aStep, "document0approved",
+                               dtype);
+               pub0approved.value().setProgressState(ProgressState.APPROVED);
+               Publication pub1 = addDoc(aStudy, aStep, "document1", dtype);
+               String format1 = pub1.value().getFormat();
+               ht.flush();
+               ht.update(aStudy);
+               ht.flush();
+
+               // Add documents to the first scenario activity
+               scen = aStudy.getScenariiList().get(0);
+               Map<Integer, org.splat.som.Step> scSteps = _projectElementService
+                               .getStepsMap(scen);
+               aStep = scSteps.get(2);
+               Publication spub1 = addDoc(scen, aStep, "sdocument1", dtype);
+               String format2 = spub1.value().getFormat();
+               ht.flush();
+
+               // Remember documents ids
+               Long id0inDraft = pub0inDraft.value().getIndex(), id0inCheck = pub0inCheck
+                               .value().getIndex(), id0approved = pub0approved.value()
+                               .getIndex(), id1 = pub1.value().getIndex(), id2 = spub1.value()
+                               .getIndex();
+
+               ht.evict(scen);
+               ht.evict(scen.getOwnerStudy());
+               ht.clear();
+
+               Assert.assertTrue(ht.find("from File").size() >= 3,
+                               "Files were not created in the database.");
+
+               Date modifTime = Calendar.getInstance().getTime();
+
+               aStudy = _studyService.selectStudy(studyId);
+               File newFile = new File(getDownloadPath(goodUser) + "replaced0.ddd");
+               createFile(newFile.getAbsolutePath());
+
+               // TEST CALL: Try to replace a file for inDraft document
+               Publication pub = getPublicationByDocId(aStudy, id0inDraft);
+               try {
+                       _publicationService.replace(pub, newFile, modifTime);
+                       Assert
+                                       .fail("IncompatibleDataException is expected for a doucment in the status "
+                                                       + pub.getProgressState().name());
+               } catch (IncompatibleDataException e) {
+                       LOG.debug("Expected exception: ", e);
+               }
+               ht.flush();
+               // TEST CALL: Try to replace a file for inCheck document
+               pub = getPublicationByDocId(aStudy, id0inCheck);
+               try {
+                       _publicationService.replace(pub, newFile, modifTime);
+                       Assert
+                                       .fail("IncompatibleDataException is expected for a doucment in the status "
+                                                       + pub.getProgressState().name());
+               } catch (IncompatibleDataException e) {
+                       LOG.debug("Expected exception: ", e);
+               }
+               ht.flush();
+               // TEST CALL: Try to replace a file for Approved document
+               pub = getPublicationByDocId(aStudy, id0approved);
+               try {
+                       _publicationService.replace(pub, newFile, modifTime);
+                       Assert
+                                       .fail("IncompatibleDataException is expected for a doucment in the status "
+                                                       + pub.getProgressState().name());
+               } catch (IncompatibleDataException e) {
+                       LOG.debug("Expected exception: ", e);
+               }
+               ht.flush();
+               newFile.delete();
+
+               // TEST CALL: Replace a file in the study step
+               pub = getPublicationByDocId(aStudy, id1);
+               newFile = new File(getDownloadPath(goodUser) + "replaced1.ddd");
+               createFile(newFile.getAbsolutePath());
+               Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime));
+               ht.flush();
+
+               // TEST CALL: Replace a file in the scenario step
+               scen = aStudy.getScenariiList().get(0);
+               pub = getPublicationByDocId(scen, id2);
+               newFile = new File(getDownloadPath(goodUser) + "replaced2.ddd");
+               createFile(newFile.getAbsolutePath());
+               Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime));
+               ht.flush();
+
+               ht.clear();
+               // Remove milliseconds because they are lost after saving in the database
+               modifTime.setTime((modifTime.getTime() / 1000) * 1000);
+
+               Document doc = ht.get(Document.class, id1);
+               String txt = readFile(doc.getFile().asFile());
+               Assert.assertTrue(doc.getFile().getName().contains("_document1"));
+               Assert.assertEquals(doc.getFile().getFormat(), format1);
+               Assert.assertTrue(txt.contains("replaced1.ddd"));
+               Assert.assertEquals(doc.getLastModificationDate(), modifTime);
+
+               doc = ht.get(Document.class, id2);
+               txt = readFile(doc.getFile().asFile());
+               Assert.assertTrue(doc.getFile().getName().contains("_sdocument1"));
+               Assert.assertEquals(doc.getFile().getFormat(), format2);
+               Assert.assertTrue(txt.contains("replaced2.ddd"));
+               Assert.assertEquals(doc.getLastModificationDate(), modifTime);
+
+               rollbackNestedTransaction();
+               LOG.debug(">>>>> END testReplace()");
+       }
+
+    /**
+     * Test testUpdateRelations method for updating relations at versioning
+     * document.<BR>
+     * <B>Description :</B> <BR>
+     * <i>Create a study and a scenario with documents and try to update
+     * relations for every document in Study or Scenario.<BR>
+     * </i><BR>
+     * <B>Action : </B><BR>
+     * <i>1. call the method for the every document in the Study or
+     * Scenario.</i><BR>
+     * <B>Test data : </B><BR>
+     * <i>no input parameters</i><BR>
+     *
+     * <B>Outcome results:</B><BR>
+     * <i>
+     * <ul>
+     * <li>1: Update relations for every document: <BR>
+     * Delete old UsedBy relation from old version and create new UsedBy
+     * relation to new version document. Create new Uses relation from new
+     * version document</li>
+     * </ul>
+     * </i>
+     *
+     * @throws BusinessException
+     *             if test data creation is failed
+     * @throws IOException
+     *             if application configuration loading or test data creation is
+     *             failed
+     * @throws SQLException
+     *             if application configuration loading or test data creation is
+     *             failed
+     */
+    @Test
+    public final void testUpdateRelations() throws
+            BusinessException, IOException, SQLException {
+        LOG.debug(">>>>> BEGIN testUpdateRelations()");
+        startNestedTransaction();
+
+        HibernateTemplate ht = getHibernateTemplate();
+
+        Database.getInstance().reset();
+        _projectSettings.getAllSteps().clear(); // Clear config to be able to
+                                                // load it again
+        _projectSettings.configure("classpath:test/som.xml");
+
+        User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
+        _userDAO.create(goodUser);
+
+        // Create private study
+        Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
+        aStudy.setTitle("0.This is private study");
+        Long studyId = _studyDAO.create(aStudy);
+
+        // Add a scenario to the study
+        Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
+        Long scenId = _scenarioDAO.create(scen);
+        ht.flush();
+
+        org.splat.som.Step[] studySteps = _projectElementService
+                .getSteps(aStudy);
+        org.splat.som.Step[] scSteps = _projectElementService.getSteps(scen);
+
+        List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
+        steps.addAll(Arrays.asList(studySteps));
+        steps.addAll(Arrays.asList(scSteps));
+        Publication[] currentArray = new Publication[steps.size() * 2 - 2];
+        Publication[] nextArray = new Publication[steps.size() * 2 - 2];
+        Map<Integer, String[]> docusesMap = new HashMap<Integer, String[]>();
+        Map<Integer, long[]> docusedMap = new HashMap<Integer, long[]>();
+        int pubNumber = 0;
+        for (org.splat.som.Step step : steps) {
+            List<DocumentType> dtypes = _documentTypeService.selectTypesOf(step
+                    .getStep());
+            if (dtypes.size() > 0) {
+                DocumentType dtype = dtypes.get(0);
+                if (step.getOwner() instanceof Study) {
+                    currentArray[pubNumber] = addDoc(aStudy, step, "current"
+                            + pubNumber, dtype);
+                    currentArray[pubNumber + 1] = addDoc(aStudy, step,
+                            "current" + (pubNumber + 1), dtype);
+
+                } else {
+                    currentArray[pubNumber] = addDoc(scen, step, "current"
+                            + pubNumber, dtype);
+                    currentArray[pubNumber + 1] = addDoc(scen, step, "current"
+                            + (pubNumber + 1), dtype);
+                }
+
+                pubNumber += 2;
+            }
+        }
+
+        ht.flush();
+        ht.update(aStudy);
+        ht.flush();
+
+        for (Integer numPub = currentArray.length - 1; numPub >= 0; numPub--) {           
+            long[] docusedby = new long[1];
+            if (numPub != 0) {
+                currentArray[numPub].addDependency(currentArray[numPub - 1]);
+            }
+            if (numPub != currentArray.length - 1) {
+                docusedby[0] = currentArray[numPub + 1].getIndex();
+                docusedMap.put(new Integer(numPub), docusedby);
+            }
+        }
+
+        for (int numPub = 0; numPub < currentArray.length; numPub++) {
+            String[] docuses = new String[1];
+            nextArray[numPub] = addDoc(aStudy, currentArray[numPub].getStep(),
+                    "next" + numPub, currentArray[numPub].value().getType());
+            ht.flush();
+            if (numPub != 0) {
+                docuses[0] = String.valueOf(nextArray[numPub - 1].value()
+                        .getIndex());
+                docusesMap.put(numPub, docuses);
+            }
+            _publicationService.updateRelations(currentArray[numPub].getStep(),
+                    currentArray[numPub], nextArray[numPub],
+                    docusesMap.get(numPub), docusedMap.get(numPub));
+        }
+
+        //Action
+        for (int numPub = 0; numPub < currentArray.length; numPub++) {
+            if (numPub != currentArray.length - 1) {
+
+                Assert.assertEquals(
+                        currentArray[numPub].getRelations(UsedByRelation.class),
+                        new ArrayList<Publication>());
+                Assert.assertTrue(nextArray[numPub].getRelations(
+                        UsedByRelation.class)
+                        .contains(currentArray[numPub + 1]));
+                Assert.assertTrue(nextArray[numPub].getRelations(
+                        UsedByRelation.class).contains(nextArray[numPub + 1]));
+            }
+
+            if (numPub != 0) {
+                Assert.assertEquals(
+                        currentArray[numPub].getRelations(UsesRelation.class)
+                                .get(0), nextArray[numPub - 1]);
+                Assert.assertEquals(
+                        nextArray[numPub].getRelations(UsesRelation.class).get(
+                                0), nextArray[numPub - 1]);
+            }
+        }
+        rollbackNestedTransaction();
+        LOG.debug(">>>>> END testUpdateRelations()");
+    }
+
+
+       /**
+        * Find a document publication in the project element.
+        * 
+        * @param projElem
+        *            the project element to scan
+        * @param docId
+        *            the document id
+        * @return the document publication if found, otherwise return null
+        */
+       private Publication getPublicationByDocId(final ProjectElement projElem,
+                       final Long docId) {
+               Publication res = null;
+               for (Publication pub : projElem.getDocums()) {
+                       if (docId.equals(pub.value().getIndex())) {
+                               res = pub;
+                               break;
+                       }
+               }
+               return res;
+       }
+
+       /**
+        * Get file content as a string.
+        * 
+        * @param f
+        *            the file to read
+        * @return the file content
+        * @throws IOException
+        *             if reading is failed
+        */
+       private String readFile(final File f) throws IOException {
+               FileInputStream fstream = new FileInputStream(f);
+               // Get the object of DataInputStream
+               DataInputStream in = new DataInputStream(fstream);
+               BufferedReader br = new BufferedReader(new InputStreamReader(in));
+               StringBuffer res = new StringBuffer();
+               String str;
+               // Read File Line By Line
+               while ((str = br.readLine()) != null) {
+                       res.append(str);
+               }
+               // Close the input stream
+               in.close();
+               return res.toString();
+       }
+}
\ No newline at end of file