1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
9 package test.splat.service;
11 import java.io.BufferedReader;
12 import java.io.DataInputStream;
14 import java.io.FileInputStream;
15 import java.io.FileNotFoundException;
16 import java.io.FileWriter;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.sql.SQLException;
20 import java.text.DecimalFormat;
21 import java.text.ParseException;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Calendar;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.List;
30 import org.splat.dal.bo.kernel.User;
31 import org.splat.dal.bo.som.ConvertsRelation;
32 import org.splat.dal.bo.som.Document;
33 import org.splat.dal.bo.som.DocumentType;
34 import org.splat.dal.bo.som.ProgressState;
35 import org.splat.dal.bo.som.ProjectElement;
36 import org.splat.dal.bo.som.Publication;
37 import org.splat.dal.bo.som.Scenario;
38 import org.splat.dal.bo.som.Study;
39 import org.splat.dal.bo.som.Document.Properties;
40 import org.splat.dal.bo.som.UsedByRelation;
41 import org.splat.dal.bo.som.UsesRelation;
42 import org.splat.dal.dao.kernel.UserDAO;
43 import org.splat.dal.dao.som.Database;
44 import org.splat.dal.dao.som.ScenarioDAO;
45 import org.splat.dal.dao.som.StudyDAO;
46 import org.splat.exception.BusinessException;
47 import org.splat.exception.IncompatibleDataException;
48 import org.splat.kernel.InvalidPropertyException;
49 import org.splat.kernel.MissedPropertyException;
50 import org.splat.kernel.MultiplyDefinedException;
51 import org.splat.kernel.NotApplicableException;
52 import org.splat.log.AppLogger;
53 import org.splat.service.DocumentTypeService;
54 import org.splat.service.ProjectElementService;
55 import org.splat.service.PublicationService;
56 import org.splat.service.StepService;
57 import org.splat.service.StudyService;
58 import org.splat.service.technical.ProjectSettingsService;
59 import org.splat.service.technical.RepositoryService;
60 import org.splat.service.technical.ProjectSettingsService.Step;
61 import org.springframework.beans.factory.annotation.Autowired;
62 import org.springframework.beans.factory.annotation.Qualifier;
63 import org.springframework.orm.hibernate3.HibernateTemplate;
64 import org.testng.Assert;
65 import org.testng.annotations.Test;
67 import test.splat.common.BaseTest;
68 import test.splat.util.TestEntitiesGenerator;
71 * Test class for PublicationService.
73 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
76 public class TestPublicationService extends BaseTest {
79 * Logger for the class.
81 private static final AppLogger LOG = AppLogger
82 .getLogger(TestPublicationService.class);
85 * The StudyDAO. Later injected by Spring.
88 @Qualifier("studyDAO")
89 private transient StudyDAO _studyDAO;
92 * The PublicationService. Later injected by Spring.
95 @Qualifier("publicationService")
96 private transient PublicationService _publicationService;
99 * The ProjectElementService. Later injected by Spring.
102 @Qualifier("projectElementService")
103 private transient ProjectElementService _projectElementService;
106 * The StepService. Later injected by Spring.
109 @Qualifier("stepService")
110 private transient StepService _stepService;
113 * The ProjectSettingsService. Later injected by Spring.
116 @Qualifier("projectSettings")
117 private transient ProjectSettingsService _projectSettings;
120 * The DocumentTypeService. Later injected by Spring.
123 @Qualifier("documentTypeService")
124 private transient DocumentTypeService _documentTypeService;
127 * The StudyService. Later injected by Spring.
130 @Qualifier("studyService")
131 private transient StudyService _studyService;
134 * The RepositoryService. Later injected by Spring.
137 @Qualifier("repositoryService")
138 private transient RepositoryService _repositoryService;
141 * The UserDAO. Later injected by Spring.
144 @Qualifier("userDAO")
145 private transient UserDAO _userDAO;
148 * The Scenario DAO. Later injected by Spring.
151 @Qualifier("scenarioDAO")
152 private transient ScenarioDAO _scenarioDAO;
155 * Create a persistent scenario for tests.
157 * @return a persistent scenario
158 * @throws InvalidPropertyException
159 * if an invalid property is used when creating objects
160 * @throws MultiplyDefinedException
161 * when trying to create an object with already existing id
162 * @throws MissedPropertyException
163 * if a mandatory property is not defined for an object to be created
164 * @throws IOException
165 * if document creation is failed
166 * @throws SQLException
167 * if project settings loading is failed
169 private Study createStudy() throws InvalidPropertyException,
170 MissedPropertyException, MultiplyDefinedException, IOException,
172 // Create a scenario for tests
173 HibernateTemplate ht = getHibernateTemplate();
175 Database.getInstance().reset();
176 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
177 // Load workflow customization
179 _projectSettings.configure("classpath:test/som.xml");
180 } catch (FileNotFoundException e) {
181 Assert.fail("Can't find som.xml: ", e);
183 List<Step> steps = _projectSettings.getAllSteps();
184 Assert.assertTrue(steps.size() > 0, "No steps are created.");
186 // Create a test user
187 User.Properties uprop = new User.Properties();
188 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
189 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
190 .addRole("TST_user").setMailAddress(
191 "noreply@salome-platform.org");
192 uprop.disableCheck();
193 User anAuthor = new User(uprop);
194 ht.saveOrUpdate(anAuthor);
196 // Create a test study
197 Study.Properties stprops = new Study.Properties().setReference(
198 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
199 Study aStudy = new Study(stprops);
200 ht.saveOrUpdate(aStudy);
202 // Create a test scenario
203 Scenario.Properties sprops = new Scenario.Properties().setTitle(
204 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
205 Scenario aScenario = new Scenario(sprops);
206 aStudy.getScenariiList().add(aScenario);
207 ht.saveOrUpdate(anAuthor);
208 ht.saveOrUpdate(aStudy);
209 ht.saveOrUpdate(aScenario);
211 // Create documents for each scenario step
212 Document.Properties dprop = new Document.Properties().setAuthor(
213 anAuthor).setDate(new Date());
215 Publication usedPub = null;
216 Map<Long, Long> usedMap = new HashMap<Long, Long>();
217 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
218 Step step = _projectSettings.getStep(stepNum);
219 LOG.debug("Create scenario step: " + stepNum);
220 ProjectElement projElem;
222 if (step.appliesTo(Study.class)) {
225 projElem = aScenario;
227 org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
228 List<DocumentType> dtypes = _documentTypeService
229 .selectTypesOf(step);
230 if (dtypes.size() > 0) {
231 DocumentType dtype = dtypes.get(0);
232 // Create a document published in the scenario
233 // document<i>: document type[0] - first type used on the step
234 // <source-file>.brep
235 // <attached-file>.med
237 dprop.setName("document" + stepNum).setType(dtype);
238 if (step.getNumber() > 3) {
239 dprop.setFormat("med");
241 dprop.setFormat("py");
243 Publication pub = createDoc(projElem, aScStep, dprop, "med",
245 if (usedPub != null) {
246 pub.addDependency(usedPub);
247 LOG.debug("Add dependency: " + pub.value().getTitle()
248 + " from " + usedPub.value().getTitle());
249 ht.saveOrUpdate(pub.value());
252 usedMap.put(pub.getIndex(), usedPub.getIndex());
256 if (dtypes.size() <= 0) {
257 LOG.debug("No document types are found for scenario step " + i);
261 // Check that the scenario and its documents have been created correctly.
263 Assert.assertNotNull(ht.find("from Document"),
264 "No documents in the database.");
265 Assert.assertTrue(ht.find("from Document").size() > 0,
266 "No documents in the database.");
268 Assert.assertNotNull(ht.find("from Publication where owner="
269 + aScenario.getIndex()), "No publications in the database.");
271 ht.find("from Publication where owner=" + aScenario.getIndex())
272 .size() > 0, "No publications in the database.");
274 for (Publication p : (List<Publication>) ht
275 .find("from Publication where owner=" + aScenario.getIndex())) {
276 LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
277 + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
279 Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
280 "The publication was not attached to the scenario.");
283 // Remove the scenario from the current hibernate session.
285 // Check that the scenario is created in the database.
286 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
287 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
288 Assert.assertTrue(aScen.getDocums().size() > 0,
289 "No publications in the scenario.");
291 Assert.assertTrue(i > 0,
292 "More then one document must be in the database");
294 // Check created uses relations
296 .assertTrue(usedMap.size() > 0,
297 "Uses relations must be created.");
298 boolean foundAny = false;
299 for (Long usingId : usedMap.keySet()) {
300 for (Publication pub : aScen.getDocums()) {
301 if (pub.getIndex() == usingId) {
302 boolean found = false;
303 for (Publication used : aScen.getDocums()) {
304 found = (used.getIndex() == usedMap.get(usingId));
310 for (Publication used : aStudy.getDocums()) {
311 found = (used.getIndex() == usedMap.get(usingId));
317 Assert.assertTrue(found,
318 "Uses relation was not created in the database.");
319 foundAny = foundAny || found;
323 Assert.assertTrue(foundAny,
324 "No Uses relation was created in the database.");
326 return aScenario.getOwnerStudy();
330 * Create a document published in the scenario. <BR>
332 * document type - type used on the step <BR>
333 * <source-file>.brep <BR>
334 * <attached-file>.med
337 * the scenario to add the document to
339 * scenario step where the document to be published
341 * document properties
342 * @param attachedFileExt
343 * extension of the secon attached (exported) file
345 * outdated document flag
346 * @return the publication of the created document
347 * @throws IOException
348 * @throws MultiplyDefinedException
349 * @throws InvalidPropertyException
350 * @throws MissedPropertyException
352 private Publication createDoc(final ProjectElement aScenario,
353 final org.splat.som.Step aScStep, final Properties dprop,
354 final String attachedFileExt, final boolean isOutdated)
355 throws MissedPropertyException, InvalidPropertyException,
356 MultiplyDefinedException, IOException {
357 // Create a document published in the scenario
358 // document<i>: document type - type used on the step
359 // <source-file>.brep
360 // <attached-file>.med
361 Publication pub = _stepService.createDocument(aScStep, dprop);
362 Assert.assertNotNull(pub.getOwner(),
363 "The publication must be attached to the scenario.");
364 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
365 "The publication was not attached to the scenario.");
371 HibernateTemplate ht = getHibernateTemplate();
372 ht.saveOrUpdate(pub);
375 ht.save(pub.value());
377 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
383 * Test of generating a study document index.<BR>
384 * <B>Description :</B> <BR>
385 * <i>Create a study and try to generate the next document index.</i><BR>
386 * <B>Action : </B><BR>
387 * <i>1. call DAO's read method for an existing id.</i><BR>
388 * <B>Test data : </B><BR>
389 * <i>no input parameters</i><BR>
391 * <B>Outcome results:</B><BR>
394 * <li>The new index must be equal to the incremented old one and saved into the database<BR>
399 * @throws InvalidPropertyException
400 * if an invalid property is used when creating objects
401 * @throws MultiplyDefinedException
402 * when trying to create an object with already existing id
403 * @throws MissedPropertyException
404 * if a mandatory property is not defined for an object to be created
405 * @throws SQLException
406 * if test study creation is failed
407 * @throws IOException
408 * if test study creation is failed
409 * @throws ParseException
410 * @throws InterruptedException
411 * @throws NotApplicableException
415 public void testCreateDoc() throws InvalidPropertyException,
416 MissedPropertyException, MultiplyDefinedException, IOException,
417 SQLException, NotApplicableException, InterruptedException,
419 LOG.debug(">>>>> BEGIN testCreateDoc()");
420 startNestedTransaction();
422 HibernateTemplate ht = getHibernateTemplate();
423 Study aStudy = createStudy();
424 // Call DAO's create method for a good transient study.
425 Long id = aStudy.getIndex();
426 Assert.assertNotNull(id,
427 "Create method returns null instead of a new id.");
428 Assert.assertTrue(id > 0, "The new id is not a positive number.");
430 // Call DAO's get method for an existing id.
432 getHibernateTemplate().evict(aStudy);
433 getHibernateTemplate().clear();
434 Study aStudyFound = _studyDAO.get(id);
435 ht.evict(aStudyFound);
437 long userId = aStudyFound.getAuthor().getIndex();
438 org.splat.som.Step[] studySteps = _projectElementService
439 .getSteps(aStudyFound);
440 org.splat.som.Step[] scSteps = _projectElementService
441 .getSteps(aStudyFound.getScenarii()[0]);
443 List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
444 steps.addAll(Arrays.asList(studySteps));
445 steps.addAll(Arrays.asList(scSteps));
446 steps.addAll(Arrays.asList(studySteps));
447 DecimalFormat tostring = new DecimalFormat(Document.suformat);
448 for (org.splat.som.Step step : steps) {
449 LOG.debug("Create a document for the step " + step.getNumber());
451 List<DocumentType> dtypes = _documentTypeService.selectTypesOf(step
453 if (dtypes.size() > 0) {
454 DocumentType dtype = dtypes.get(0);
455 int oldInd = ht.get(Study.class, aStudyFound.getIndex())
456 .getLastLocalIndex();
458 // Create a file in the download directory
459 String fname = "filename" + step.getNumber() + ".py";
460 String filePath = getDownloadPath(aStudyFound.getAuthor())
462 LOG.debug(step.getStep().getKey() + ": "
463 + step.getOwner().getClass().getSimpleName()
464 + ": Create test file: " + filePath);
465 FileWriter fw = new FileWriter(filePath);
467 .write("Simulation of filename.py file for creating a new document at "
471 Publication addoc = _publicationService.createDoc(aStudyFound
472 .getIndex(), step, dtype.getIndex(), userId, fname,
473 "tstdoc", ProgressState.inWORK, "", "", new Date(),
479 int ind = ht.get(Study.class, aStudyFound.getIndex())
480 .getLastLocalIndex();
482 LOG.debug("Previous index: " + oldInd + ", new index: " + ind);
483 Assert.assertEquals(ht.get(Study.class, aStudyFound.getIndex())
484 .getLastLocalIndex(), oldInd + 1,
485 "Incremented index must be saved in the database.");
486 aStudy = (Study) ht.find(
487 "from Study where rid = " + aStudyFound.getIndex())
489 Assert.assertEquals(aStudy.getLastLocalIndex(), oldInd + 1,
490 "Incremented index must be saved in the database.");
491 Assert.assertEquals(addoc.getSourceFile().getName(), tostring
492 .format(aStudy.getLastLocalIndex())
493 + "_" + fname, "The generated file name is incorrect.");
497 rollbackNestedTransaction();
498 LOG.debug(">>>>> END testCreateDoc()");
502 * Test of file attaching to a study document.<BR>
503 * <B>Description :</B> <BR>
504 * <i>Create a study and try to attach a new file to its each document.</i><BR>
505 * <B>Action : </B><BR>
506 * <i>1. call attach method for each document publication of the study.</i><BR>
507 * <B>Test data : </B><BR>
508 * <i>no input parameters</i><BR>
510 * <B>Outcome results:</B><BR>
513 * <li>The new ConvertsRelation and the new File object must be created in the database.<BR>
518 * @throws InvalidPropertyException
519 * if an invalid property is used when creating objects
520 * @throws MultiplyDefinedException
521 * when trying to create an object with already existing id
522 * @throws MissedPropertyException
523 * if a mandatory property is not defined for an object to be created
524 * @throws SQLException
525 * if test study creation is failed
526 * @throws IOException
527 * if test study creation is failed
528 * @throws ParseException
529 * @throws InterruptedException
530 * @throws NotApplicableException
534 public void testAttach() throws InvalidPropertyException,
535 MissedPropertyException, MultiplyDefinedException, IOException,
536 SQLException, NotApplicableException, InterruptedException,
538 LOG.debug(">>>>> BEGIN testAttach()");
539 startNestedTransaction();
541 HibernateTemplate ht = getHibernateTemplate();
542 Study aStudy = createStudy();
543 // Call DAO's create method for a good transient study.
544 Long id = aStudy.getIndex();
545 Assert.assertNotNull(id,
546 "Create method returns null instead of a new id.");
547 Assert.assertTrue(id > 0, "The new id is not a positive number.");
549 // Call DAO's get method for an existing id.
551 getHibernateTemplate().evict(aStudy);
552 getHibernateTemplate().clear();
553 Study aStudyFound = _studyDAO.get(id);
555 ht.evict(aStudyFound);
557 long userId = aStudyFound.getAuthor().getIndex();
558 org.splat.som.Step[] studySteps = _projectElementService
559 .getSteps(aStudyFound);
560 org.splat.som.Step[] scSteps = _projectElementService
561 .getSteps(aStudyFound.getScenarii()[0]);
563 List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
564 steps.addAll(Arrays.asList(studySteps));
565 steps.addAll(Arrays.asList(scSteps));
566 steps.addAll(Arrays.asList(studySteps));
567 for (org.splat.som.Step step : steps) {
568 LOG.debug("Attach a new .py file to documents of the step "
569 + step.getNumber() + ": " + step.getStep().getKey() + ": "
570 + step.getOwner().getClass().getSimpleName());
572 for (Publication pub : step.getAllDocuments()) {
574 ht.evict(step.getOwner());
576 ht.evict(pub.value());
577 int nbConverts = ht.find("from ConvertsRelation").size();
578 int nbDocConverts = ht.find(
579 "from ConvertsRelation where owner="
580 + pub.value().getIndex()).size();
581 int nbFiles = ht.find("from File").size();
583 ConvertsRelation rel = _publicationService.attach(pub, "py");
587 Assert.assertNotNull(rel,
588 "Returned ConvertsRelation must not be null.");
590 .assertTrue(rel.isSaved(),
591 "Returned ConvertsRelation must be saved in the database.");
592 Assert.assertEquals(ht.find(
593 "from ConvertsRelation where owner="
594 + pub.value().getIndex()).size(),
596 "Number of created ConvertsRelations must be 1.");
597 Assert.assertEquals(ht.find("from ConvertsRelation").size(),
599 "Number of created ConvertsRelations must be 1.");
600 Assert.assertNotNull(rel.getTo(),
601 "Attached File must not be null.");
602 Assert.assertTrue(rel.isSaved(),
603 "Attached File must be saved in the database.");
607 "from File where rid="
608 + rel.getTo().getIndex())
609 .size(), 1, "Number of created File must be 1.");
610 Assert.assertEquals(ht.find("from File").size(), nbFiles + 1,
611 "Number of created Files must be 1.");
615 rollbackNestedTransaction();
616 LOG.debug(">>>>> END testAttach()");
620 * Get path to the user's downloads directory. The directory is created if it is not exist yet.
624 * @return absolute path to downloads directory followed by slash
626 private String getDownloadPath(final User user) {
627 // Prepare download directory
628 File tmpDir = _repositoryService.getDownloadDirectory(user);
629 if (!tmpDir.exists()) {
630 Assert.assertTrue(tmpDir.mkdir(),
631 "Can't create temporary directory: "
632 + tmpDir.getAbsolutePath());
635 return tmpDir.getAbsolutePath() + "/";
639 * Test testReplace method for a published document.<BR>
640 * <B>Description :</B> <BR>
641 * <i>Create a study and a scenario with documents and try to replace source files.<BR>
643 * <B>Action : </B><BR>
644 * <i>1. call the method for a document in the status inDRAFT.</i><BR>
645 * <i>2. call the method for a document in the status inCHECK.</i><BR>
646 * <i>3. call the method for a document in the status APPROVED.</i><BR>
647 * <i>4. call the method for an Extern document published in the study step.</i><BR>
648 * <i>5. call the method for an inWork document published in the scenario step.</i><BR>
649 * <B>Test data : </B><BR>
650 * <i>no input parameters</i><BR>
652 * <B>Outcome results:</B><BR>
655 * <li>1-3: Exception must be thrown. The document source file content must not be replaced.<BR>
657 * <li>4: The document source file content in the study must be replaced.<BR>
659 * <li>5: The document source file content in the scenario must be replaced.<BR>
664 * @throws BusinessException
665 * if test data creation is failed
666 * @throws IOException
667 * if application configuration loading or test data creation is failed
668 * @throws SQLException
669 * if application configuration loading or test data creation is failed
672 public void testReplace() throws BusinessException, IOException,
674 LOG.debug(">>>>> BEGIN testReplace()");
675 startNestedTransaction();
677 HibernateTemplate ht = getHibernateTemplate();
679 Database.getInstance().reset();
680 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
681 _projectSettings.configure("classpath:test/som.xml");
683 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
684 _userDAO.create(goodUser);
686 // Create private study
687 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
688 aStudy.setTitle("0.This is private study");
689 Long studyId = _studyDAO.create(aStudy);
691 // Add a scenario to the study
692 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
693 Long scenId = _scenarioDAO.create(scen);
696 DocumentType dtype = _documentTypeService.selectType("minutes");
698 // Add documents to the first study activity
699 // Add a converts relations
700 Map<Integer, org.splat.som.Step> stSteps = _projectElementService
701 .getStepsMap(aStudy);
702 org.splat.som.Step aStep = stSteps.get(1);
703 Publication pub0inDraft = addDoc(aStudy, aStep, "document0indraft",
705 pub0inDraft.value().setProgressState(ProgressState.inDRAFT);
706 Publication pub0inCheck = addDoc(aStudy, aStep, "document0incheck",
708 pub0inCheck.value().setProgressState(ProgressState.inCHECK);
709 Publication pub0approved = addDoc(aStudy, aStep, "document0approved",
711 pub0approved.value().setProgressState(ProgressState.APPROVED);
712 Publication pub1 = addDoc(aStudy, aStep, "document1", dtype);
713 String format1 = pub1.value().getFormat();
718 // Add documents to the first scenario activity
719 scen = aStudy.getScenariiList().get(0);
720 Map<Integer, org.splat.som.Step> scSteps = _projectElementService
722 aStep = scSteps.get(2);
723 Publication spub1 = addDoc(scen, aStep, "sdocument1", dtype);
724 String format2 = spub1.value().getFormat();
727 // Remember documents ids
728 Long id0inDraft = pub0inDraft.value().getIndex(), id0inCheck = pub0inCheck
729 .value().getIndex(), id0approved = pub0approved.value()
730 .getIndex(), id1 = pub1.value().getIndex(), id2 = spub1.value()
734 ht.evict(scen.getOwnerStudy());
737 Assert.assertTrue(ht.find("from File").size() >= 3,
738 "Files were not created in the database.");
740 Date modifTime = Calendar.getInstance().getTime();
742 aStudy = _studyService.selectStudy(studyId);
743 File newFile = new File(getDownloadPath(goodUser) + "replaced0.ddd");
744 createFile(newFile.getAbsolutePath());
746 // TEST CALL: Try to replace a file for inDraft document
747 Publication pub = getPublicationByDocId(aStudy, id0inDraft);
749 _publicationService.replace(pub, newFile, modifTime);
751 .fail("IncompatibleDataException is expected for a doucment in the status "
752 + pub.getProgressState().name());
753 } catch (IncompatibleDataException e) {
754 LOG.debug("Expected exception: ", e);
757 // TEST CALL: Try to replace a file for inCheck document
758 pub = getPublicationByDocId(aStudy, id0inCheck);
760 _publicationService.replace(pub, newFile, modifTime);
762 .fail("IncompatibleDataException is expected for a doucment in the status "
763 + pub.getProgressState().name());
764 } catch (IncompatibleDataException e) {
765 LOG.debug("Expected exception: ", e);
768 // TEST CALL: Try to replace a file for Approved document
769 pub = getPublicationByDocId(aStudy, id0approved);
771 _publicationService.replace(pub, newFile, modifTime);
773 .fail("IncompatibleDataException is expected for a doucment in the status "
774 + pub.getProgressState().name());
775 } catch (IncompatibleDataException e) {
776 LOG.debug("Expected exception: ", e);
781 // TEST CALL: Replace a file in the study step
782 pub = getPublicationByDocId(aStudy, id1);
783 newFile = new File(getDownloadPath(goodUser) + "replaced1.ddd");
784 createFile(newFile.getAbsolutePath());
785 Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime));
788 // TEST CALL: Replace a file in the scenario step
789 scen = aStudy.getScenariiList().get(0);
790 pub = getPublicationByDocId(scen, id2);
791 newFile = new File(getDownloadPath(goodUser) + "replaced2.ddd");
792 createFile(newFile.getAbsolutePath());
793 Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime));
797 // Remove milliseconds because they are lost after saving in the database
798 modifTime.setTime((modifTime.getTime() / 1000) * 1000);
800 Document doc = ht.get(Document.class, id1);
801 String txt = readFile(doc.getFile().asFile());
802 Assert.assertTrue(doc.getFile().getName().contains("_document1"));
803 Assert.assertEquals(doc.getFile().getFormat(), format1);
804 Assert.assertTrue(txt.contains("replaced1.ddd"));
805 Assert.assertEquals(doc.getLastModificationDate(), modifTime);
807 doc = ht.get(Document.class, id2);
808 txt = readFile(doc.getFile().asFile());
809 Assert.assertTrue(doc.getFile().getName().contains("_sdocument1"));
810 Assert.assertEquals(doc.getFile().getFormat(), format2);
811 Assert.assertTrue(txt.contains("replaced2.ddd"));
812 Assert.assertEquals(doc.getLastModificationDate(), modifTime);
814 rollbackNestedTransaction();
815 LOG.debug(">>>>> END testReplace()");
819 * Test testUpdateRelations method for updating relations at versioning
821 * <B>Description :</B> <BR>
822 * <i>Create a study and a scenario with documents and try to update
823 * relations for every document in Study or Scenario.<BR>
825 * <B>Action : </B><BR>
826 * <i>1. call the method for the every document in the Study or
828 * <B>Test data : </B><BR>
829 * <i>no input parameters</i><BR>
831 * <B>Outcome results:</B><BR>
834 * <li>1: Update relations for every document: <BR>
835 * Delete old UsedBy relation from old version and create new UsedBy
836 * relation to new version document. Create new Uses relation from new
837 * version document</li>
841 * @throws BusinessException
842 * if test data creation is failed
843 * @throws IOException
844 * if application configuration loading or test data creation is
846 * @throws SQLException
847 * if application configuration loading or test data creation is
851 public final void testUpdateRelations() throws
852 BusinessException, IOException, SQLException {
853 LOG.debug(">>>>> BEGIN testUpdateRelations()");
854 startNestedTransaction();
856 HibernateTemplate ht = getHibernateTemplate();
858 Database.getInstance().reset();
859 _projectSettings.getAllSteps().clear(); // Clear config to be able to
861 _projectSettings.configure("classpath:test/som.xml");
863 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
864 _userDAO.create(goodUser);
866 // Create private study
867 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
868 aStudy.setTitle("0.This is private study");
869 Long studyId = _studyDAO.create(aStudy);
871 // Add a scenario to the study
872 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
873 Long scenId = _scenarioDAO.create(scen);
876 org.splat.som.Step[] studySteps = _projectElementService
878 org.splat.som.Step[] scSteps = _projectElementService.getSteps(scen);
880 List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
881 steps.addAll(Arrays.asList(studySteps));
882 steps.addAll(Arrays.asList(scSteps));
883 Publication[] currentArray = new Publication[steps.size() * 2 - 2];
884 Publication[] nextArray = new Publication[steps.size() * 2 - 2];
885 Map<Integer, String[]> docusesMap = new HashMap<Integer, String[]>();
886 Map<Integer, long[]> docusedMap = new HashMap<Integer, long[]>();
888 for (org.splat.som.Step step : steps) {
889 List<DocumentType> dtypes = _documentTypeService.selectTypesOf(step
891 if (dtypes.size() > 0) {
892 DocumentType dtype = dtypes.get(0);
893 if (step.getOwner() instanceof Study) {
894 currentArray[pubNumber] = addDoc(aStudy, step, "current"
896 currentArray[pubNumber + 1] = addDoc(aStudy, step,
897 "current" + (pubNumber + 1), dtype);
900 currentArray[pubNumber] = addDoc(scen, step, "current"
902 currentArray[pubNumber + 1] = addDoc(scen, step, "current"
903 + (pubNumber + 1), dtype);
914 for (Integer numPub = currentArray.length - 1; numPub >= 0; numPub--) {
915 long[] docusedby = new long[1];
917 currentArray[numPub].addDependency(currentArray[numPub - 1]);
919 if (numPub != currentArray.length - 1) {
920 docusedby[0] = currentArray[numPub + 1].getIndex();
921 docusedMap.put(new Integer(numPub), docusedby);
925 for (int numPub = 0; numPub < currentArray.length; numPub++) {
926 String[] docuses = new String[1];
927 nextArray[numPub] = addDoc(aStudy, currentArray[numPub].getStep(),
928 "next" + numPub, currentArray[numPub].value().getType());
931 docuses[0] = String.valueOf(nextArray[numPub - 1].value()
933 docusesMap.put(numPub, docuses);
935 _publicationService.updateRelations(currentArray[numPub].getStep(),
936 currentArray[numPub], nextArray[numPub],
937 docusesMap.get(numPub), docusedMap.get(numPub));
941 for (int numPub = 0; numPub < currentArray.length; numPub++) {
942 if (numPub != currentArray.length - 1) {
945 currentArray[numPub].getRelations(UsedByRelation.class),
946 new ArrayList<Publication>());
947 Assert.assertTrue(nextArray[numPub].getRelations(
948 UsedByRelation.class)
949 .contains(currentArray[numPub + 1]));
950 Assert.assertTrue(nextArray[numPub].getRelations(
951 UsedByRelation.class).contains(nextArray[numPub + 1]));
956 currentArray[numPub].getRelations(UsesRelation.class)
957 .get(0), nextArray[numPub - 1]);
959 nextArray[numPub].getRelations(UsesRelation.class).get(
960 0), nextArray[numPub - 1]);
963 rollbackNestedTransaction();
964 LOG.debug(">>>>> END testUpdateRelations()");
969 * Find a document publication in the project element.
972 * the project element to scan
975 * @return the document publication if found, otherwise return null
977 private Publication getPublicationByDocId(final ProjectElement projElem,
979 Publication res = null;
980 for (Publication pub : projElem.getDocums()) {
981 if (docId.equals(pub.value().getIndex())) {
990 * Get file content as a string.
994 * @return the file content
995 * @throws IOException
996 * if reading is failed
998 private String readFile(final File f) throws IOException {
999 FileInputStream fstream = new FileInputStream(f);
1000 // Get the object of DataInputStream
1001 DataInputStream in = new DataInputStream(fstream);
1002 BufferedReader br = new BufferedReader(new InputStreamReader(in));
1003 StringBuffer res = new StringBuffer();
1005 // Read File Line By Line
1006 while ((str = br.readLine()) != null) {
1009 // Close the input stream
1011 return res.toString();