Salome HOME
dc2e30306ef8e9b21e29782801c61429b0f9c64c
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / service / TestStudyService.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   12 Oct 2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9 package test.splat.service;
10
11 import java.io.File;
12 import java.io.FileNotFoundException;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.sql.SQLException;
16 import java.util.Date;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.splat.dal.bo.kernel.User;
22 import org.splat.dal.bo.som.ContributorRelation;
23 import org.splat.dal.bo.som.DescriptionAttribute;
24 import org.splat.dal.bo.som.Document;
25 import org.splat.dal.bo.som.DocumentType;
26 import org.splat.dal.bo.som.KnowledgeElement;
27 import org.splat.dal.bo.som.KnowledgeElementType;
28 import org.splat.dal.bo.som.ProgressState;
29 import org.splat.dal.bo.som.ProjectElement;
30 import org.splat.dal.bo.som.Publication;
31 import org.splat.dal.bo.som.Scenario;
32 import org.splat.dal.bo.som.SimulationContext;
33 import org.splat.dal.bo.som.Study;
34 import org.splat.dal.bo.som.ValidationCycle;
35 import org.splat.dal.bo.som.ValidationCycleRelation;
36 import org.splat.dal.bo.som.ValidationStep;
37 import org.splat.dal.bo.som.Document.Properties;
38 import org.splat.dal.dao.kernel.UserDAO;
39 import org.splat.dal.dao.som.Database;
40 import org.splat.dal.dao.som.KnowledgeElementDAO;
41 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
42 import org.splat.dal.dao.som.ScenarioDAO;
43 import org.splat.dal.dao.som.StudyDAO;
44 import org.splat.dal.dao.som.ValidationCycleDAO;
45 import org.splat.exception.BusinessException;
46 import org.splat.exception.InvalidParameterException;
47 import org.splat.kernel.InvalidPropertyException;
48 import org.splat.kernel.MissedPropertyException;
49 import org.splat.kernel.MultiplyDefinedException;
50 import org.splat.log.AppLogger;
51 import org.splat.service.DocumentTypeService;
52 import org.splat.service.ProjectElementService;
53 import org.splat.service.PublicationService;
54 import org.splat.service.SimulationContextService;
55 import org.splat.service.StepService;
56 import org.splat.service.StudyService;
57 import org.splat.service.dto.FileDTO;
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;
66
67 import test.splat.common.BaseTest;
68 import test.splat.util.TestEntitiesGenerator;
69
70 /**
71  * Test class for StudyService.
72  * 
73  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
74  * 
75  */
76 public class TestStudyService extends BaseTest {
77
78         /**
79          * Logger for the class.
80          */
81         private static final AppLogger LOG = AppLogger
82                         .getLogger(TestStudyService.class);
83
84         /**
85          * The StudyDAO. Later injected by Spring.
86          */
87         @Autowired
88         @Qualifier("studyDAO")
89         private transient StudyDAO _studyDAO;
90
91         /**
92          * The PublicationService. Later injected by Spring.
93          */
94         @Autowired
95         @Qualifier("publicationService")
96         private transient PublicationService _publicationService;
97
98         /**
99          * The ProjectElementService. Later injected by Spring.
100          */
101         @Autowired
102         @Qualifier("projectElementService")
103         private transient ProjectElementService _projectElementService;
104
105         /**
106          * The StepService. Later injected by Spring.
107          */
108         @Autowired
109         @Qualifier("stepService")
110         private transient StepService _stepService;
111
112         /**
113          * The ProjectSettingsService. Later injected by Spring.
114          */
115         @Autowired
116         @Qualifier("projectSettings")
117         private transient ProjectSettingsService _projectSettings;
118
119         /**
120          * The DocumentTypeService. Later injected by Spring.
121          */
122         @Autowired
123         @Qualifier("documentTypeService")
124         private transient DocumentTypeService _documentTypeService;
125
126         /**
127          * The StudyService. Later injected by Spring.
128          */
129         @Autowired
130         @Qualifier("studyService")
131         private transient StudyService _studyService;
132
133         /**
134          * The UserDAO. Later injected by Spring.
135          */
136         @Autowired
137         @Qualifier("userDAO")
138         private transient UserDAO _userDAO;
139
140         /**
141          * The KnowledgeElementDAO. Later injected by Spring.
142          */
143         @Autowired
144         @Qualifier("knowledgeElementDAO")
145         private transient KnowledgeElementDAO _knowledgeElementDAO;
146
147         /**
148          * The KnowledgeElementTypeDAO. Later injected by Spring.
149          */
150         @Autowired
151         @Qualifier("knowledgeElementTypeDAO")
152         private transient KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
153
154         /**
155          * The ScenarioDAO. Later injected by Spring.
156          */
157         @Autowired
158         @Qualifier("scenarioDAO")
159         private transient ScenarioDAO _scenarioDAO;
160
161         /**
162          * The SimulationContextService. Later injected by Spring.
163          */
164         @Autowired
165         @Qualifier("simulationContextService")
166         private transient SimulationContextService _simulationContextService;
167
168         /**
169          * The ValidationCycleDAO. Later injected by Spring.
170          */
171         @Autowired
172         @Qualifier("validationCycleDAO")
173         private transient ValidationCycleDAO _validationCycleDAO;
174
175         /**
176          * The RepositoryService. Later injected by Spring.
177          */
178         @Autowired
179         @Qualifier("repositoryService")
180         private transient RepositoryService _repositoryService;
181
182         /**
183          * Create a persistent scenario for tests.
184          * 
185          * @return a persistent scenario
186          * @throws InvalidPropertyException
187          *             if an invalid property is used when creating objects
188          * @throws MultiplyDefinedException
189          *             when trying to create an object with already existing id
190          * @throws MissedPropertyException
191          *             if a mandatory property is not defined for an object to be created
192          * @throws IOException
193          *             if document creation is failed
194          * @throws SQLException
195          *             if project settings loading is failed
196          */
197         private Study createStudy() throws InvalidPropertyException,
198                         MissedPropertyException, MultiplyDefinedException, IOException,
199                         SQLException {
200                 // Create a scenario for tests
201                 HibernateTemplate ht = getHibernateTemplate();
202
203                 Database.getInstance().reset();
204                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
205                 // Load workflow customization
206                 try {
207                         _projectSettings.configure("classpath:test/som.xml");
208                 } catch (FileNotFoundException e) {
209                         Assert.fail("Can't find som.xml: ", e);
210                 }
211                 List<Step> steps = _projectSettings.getAllSteps();
212                 Assert.assertTrue(steps.size() > 0, "No steps are created.");
213
214                 // Create a test user
215                 User.Properties uprop = new User.Properties();
216                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
217                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
218                                 .addRole("TST_user").setMailAddress(
219                                                 "noreply@salome-platform.org");
220                 uprop.disableCheck();
221                 User anAuthor = new User(uprop);
222                 ht.saveOrUpdate(anAuthor);
223
224                 // Create a test study
225                 Study.Properties stprops = new Study.Properties().setReference(
226                                 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
227                 Study aStudy = new Study(stprops);
228                 ht.saveOrUpdate(aStudy);
229
230                 // Create a test scenario
231                 Scenario.Properties sprops = new Scenario.Properties().setTitle(
232                                 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
233                 Scenario aScenario = new Scenario(sprops);
234                 aStudy.getScenariiList().add(aScenario);
235                 ht.saveOrUpdate(anAuthor);
236                 ht.saveOrUpdate(aStudy);
237                 ht.saveOrUpdate(aScenario);
238
239                 // Create documents for each scenario step
240                 Document.Properties dprop = new Document.Properties().setAuthor(
241                                 anAuthor).setDate(new Date());
242                 int i = 0;
243                 Publication usedPub = null;
244                 Map<Long, Long> usedMap = new HashMap<Long, Long>();
245                 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
246                         Step step = _projectSettings.getStep(stepNum);
247                         LOG.debug("Create scenario step: " + stepNum);
248                         ProjectElement projElem;
249
250                         if (step.appliesTo(Study.class)) {
251                                 projElem = aStudy;
252                         } else {
253                                 projElem = aScenario;
254                         }
255                         org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
256                         List<DocumentType> dtypes = _documentTypeService
257                                         .selectTypesOf(step);
258                         if (dtypes.size() > 0) {
259                                 DocumentType dtype = dtypes.get(0);
260                                 // Create a document published in the scenario
261                                 // document<i>: document type[0] - first type used on the step
262                                 // <source-file>.brep
263                                 // <attached-file>.med
264                                 i++;
265                                 dprop.setName("document" + stepNum).setType(dtype);
266                                 if (step.getNumber() > 3) {
267                                         dprop.setFormat("med");
268                                 } else {
269                                         dprop.setFormat("py");
270                                 }
271                                 Publication pub = createDoc(projElem, aScStep, dprop, "med",
272                                                 false);
273                                 if (usedPub != null) {
274                                         pub.addDependency(usedPub);
275                                         LOG.debug("Add dependency: " + pub.value().getTitle()
276                                                         + " from " + usedPub.value().getTitle());
277                                         ht.saveOrUpdate(pub.value());
278                                         ht.flush();
279
280                                         usedMap.put(pub.getIndex(), usedPub.getIndex());
281                                 }
282                                 usedPub = pub;
283                         }
284                         if (dtypes.size() <= 0) {
285                                 LOG.debug("No document types are found for scenario step " + i);
286                         }
287                 }
288
289                 // Check that the scenario and its documents have been created correctly.
290
291                 Assert.assertNotNull(ht.find("from Document"),
292                                 "No documents in the database.");
293                 Assert.assertTrue(ht.find("from Document").size() > 0,
294                                 "No documents in the database.");
295
296                 Assert.assertNotNull(ht.find("from Publication where owner="
297                                 + aScenario.getIndex()), "No publications in the database.");
298                 Assert.assertTrue(
299                                 ht.find("from Publication where owner=" + aScenario.getIndex())
300                                                 .size() > 0, "No publications in the database.");
301
302                 for (Publication p : (List<Publication>) ht
303                                 .find("from Publication where owner=" + aScenario.getIndex())) {
304                         LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
305                                         + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
306                                         + "]");
307                         Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
308                                         "The publication was not attached to the scenario.");
309                 }
310
311                 // Remove the scenario from the current hibernate session.
312                 ht.evict(aScenario);
313                 // Check that the scenario is created in the database.
314                 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
315                 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
316                 Assert.assertTrue(aScen.getDocums().size() > 0,
317                                 "No publications in the scenario.");
318
319                 Assert.assertTrue(i > 0,
320                                 "More then one document must be in the database");
321
322                 // Check created uses relations
323                 Assert
324                                 .assertTrue(usedMap.size() > 0,
325                                                 "Uses relations must be created.");
326                 boolean foundAny = false;
327                 for (Long usingId : usedMap.keySet()) {
328                         for (Publication pub : aScen.getDocums()) {
329                                 if (pub.getIndex() == usingId) {
330                                         boolean found = false;
331                                         for (Publication used : aScen.getDocums()) {
332                                                 found = (used.getIndex() == usedMap.get(usingId));
333                                                 if (found) {
334                                                         break;
335                                                 }
336                                         }
337                                         if (!found) {
338                                                 for (Publication used : aStudy.getDocums()) {
339                                                         found = (used.getIndex() == usedMap.get(usingId));
340                                                         if (found) {
341                                                                 break;
342                                                         }
343                                                 }
344                                         }
345                                         Assert.assertTrue(found,
346                                                         "Uses relation was not created in the database.");
347                                         foundAny = foundAny || found;
348                                 }
349                         }
350                 }
351                 Assert.assertTrue(foundAny,
352                                 "No Uses relation was created in the database.");
353
354                 return aScenario.getOwnerStudy();
355         }
356
357         /**
358          * Create a document published in the scenario. <BR>
359          * document:<BR>
360          * document type - type used on the step <BR>
361          * &lt;source-file&gt;.brep <BR>
362          * &lt;attached-file&gt;.med
363          * 
364          * @param aScenario
365          *            the scenario to add the document to
366          * @param aScStep
367          *            scenario step where the document to be published
368          * @param dprop
369          *            document properties
370          * @param attachedFileExt
371          *            extension of the secon attached (exported) file
372          * @param isOutdated
373          *            outdated document flag
374          * @return the publication of the created document
375          * @throws IOException
376          * @throws MultiplyDefinedException
377          * @throws InvalidPropertyException
378          * @throws MissedPropertyException
379          */
380         private Publication createDoc(final ProjectElement aScenario,
381                         final org.splat.som.Step aScStep, final Properties dprop,
382                         final String attachedFileExt, final boolean isOutdated)
383                         throws MissedPropertyException, InvalidPropertyException,
384                         MultiplyDefinedException, IOException {
385                 // Create a document published in the scenario
386                 // document<i>: document type - type used on the step
387                 // <source-file>.brep
388                 // <attached-file>.med
389                 Publication pub = _stepService.createDocument(aScStep, dprop);
390                 Assert.assertNotNull(pub.getOwner(),
391                                 "The publication must be attached to the scenario.");
392                 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
393                                 "The publication was not attached to the scenario.");
394
395                 if (isOutdated) {
396                         pub.setIsnew('O');
397                 }
398                 aScenario.add(pub);
399                 HibernateTemplate ht = getHibernateTemplate();
400                 ht.saveOrUpdate(pub);
401
402                 // Attach a file
403                 ht.save(pub.value());
404                 ht.flush();
405                 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
406
407                 return pub;
408         }
409
410         /**
411          * Test of generating a study document index.<BR>
412          * <B>Description :</B> <BR>
413          * <i>Create a study and try to generate the next document index.</i><BR>
414          * <B>Action : </B><BR>
415          * <i>1. call DAO's read method for an existing id.</i><BR>
416          * <B>Test data : </B><BR>
417          * <i>no input parameters</i><BR>
418          * 
419          * <B>Outcome results:</B><BR>
420          * <i>
421          * <ul>
422          * <li>The new index must be equal to the incremented old one and saved into the database<BR>
423          * </li>
424          * </ul>
425          * </i>
426          * 
427          * @throws InvalidPropertyException
428          *             if an invalid property is used when creating objects
429          * @throws MultiplyDefinedException
430          *             when trying to create an object with already existing id
431          * @throws MissedPropertyException
432          *             if a mandatory property is not defined for an object to be created
433          * @throws SQLException
434          *             if test study creation is failed
435          * @throws IOException
436          *             if test study creation is failed
437          * 
438          */
439         @Test
440         public void testGenerateLocalIndex() throws InvalidPropertyException,
441                         MissedPropertyException, MultiplyDefinedException, IOException,
442                         SQLException {
443                 LOG.debug(">>>>> BEGIN testGenerateLocalIndex()");
444                 startNestedTransaction();
445
446                 HibernateTemplate ht = getHibernateTemplate();
447                 Study aStudy = createStudy();
448                 // Call DAO's create method for a good transient study.
449                 Long id = aStudy.getIndex();
450                 Assert.assertNotNull(id,
451                                 "Create method returns null instead of a new id.");
452                 Assert.assertTrue(id > 0, "The new id is not a positive number.");
453
454                 // Call DAO's get method for an existing id.
455                 _studyDAO.flush();
456                 getHibernateTemplate().evict(aStudy);
457                 getHibernateTemplate().clear();
458                 Study aStudyFound = _studyDAO.get(id);
459
460                 int oldInd = aStudyFound.getLastLocalIndex();
461                 int ind = _studyService.generateLocalIndex(aStudyFound);
462
463                 _studyDAO.flush();
464                 Assert.assertEquals(ind, oldInd + 1, "Index must be incremented.");
465                 Assert.assertEquals(ind, aStudyFound.getLastLocalIndex(),
466                                 "Index must be incremented.");
467                 Assert.assertEquals(ind, ht.get(Study.class, aStudyFound.getIndex())
468                                 .getLastLocalIndex(),
469                                 "Incremented index must be saved in the database.");
470                 aStudy = (Study) ht.find(
471                                 "from Study where rid = " + aStudyFound.getIndex()).get(0);
472                 Assert.assertEquals(ind, aStudy.getLastLocalIndex(),
473                                 "Incremented index must be saved in the database.");
474
475                 rollbackNestedTransaction();
476                 LOG.debug(">>>>> END testGenerateLocalIndex()");
477         }
478
479         /**
480          * Test of retrieval of a study description.
481          * 
482          * @throws BusinessException
483          *             if there is something wrong likely unrelated to the tested method
484          */
485         @Test
486         public void testGetDescription() throws BusinessException {
487                 LOG.debug(">>>>> BEGIN testGetDescription()");
488                 startNestedTransaction();
489
490                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
491                 _userDAO.create(user);
492                 Study study = TestEntitiesGenerator.getTestStudy(user);
493                 _studyDAO.create(study);
494                 _studyDAO.flush();
495                 Long studyId = Long.valueOf(study.getIndex());
496
497                 // Empty description:
498                 Assert.assertNull(_studyService.getDescription(studyId),
499                                 "returned value for study without description must be null");
500
501                 // Not empty description:
502                 study.setAttribute(new DescriptionAttribute(study, "description"));
503                 _studyDAO.update(study);
504                 _studyDAO.flush();
505                 Assert.assertEquals("description", _studyService
506                                 .getDescription(studyId));
507
508                 // null id
509                 try {
510                         _studyService.getDescription(null);
511                         Assert.fail("retrieval with null study id must fail");
512                 } catch (InvalidParameterException e) {
513                         LOG.debug("Expected exception is thrown: "
514                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
515                 }
516
517                 // Non-existing id
518                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
519                 _studyDAO.create(tmpStudy);
520                 Long nonExistingId = tmpStudy.getIndex();
521                 _studyDAO.delete(tmpStudy);
522                 try {
523                         _studyService.getDescription(nonExistingId);
524                         Assert.fail("retrieval with non-existing study id must fail");
525                 } catch (InvalidParameterException e) {
526                         LOG.debug("Expected exception is thrown: "
527                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
528                 }
529
530                 rollbackNestedTransaction();
531                 LOG.debug(">>>>> END testGetDescription()");
532         }
533
534         /**
535          * Test of setting of a study description.
536          * 
537          * @throws BusinessException
538          *             if there is something wrong likely unrelated to the tested method
539          */
540         @Test
541         public void testSetDescription() throws BusinessException {
542                 LOG.debug(">>>>> BEGIN testSetDescription()");
543                 startNestedTransaction();
544
545                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
546                 _userDAO.create(user);
547                 Study study = TestEntitiesGenerator.getTestStudy(user);
548                 _studyDAO.create(study);
549                 _studyDAO.flush();
550                 Long studyId = Long.valueOf(study.getIndex());
551
552                 // Setting description for study without any
553                 _studyService.setDescription(studyId, "description");
554
555                 // Resetting description
556                 _studyService.setDescription(studyId, "replaced description");
557
558                 // null id
559                 try {
560                         _studyService.setDescription(null, "description");
561                         Assert.fail("setting with null study id must fail");
562                 } catch (InvalidParameterException e) {
563                         LOG.debug("Expected exception is thrown: "
564                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
565                 }
566
567                 // Non-existing id
568                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
569                 _studyDAO.create(tmpStudy);
570                 Long nonExistingId = tmpStudy.getIndex();
571                 _studyDAO.delete(tmpStudy);
572
573                 try {
574                         _studyService.setDescription(nonExistingId, "description");
575                         Assert.fail("retrieval with non-existing study id must fail");
576                 } catch (InvalidParameterException e) {
577                         LOG.debug("Expected exception is thrown: "
578                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
579                 }
580
581                 rollbackNestedTransaction();
582                 LOG.debug(">>>>> END testSetDescription()");
583         }
584
585         /**
586          * Test of removal of a study description.
587          * 
588          * @throws BusinessException
589          *             if there is something wrong likely unrelated to the tested method
590          */
591         @Test
592         public void testRemoveDescription() throws BusinessException {
593                 LOG.debug(">>>>> BEGIN testRemoveDescription()");
594                 startNestedTransaction();
595
596                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
597                 _userDAO.create(user);
598                 Study study = TestEntitiesGenerator.getTestStudy(user);
599                 _studyDAO.create(study);
600                 _studyDAO.flush();
601                 Long studyId = Long.valueOf(study.getIndex());
602
603                 // Empty description:
604                 Assert.assertFalse(_studyService.removeDescription(studyId),
605                                 "returned value for study without description must be null");
606
607                 // Not empty description:
608                 study.setAttribute(new DescriptionAttribute(study, "description"));
609                 _studyDAO.update(study);
610                 _studyDAO.flush();
611                 Assert.assertTrue(_studyService.removeDescription(studyId),
612                                 "existing description removal must return true");
613
614                 Assert.assertNull(_studyService.getDescription(studyId),
615                                 "description hasn't been successfully removed");
616
617                 // null id
618                 try {
619                         _studyService.removeDescription(null);
620                         Assert.fail("removal with null study id must fail");
621                 } catch (InvalidParameterException e) {
622                         LOG.debug("Expected exception is thrown: "
623                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
624                 }
625
626                 // Non-existing id
627                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
628                 _studyDAO.create(tmpStudy);
629                 Long nonExistingId = tmpStudy.getIndex();
630                 _studyDAO.delete(tmpStudy);
631                 try {
632                         _studyService.removeDescription(nonExistingId);
633                         Assert.fail("removal with non-existing study id must fail");
634                 } catch (InvalidParameterException e) {
635                         LOG.debug("Expected exception is thrown: "
636                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
637                 }
638
639                 rollbackNestedTransaction();
640                 LOG.debug(">>>>> END testGetDescription()");
641         }
642
643         /**
644          * Test study removal.<BR>
645          * <B>Description :</B> <BR>
646          * <i>Delete a study.</i><BR>
647          * <B>Action : </B><BR>
648          * <i>1. call the method for a not existing study id expecting an exception.</i><BR>
649          * <i>2. call the method for an existing study id.</i><BR>
650          * <B>Test data : </B><BR>
651          * <i>no input parameters</i><BR>
652          * 
653          * <B>Outcome results:</B><BR>
654          * <i>
655          * <ul>
656          * <li>1: Exception must be thrown.</li>
657          * <li>2: The study and all its objects must be removed.</li>
658          * </ul>
659          * </i>
660          * 
661          * @throws BusinessException
662          *             if test data creation is failed
663          * @throws IOException
664          *             if document creation is failed
665          */
666         @Test
667         public void testRemoveStudy() throws BusinessException, IOException {
668                 LOG.debug(">>>>> BEGIN testRemoveStudy()");
669                 startNestedTransaction();
670
671                 HibernateTemplate ht = getHibernateTemplate();
672
673                 Database.getInstance().reset();
674                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
675                 // Load workflow customization
676                 try {
677                         _projectSettings.configure("classpath:test/som.xml");
678                 } catch (Exception e) {
679                         Assert.fail("Can't load som.xml: ", e);
680                 }
681
682                 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
683                 _userDAO.create(goodUser);
684                 User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
685                 _userDAO.create(otherUser);
686                 User thirdUser = TestEntitiesGenerator.getTestUser("thirdUser");
687                 _userDAO.create(thirdUser);
688                 KnowledgeElementType ktype1 = new KnowledgeElementType("testKType1");
689                 KnowledgeElementType ktype2 = new KnowledgeElementType("testKType2");
690                 ktype2.setState(ProgressState.inWORK);
691                 _knowledgeElementTypeDAO.create(ktype1);
692                 _knowledgeElementTypeDAO.create(ktype2);
693
694                 // Create private study
695                 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
696                 aStudy.setTitle("0.This is private study");
697                 Long studyId = _studyDAO.create(aStudy);
698
699                 // Add simulation context to the study
700                 SimulationContext.Properties cprop = new SimulationContext.Properties();
701                 cprop.setType(_simulationContextService.selectType("product"))
702                                 .setValue("Test Simulation Context: Product");
703                 _studyService.addProjectContext(aStudy, cprop);
704                 ht.flush();
705
706                 // Add a scenario to the study
707                 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
708                 _scenarioDAO.create(scen);
709                 ht.flush();
710
711                 // Add knowledge elements to the scenario
712                 KnowledgeElement kelm01 = TestEntitiesGenerator
713                                 .getTestKnowledgeElement(scen, ktype1, "TestKelm01 title");
714                 KnowledgeElement kelm02 = TestEntitiesGenerator
715                                 .getTestKnowledgeElement(scen, ktype2, "TestKelm02 title");
716                 _knowledgeElementDAO.create(kelm01);
717                 _knowledgeElementDAO.create(kelm02);
718                 ht.flush();
719
720                 // Add contributor relation
721                 aStudy.addRelation(new ContributorRelation(aStudy, otherUser));
722                 ht.flush();
723
724                 // Add a validation cycle with otherUser as a reviewer
725                 ValidationCycle.Properties vprop = new ValidationCycle.Properties();
726                 DocumentType dtype = _documentTypeService.selectType("minutes");
727                 vprop.setDocumentType(dtype);
728                 vprop.setActor(ValidationStep.REVIEW, otherUser);
729                 ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
730                 _validationCycleDAO.create(cycle);
731                 ValidationCycleRelation link = cycle.getContext();
732                 aStudy.addRelation(link);
733                 ht.flush();
734
735                 // Add documents to the first study activity
736                 // Add a converts relations
737                 Publication pub1 = addDoc(aStudy, "document1", dtype);
738                 Publication pub2 = addDoc(aStudy, "document2", dtype);
739                 Publication pub3 = addDoc(aStudy, "document3", dtype);
740                 ht.flush();
741
742                 LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
743                                 + pub1.value().getReference() + "]" + " ["
744                                 + pub1.value().getRid() + "]");
745                 LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
746                                 + pub2.value().getReference() + "]" + " ["
747                                 + pub2.value().getRid() + "]");
748                 LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
749                                 + pub3.value().getReference() + "]" + " ["
750                                 + pub3.value().getRid() + "]");
751
752                 ht.update(aStudy);
753
754                 ht.flush();
755                 LOG.debug("Before versioning:");
756                 for (Publication doc : _projectElementService.getFirstStep(aStudy)
757                                 .getAllDocuments()) {
758                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
759                                         + doc.value().getReference() + "]" + " ["
760                                         + doc.value().getRid() + "]");
761                 }
762                 // Add a version relations
763                 Publication pub31 = version(pub3);
764
765                 // _publicationService.versionDocument(_projectElementService
766                 // .getFirstStep(aStudy), goodUser, pub3
767                 // .getSourceFile().getName(), pub3.value().getIndex(), "",
768                 // "The new version", pub3.getProgressState(), new Date(), null,
769                 // null);
770
771                 // Publication pub31 = null;
772                 // for (Publication pub : aStudy.getDocums()) {
773                 // if (pub.value().getPreviousVersion() != null) {
774                 // pub31 = pub;
775                 // }
776                 // }
777
778                 LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
779                                 + pub31.value().getReference() + "]" + " ["
780                                 + pub31.value().getRid() + "]");
781                 ht.saveOrUpdate(aStudy);
782
783                 LOG.debug("After versioning:");
784                 for (Publication doc : aStudy.getDocums()) {
785                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
786                                         + doc.value().getReference() + "]" + " ["
787                                         + doc.value().getRid() + "]");
788                 }
789
790                 // Add documents to the first scenario activity
791                 Publication spub1 = addDoc(scen, "sdocument1", dtype);
792                 Publication spub2 = addDoc(scen, "sdocument2", dtype);
793                 Publication spub3 = addDoc(scen, "sdocument3", dtype);
794                 LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
795                                 + spub1.value().getReference() + "]" + " ["
796                                 + spub1.value().getRid() + "]");
797                 LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
798                                 + spub2.value().getReference() + "]" + " ["
799                                 + spub2.value().getRid() + "]");
800                 LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
801                                 + spub3.value().getReference() + "]" + " ["
802                                 + spub3.value().getRid() + "]");
803                 ht.flush();
804
805                 // Create a scenario document version
806                 Publication spub31 = version(spub3);
807                 LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
808                                 + spub31.value().getReference() + "]" + " ["
809                                 + spub31.value().getRid() + "]");
810
811                 // Add uses relations
812                 pub2.addDependency(pub1);
813                 ht.saveOrUpdate(pub2.value());
814                 pub3.addDependency(pub2);
815                 ht.saveOrUpdate(pub3.value());
816
817                 spub2.addDependency(pub1);
818                 spub2.addDependency(spub1);
819                 spub2.addDependency(pub2);
820                 spub2.addDependency(pub3);
821                 ht.saveOrUpdate(spub2.value());
822                 spub3.addDependency(spub2);
823                 ht.saveOrUpdate(spub3.value());
824                 spub31.addDependency(spub31);
825                 ht.saveOrUpdate(spub31.value());
826                 ht.flush();
827
828                 // /////////////////////////////////////////////////////////
829                 ht.clear();
830                 _studyService.removeStudy(studyId);
831                 ht.flush();
832
833                 // Check removal of the study
834                 Study foundStudy = ht.get(Study.class, studyId);
835                 Assert.assertNull(foundStudy);
836                 // Check removal of relations to validation cycle
837                 List found = ht.find("from ValidationCycleRelation where owner="
838                                 + studyId);
839                 Assert.assertEquals(found.size(), 0,
840                                 "ValidationCycleRelation is not removed");
841                 // Check removal of validation cycles
842                 found = ht.find("from ValidationCycle where rid=" + cycle.getIndex());
843                 Assert.assertEquals(found.size(), 0, "ValidationCycle is not removed");
844                 // Check removal of contributors relation
845                 found = ht.find("from ContributorRelation where owner=" + studyId);
846                 Assert.assertEquals(found.size(), 0,
847                                 "ContributorRelation is not removed");
848                 // Check that contributors are not removed
849                 User foundUser = ht.get(User.class, otherUser.getIndex());
850                 Assert.assertNotNull(foundUser);
851                 // Check removal of the scenario
852                 found = ht.find("from Scenario where owner=" + studyId);
853                 Assert.assertEquals(found.size(), 0, "Scenario is not removed");
854                 // Check removal of publications
855                 found = ht
856                                 .find("from Publication pub left join pub.owner as own where own.rid="
857                                                 + studyId + " or own.rid=" + scen.getIndex());
858                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
859                 found = ht.find("from Publication");
860                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
861                 // Check removal of documents
862                 found = ht.find("from Document");
863                 Assert.assertEquals(found.size(), 0, "Document is not removed");
864                 // Check removal of version relations
865                 found = ht.find("from VersionsRelation");
866                 Assert.assertEquals(found.size(), 0, "VersionsRelation is not removed");
867                 // Check removal of converts relations
868                 found = ht.find("from ConvertsRelation");
869                 Assert.assertEquals(found.size(), 0, "ConvertsRelation is not removed");
870                 // Check removal of files
871                 found = ht.find("from File");
872                 Assert.assertEquals(found.size(), 0, "File is not removed");
873                 // Check removal of uses relations
874                 found = ht.find("from UsesRelation");
875                 Assert.assertEquals(found.size(), 0, "UsesRelation is not removed");
876                 // Check removal of usedBy relations
877                 found = ht.find("from UsedByRelation");
878                 Assert.assertEquals(found.size(), 0, "UsedByRelation is not removed");
879
880                 rollbackNestedTransaction();
881                 LOG.debug(">>>>> END testRemoveStudy()");
882         }
883
884         /**
885          * Create a new version of the document.
886          * 
887          * @param pub
888          *            the current document publication
889          * @return the new document version publication
890          * @throws IOException
891          *             if versioning is failed
892          * @throws BusinessException
893          *             if versioning is failed
894          */
895         private Publication version(final Publication pub)
896                         throws BusinessException, IOException {
897                 Document.Properties dprop = new Document.Properties();
898                 dprop.setDocument(pub.value(), pub.getStep().getStep());
899                 Publication newpub = _stepService.versionDocument(pub.getStep(), pub,
900                                 dprop);
901                 pub.getOwner().getDocums().remove(pub);
902                 pub.getStep().getDocuments().remove(pub);
903                 pub.getOwner().add(newpub);
904                 pub.getStep().getDocuments().add(newpub);
905                 return newpub;
906         }
907
908         /**
909          * Create a document and publish it in the project element.
910          * 
911          * @param aStudy
912          *            the project element
913          * @param stStep
914          * @param docname
915          *            document name
916          * @param dtype
917          *            document type
918          * @return publication of the created document
919          * @throws BusinessException
920          *             if document creation is failed
921          * @throws IOException
922          *             if file creation is failed
923          */
924         private Publication addDoc(final ProjectElement aStudy,
925                         final String docname, final DocumentType dtype)
926                         throws BusinessException, IOException {
927                 HibernateTemplate ht = getHibernateTemplate();
928                 // Add documents to the first study activity
929                 org.splat.som.Step aStep = _projectElementService.getFirstStep(aStudy);
930                 Document.Properties dprop = new Document.Properties().setAuthor(
931                                 aStudy.getAuthor()).setDate(new Date()).setName(docname)
932                                 .setType(dtype).setFormat("py");
933                 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
934                 dprop.setStep(aStep.getStep());
935                 Publication pub = _stepService.createDocument(aStep, dprop);
936                 pub.setStep(aStep);
937                 aStudy.add(pub);
938                 aStep.getDocuments().add(pub);
939                 ht.saveOrUpdate(pub);
940                 ht.save(pub.value());
941                 // Add a converts relation
942                 // Attach a med file
943                 ht.saveOrUpdate(_publicationService.attach(pub, "med"));
944                 createDownloadedFile(aStudy.getAuthor().getIndex(), dprop
945                                 .getLocalPath());
946                 createDownloadedFile(aStudy.getAuthor().getIndex(), dprop
947                                 .getLocalPath().substring(0,
948                                                 dprop.getLocalPath().lastIndexOf(".") - 1), "med");
949                 return pub;
950         }
951
952         /**
953          * Create a file in the user's repository downloads directory.
954          * 
955          * @param userId
956          *            user id
957          * @param name
958          *            file name
959          * @param format
960          *            file extension
961          * @return created file DTO
962          * @throws IOException
963          *             if file creation failed
964          */
965         private FileDTO createDownloadedFile(final long userId, final String name,
966                         final String format) throws IOException {
967                 // Create a file in the download directory
968                 return createDownloadedFile(userId, name + "." + format);
969         }
970
971         /**
972          * Get path to the user's downloads directory. The directory is created if it is not exist yet.
973          * 
974          * @param userId
975          *            user id
976          * @return absolute path to downloads directory followed by slash
977          */
978         private String getDownloadPath(final long userId) {
979                 // Prepare download directory
980                 File tmpDir = _repositoryService.getDownloadDirectory(userId);
981                 if (!tmpDir.exists()) {
982                         Assert.assertTrue(tmpDir.mkdir(),
983                                         "Can't create temporary directory: "
984                                                         + tmpDir.getAbsolutePath());
985                 }
986
987                 return tmpDir.getAbsolutePath() + "/";
988         }
989
990         /**
991          * Create a file in the user's repository downloads directory.
992          * 
993          * @param userId
994          *            user id
995          * @param fname
996          *            file name
997          * @return created file DTO
998          * @throws IOException
999          *             if file creation failed
1000          */
1001         private FileDTO createDownloadedFile(final long userId, final String fname)
1002                         throws IOException {
1003                 // Create a file in the download directory
1004                 String filePath = getDownloadPath(userId) + fname;
1005                 FileWriter fw = new FileWriter(filePath);
1006                 fw.write("Simulation of " + fname + " file for checkin at "
1007                                 + new Date());
1008                 fw.close();
1009                 return new FileDTO(filePath);
1010         }
1011 }