1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
9 package test.splat.service;
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.sql.SQLException;
14 import java.util.ArrayList;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.List;
20 import org.splat.dal.bo.kernel.User;
21 import org.splat.dal.bo.som.Document;
22 import org.splat.dal.bo.som.DocumentType;
23 import org.splat.dal.bo.som.ProjectElement;
24 import org.splat.dal.bo.som.Publication;
25 import org.splat.dal.bo.som.Scenario;
26 import org.splat.dal.bo.som.Study;
27 import org.splat.dal.bo.som.UsedByRelation;
28 import org.splat.dal.bo.som.UsesRelation;
29 import org.splat.dal.bo.som.Document.Properties;
30 import org.splat.dal.dao.som.Database;
31 import org.splat.dal.dao.som.ScenarioDAO;
32 import org.splat.exception.BusinessException;
33 import org.splat.exception.DocumentIsUsedException;
34 import org.splat.kernel.InvalidPropertyException;
35 import org.splat.kernel.MissedPropertyException;
36 import org.splat.kernel.MultiplyDefinedException;
37 import org.splat.log.AppLogger;
38 import org.splat.service.DocumentTypeService;
39 import org.splat.service.PublicationService;
40 import org.splat.service.StepService;
41 import org.splat.service.StudyService;
42 import org.splat.service.technical.ProjectSettingsService;
43 import org.splat.service.technical.ProjectSettingsService.Step;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.beans.factory.annotation.Qualifier;
46 import org.springframework.orm.hibernate3.HibernateTemplate;
47 import org.testng.Assert;
48 import org.testng.annotations.Test;
50 import test.splat.common.BaseTest;
53 * Test class for StepService.
55 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
58 public class TestStepService extends BaseTest {
61 * Logger for the class.
63 private static final AppLogger LOG = AppLogger
64 .getLogger(TestStepService.class);
67 * The StudyService. Later injected by Spring.
70 @Qualifier("studyService")
71 private transient StudyService _studyService;
74 * The Scenario DAO. Later injected by Spring.
77 @Qualifier("scenarioDAO")
78 private transient ScenarioDAO _scenarioDAO;
81 * The PublicationService. Later injected by Spring.
84 @Qualifier("publicationService")
85 private transient PublicationService _publicationService;
88 * The StepService. Later injected by Spring.
91 @Qualifier("stepService")
92 private transient StepService _stepService;
95 * The ProjectSettingsService. Later injected by Spring.
98 @Qualifier("projectSettings")
99 private transient ProjectSettingsService _projectSettings;
102 * The DocumentTypeService. Later injected by Spring.
105 @Qualifier("documentTypeService")
106 private transient DocumentTypeService _documentTypeService;
109 * Test removeDocument method.<BR>
110 * <B>Description :</B> <BR>
111 * <i>Create a scenario and try to remove documents from it.<BR>
113 * <B>Action : </B><BR>
114 * <i>1. call the method for all documents used by other document(s).</i><BR>
115 * <i>2. call the method for all documents starting from the last activity.</i><BR>
116 * <B>Test data : </B><BR>
117 * <i>no input parameters</i><BR>
118 * <i>no input parameters</i><BR>
120 * <B>Outcome results:</B><BR>
123 * <li>Exception DocumentIsUsedException is expected<BR>
125 * <li>All documents and their files and relations must be removed<BR>
130 * @throws BusinessException
131 * if scenario creation or checkin is failed
132 * @throws IOException
133 * if scenario creation is failed
134 * @throws SQLException
135 * if scenario creation is failed
138 public void testRemoveDocument() throws BusinessException, IOException,
140 LOG.debug(">>>>> BEGIN testRemoveDocument()");
141 startNestedTransaction();
143 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
144 _projectSettings.configure(ClassLoader
145 .getSystemResource("test/som.xml").getPath());
146 HibernateTemplate ht = getHibernateTemplate();
148 long scenarioId = createScenario();
150 _scenarioDAO.flush();
151 Scenario aScen = _scenarioDAO.get(scenarioId);
154 ht.evict(aScen.getOwnerStudy());
156 Assert.assertTrue(ht.find("from UsesRelation").size() > 0,
157 "Uses relations were not created in the database.");
159 Assert.assertTrue(ht.find("from UsedByRelation").size() > 0,
160 "UsedBy relations were not created in the database.");
162 ProjectElement projElem;
166 int nbDoc = ht.find("from Document").size();
167 int nbRemovedDoc = 0;
168 List<Long> removedDocs = new ArrayList<Long>();
170 // ////////////////////////////////////////////////////////
171 // Call removeDocument method for each document
172 // used by other document(s).
173 // Exception DocumentIsUsedException is expected
174 for (int i = 1; i <= _projectSettings.getAllSteps().size(); i++) {
175 LOG.debug("Remove used documents from the step " + i);
176 step = _projectSettings.getStep(i);
177 if (step.appliesTo(Study.class)) {
178 projElem = _studyService.selectStudy(aScen.getOwnerStudy()
184 org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
186 if (aScStep.getDocuments().size() > 0) {
187 docId = aScStep.getDocuments().get(0).value().getIndex();
189 List<UsesRelation> uses = ht
190 .find("from UsesRelation where owner=" + docId);
191 List<UsedByRelation> usedBy = ht
192 .find("from UsedByRelation where owner=" + docId);
193 if (!usedBy.isEmpty()) {
194 int usesRefer = ht.find(
195 "from UsesRelation where refer=" + docId).size();
196 int usedByRefer = ht.find(
197 "from UsedByRelation where refer=" + docId).size();
198 int convertsNb = ht.find(
199 "from ConvertsRelation where owner=" + docId)
201 LOG.debug("Remove used document "
202 + aScStep.getDocument(docId).value().getTitle());
203 LOG.debug("From db: It uses following " + uses.size()
205 for (UsesRelation rel : uses) {
206 LOG.debug(rel.getTo().getTitle());
209 .debug("From step: It uses following "
210 + aScStep.getDocument(docId).value()
211 .getRelations(UsesRelation.class)
212 .size() + " documents: ");
213 for (Publication rel : aScStep.getDocument(docId)
214 .getRelations(UsesRelation.class)) {
215 LOG.debug(rel.value().getTitle());
217 LOG.debug("From db: It is used by following "
218 + usedBy.size() + " documents: ");
219 for (UsedByRelation rel : usedBy) {
220 LOG.debug(rel.getTo().getTitle());
222 LOG.debug("From step: It is used by following "
223 + aScStep.getDocument(docId).value().getRelations(
224 UsedByRelation.class).size()
226 for (Publication rel : aScStep.getDocument(docId)
227 .getRelations(UsedByRelation.class)) {
228 LOG.debug(rel.value().getTitle());
231 ok = _stepService.removeDocument(aScStep, docId);
232 Assert.fail("DocumentIsUsedException must be thrown.");
233 } catch (DocumentIsUsedException e) {
234 LOG.debug("Expected exception is thrown: "
235 + e.getLocalizedMessage());
237 _scenarioDAO.flush();
240 .assertEquals(ht.find(
241 "from UsesRelation where owner=" + docId)
242 .size(), uses.size(),
243 "UsesRelation(s) must not be changed.");
244 Assert.assertEquals(ht.find(
245 "from UsedByRelation where owner=" + docId).size(),
247 "UsedByRelation(s) must not be changed.");
248 Assert.assertEquals(ht.find(
249 "from UsesRelation where refer=" + docId).size(),
251 "Referencing UsesRelation(s) must not be changed.");
253 .assertEquals(ht.find(
254 "from UsedByRelation where refer=" + docId)
255 .size(), usedByRefer,
256 "Referencing UsedByRelation(s) must not be changed.");
257 Assert.assertEquals(ht.find(
258 "from ConvertsRelation where owner=" + docId)
260 "ConvertsRelation(s) must not be changed.");
265 // ////////////////////////////////////////////////////////
266 // Call removeDocument method for each document
267 // starting from the last activity.
268 for (int i = _projectSettings.getAllSteps().size(); i > 0; i--) {
269 LOG.debug("Remove documents from the step " + i);
270 step = _projectSettings.getStep(i);
271 if (step.appliesTo(Study.class)) {
272 projElem = _studyService.selectStudy(aScen.getOwnerStudy()
278 org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
280 if (aScStep.getDocuments().size() > 0) {
281 docId = aScStep.getDocuments().get(0).value().getIndex();
282 LOG.debug("Remove document#" + docId + " "
283 + aScStep.getDocument(docId).value().getTitle());
285 List<UsesRelation> uses = ht
286 .find("from UsesRelation where owner=" + docId);
287 List<UsedByRelation> usedBy = ht
288 .find("from UsedByRelation where owner=" + docId);
289 LOG.debug("From db: It uses following " + uses.size()
291 for (UsesRelation rel : uses) {
292 LOG.debug(rel.getTo().getTitle());
294 LOG.debug("From step: It uses following "
295 + aScStep.getDocument(docId).getRelations(
296 UsesRelation.class).size() + " documents: ");
297 for (Publication rel : aScStep.getDocument(docId).getRelations(
298 UsesRelation.class)) {
299 LOG.debug(rel.value().getTitle());
301 LOG.debug("From db: It is used by following " + usedBy.size()
303 for (UsedByRelation rel : usedBy) {
304 LOG.debug(rel.getTo().getTitle());
306 LOG.debug("From step: It is used by following "
307 + aScStep.getDocument(docId).getRelations(
308 UsedByRelation.class).size() + " documents: ");
309 for (Publication rel : aScStep.getDocument(docId).getRelations(
310 UsedByRelation.class)) {
311 LOG.debug(rel.value().getTitle());
313 Assert.assertEquals(ht.find("from Document where rid=" + docId)
314 .size(), 1, "Nothing to delete.");
316 ok = _stepService.removeDocument(aScStep, docId);
319 removedDocs.add(docId);
321 Assert.assertTrue(ok, "Removing was failed.");
322 _scenarioDAO.flush();
325 for (Long id : removedDocs) {
327 if (ht.get(Document.class, id) != null) {
328 title = ht.get(Document.class, id).getTitle();
330 Assert.assertEquals(ht
331 .find("from Document where rid=" + id).size(), 0,
332 "Document#" + id + "(" + title
333 + ") was not removed from the database.");
336 Assert.assertEquals(ht.find("from Document").size(), nbDoc
338 "Documents were not removed from the database.");
339 Assert.assertEquals(ht.find(
340 "from UsesRelation where owner=" + docId).size(), 0,
341 "UsesRelation(s) were not removed from the database.");
343 .assertEquals(ht.find(
344 "from UsedByRelation where owner=" + docId)
346 "UsedByRelation(s) were not removed from the database.");
348 .assertEquals(ht.find(
349 "from UsesRelation where refer=" + docId)
351 "Referencing UsesRelation(s) were not removed from the database.");
353 .assertEquals(ht.find(
354 "from UsedByRelation where refer=" + docId)
356 "Referencing UsedByRelation(s) were not removed from the database.");
358 .assertEquals(ht.find(
359 "from ConvertsRelation where owner=" + docId)
361 "ConvertsRelation(s) were not removed from the database.");
366 .assertEquals(ht.find("from Document").size(), nbDoc
368 "Documents were not removed from the database.");
371 .assertEquals(ht.find("from File").size(), 0,
372 "Files were not removed from the database.");
374 Assert.assertEquals(ht.find(
375 "from Publication where owner=" + aScen.getIndex()).size(), 0,
376 "Publications were not removed from the database.");
378 Assert.assertEquals(ht.find("from UsesRelation").size(), 0,
379 "Uses relations were not removed from the database.");
381 Assert.assertEquals(ht.find("from UsedByRelation").size(), 0,
382 "UsedBy relations were not removed from the database.");
384 rollbackNestedTransaction();
385 LOG.debug(">>>>> END testRemoveDocument()");
389 * Create a persistent scenario for tests.
391 * @return a persistent scenario
392 * @throws InvalidPropertyException
393 * if an invalid property is used when creating objects
394 * @throws MultiplyDefinedException
395 * when trying to create an object with already existing id
396 * @throws MissedPropertyException
397 * if a mandatory property is not defined for an object to be created
398 * @throws IOException
399 * if document creation is failed
400 * @throws SQLException
401 * if project settings loading is failed
403 private long createScenario() throws InvalidPropertyException,
404 MissedPropertyException, MultiplyDefinedException, IOException,
406 // Create a scenario for tests
407 HibernateTemplate ht = getHibernateTemplate();
409 Database.getInstance().reset();
410 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
411 // Load workflow customization
413 _projectSettings.configure(ClassLoader.getSystemResource(
414 "test/som.xml").getPath());
415 } catch (FileNotFoundException e) {
416 Assert.fail("Can't find som.xml: ", e);
418 List<Step> steps = _projectSettings.getAllSteps();
419 Assert.assertTrue(steps.size() > 0, "No steps are created.");
421 // Create a test user
422 User.Properties uprop = new User.Properties();
423 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
424 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
425 .addRole("TST_user").setMailAddress(
426 "noreply@salome-platform.org");
427 uprop.disableCheck();
428 User anAuthor = new User(uprop);
429 ht.saveOrUpdate(anAuthor);
431 // Create a test study
432 Study.Properties stprops = new Study.Properties().setReference(
433 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
434 Study aStudy = new Study(stprops);
435 ht.saveOrUpdate(aStudy);
437 // Create a test scenario
438 Scenario.Properties sprops = new Scenario.Properties().setTitle(
439 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
440 Scenario aScenario = new Scenario(sprops);
441 aStudy.getScenariiList().add(aScenario);
442 ht.saveOrUpdate(anAuthor);
443 ht.saveOrUpdate(aStudy);
444 ht.saveOrUpdate(aScenario);
446 // Create documents for each scenario step
447 Document.Properties dprop = new Document.Properties().setAuthor(
448 anAuthor).setDate(new Date());
450 Publication usedPub = null;
451 Map<Long, Long> usedMap = new HashMap<Long, Long>();
452 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
453 Step step = _projectSettings.getStep(stepNum);
454 LOG.debug("Create scenario step: " + stepNum);
455 ProjectElement projElem;
457 if (step.appliesTo(Study.class)) {
460 projElem = aScenario;
462 org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
463 List<DocumentType> dtypes = _documentTypeService
464 .selectTypesOf(step);
465 if (dtypes.size() > 0) {
466 DocumentType dtype = dtypes.get(0);
467 // Create a document published in the scenario
468 // document<i>: document type[0] - first type used on the step
469 // <source-file>.brep
470 // <attached-file>.med
472 dprop.setName("document" + stepNum).setType(dtype);
473 if (step.getNumber() > 3) {
474 dprop.setFormat("med");
476 dprop.setFormat("py");
478 Publication pub = createDoc(projElem, aScStep, dprop, "med",
480 if (usedPub != null) {
481 pub.addDependency(usedPub);
482 LOG.debug("Add dependency: " + pub.value().getTitle()
483 + " from " + usedPub.value().getTitle());
484 ht.saveOrUpdate(pub.value());
487 usedMap.put(pub.getIndex(), usedPub.getIndex());
491 if (dtypes.size() <= 0) {
492 LOG.debug("No document types are found for scenario step " + i);
496 // Check that the scenario and its documents have been created correctly.
498 Assert.assertNotNull(ht.find("from Document"),
499 "No documents in the database.");
500 Assert.assertTrue(ht.find("from Document").size() > 0,
501 "No documents in the database.");
503 Assert.assertNotNull(ht.find("from Publication where owner="
504 + aScenario.getIndex()), "No publications in the database.");
506 ht.find("from Publication where owner=" + aScenario.getIndex())
507 .size() > 0, "No publications in the database.");
509 for (Publication p : (List<Publication>) ht
510 .find("from Publication where owner=" + aScenario.getIndex())) {
511 LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
512 + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
514 Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
515 "The publication was not attached to the scenario.");
518 // Remove the scenario from the current hibernate session.
520 // Check that the scenario is created in the database.
521 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
522 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
523 Assert.assertTrue(aScen.getDocums().size() > 0,
524 "No publications in the scenario.");
526 Assert.assertTrue(i > 0,
527 "More then one document must be in the database");
529 // Check created uses relations
531 .assertTrue(usedMap.size() > 0,
532 "Uses relations must be created.");
533 boolean foundAny = false;
534 for (Long usingId : usedMap.keySet()) {
535 for (Publication pub : aScen.getDocums()) {
536 if (pub.getIndex() == usingId) {
537 boolean found = false;
538 for (Publication used : aScen.getDocums()) {
539 found = (used.getIndex() == usedMap.get(usingId));
545 for (Publication used : aStudy.getDocums()) {
546 found = (used.getIndex() == usedMap.get(usingId));
552 Assert.assertTrue(found,
553 "Uses relation was not created in the database.");
554 foundAny = foundAny || found;
558 Assert.assertTrue(foundAny,
559 "No Uses relation was created in the database.");
561 return aScenario.getIndex();
565 * Create a document published in the scenario. <BR>
567 * document type - type used on the step <BR>
568 * <source-file>.brep <BR>
569 * <attached-file>.med
572 * the scenario to add the document to
574 * scenario step where the document to be published
576 * document properties
577 * @param attachedFileExt
578 * extension of the secon attached (exported) file
580 * outdated document flag
581 * @return the publication of the created document
582 * @throws IOException
583 * @throws MultiplyDefinedException
584 * @throws InvalidPropertyException
585 * @throws MissedPropertyException
587 private Publication createDoc(final ProjectElement aScenario,
588 final org.splat.som.Step aScStep, final Properties dprop,
589 final String attachedFileExt, final boolean isOutdated)
590 throws MissedPropertyException, InvalidPropertyException,
591 MultiplyDefinedException, IOException {
592 // Create a document published in the scenario
593 // document<i>: document type - type used on the step
594 // <source-file>.brep
595 // <attached-file>.med
596 Publication pub = _stepService.createDocument(aScStep, dprop);
597 Assert.assertNotNull(pub.getOwner(),
598 "The publication must be attached to the scenario.");
599 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
600 "The publication was not attached to the scenario.");
606 HibernateTemplate ht = getHibernateTemplate();
607 ht.saveOrUpdate(pub);
610 ht.save(pub.value());
612 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));