1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
9 package test.splat.service;
12 import java.io.FileNotFoundException;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.sql.SQLException;
16 import java.text.ParseException;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Date;
20 import java.util.HashMap;
21 import java.util.List;
24 import org.splat.dal.bo.kernel.User;
25 import org.splat.dal.bo.som.Document;
26 import org.splat.dal.bo.som.DocumentType;
27 import org.splat.dal.bo.som.ProgressState;
28 import org.splat.dal.bo.som.ProjectElement;
29 import org.splat.dal.bo.som.Publication;
30 import org.splat.dal.bo.som.Scenario;
31 import org.splat.dal.bo.som.Study;
32 import org.splat.dal.bo.som.Document.Properties;
33 import org.splat.dal.dao.som.Database;
34 import org.splat.dal.dao.som.StudyDAO;
35 import org.splat.kernel.InvalidPropertyException;
36 import org.splat.kernel.MissedPropertyException;
37 import org.splat.kernel.MultiplyDefinedException;
38 import org.splat.kernel.NotApplicableException;
39 import org.splat.log.AppLogger;
40 import org.splat.service.DocumentTypeService;
41 import org.splat.service.ProjectElementService;
42 import org.splat.service.PublicationService;
43 import org.splat.service.StepService;
44 import org.splat.service.StudyService;
45 import org.splat.service.technical.ProjectSettingsService;
46 import org.splat.service.technical.RepositoryService;
47 import org.splat.service.technical.ProjectSettingsService.Step;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.beans.factory.annotation.Qualifier;
50 import org.springframework.orm.hibernate3.HibernateTemplate;
51 import org.testng.Assert;
52 import org.testng.annotations.Test;
54 import test.splat.common.BaseTest;
57 * Test class for PublicationService.
59 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
62 public class TestPublicationService extends BaseTest {
65 * Logger for the class.
67 private static final AppLogger LOG = AppLogger
68 .getLogger(TestPublicationService.class);
71 * The StudyDAO. Later injected by Spring.
74 @Qualifier("studyDAO")
75 private transient StudyDAO _studyDAO;
78 * The PublicationService. Later injected by Spring.
81 @Qualifier("publicationService")
82 private transient PublicationService _publicationService;
85 * The ProjectElementService. Later injected by Spring.
88 @Qualifier("projectElementService")
89 private transient ProjectElementService _projectElementService;
92 * The StepService. Later injected by Spring.
95 @Qualifier("stepService")
96 private transient StepService _stepService;
99 * The ProjectSettingsService. Later injected by Spring.
102 @Qualifier("projectSettings")
103 private transient ProjectSettingsService _projectSettings;
106 * The DocumentTypeService. Later injected by Spring.
109 @Qualifier("documentTypeService")
110 private transient DocumentTypeService _documentTypeService;
113 * The StudyService. Later injected by Spring.
116 @Qualifier("studyService")
117 private transient StudyService _studyService;
120 * The RepositoryService. Later injected by Spring.
123 @Qualifier("repositoryService")
124 private transient RepositoryService _repositoryService;
127 * Create a persistent scenario for tests.
129 * @return a persistent scenario
130 * @throws InvalidPropertyException
131 * if an invalid property is used when creating objects
132 * @throws MultiplyDefinedException
133 * when trying to create an object with already existing id
134 * @throws MissedPropertyException
135 * if a mandatory property is not defined for an object to be created
136 * @throws IOException
137 * if document creation is failed
138 * @throws SQLException
139 * if project settings loading is failed
141 private Study createStudy() throws InvalidPropertyException,
142 MissedPropertyException, MultiplyDefinedException, IOException,
144 // Create a scenario for tests
145 HibernateTemplate ht = getHibernateTemplate();
147 Database.getInstance().reset();
148 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
149 // Load workflow customization
151 _projectSettings.configure(ClassLoader.getSystemResource(
152 "test/som.xml").getPath());
153 } catch (FileNotFoundException e) {
154 Assert.fail("Can't find som.xml: ", e);
156 List<Step> steps = _projectSettings.getAllSteps();
157 Assert.assertTrue(steps.size() > 0, "No steps are created.");
159 // Create a test user
160 User.Properties uprop = new User.Properties();
161 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
162 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
163 .addRole("TST_user").setMailAddress(
164 "noreply@salome-platform.org");
165 uprop.disableCheck();
166 User anAuthor = new User(uprop);
167 ht.saveOrUpdate(anAuthor);
169 // Create a test study
170 Study.Properties stprops = new Study.Properties().setReference(
171 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
172 Study aStudy = new Study(stprops);
173 ht.saveOrUpdate(aStudy);
175 // Create a test scenario
176 Scenario.Properties sprops = new Scenario.Properties().setTitle(
177 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
178 Scenario aScenario = new Scenario(sprops);
179 aStudy.getScenariiList().add(aScenario);
180 ht.saveOrUpdate(anAuthor);
181 ht.saveOrUpdate(aStudy);
182 ht.saveOrUpdate(aScenario);
184 // Create documents for each scenario step
185 Document.Properties dprop = new Document.Properties().setAuthor(
186 anAuthor).setDate(new Date());
188 Publication usedPub = null;
189 Map<Long, Long> usedMap = new HashMap<Long, Long>();
190 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
191 Step step = _projectSettings.getStep(stepNum);
192 LOG.debug("Create scenario step: " + stepNum);
193 ProjectElement projElem;
195 if (step.appliesTo(Study.class)) {
198 projElem = aScenario;
200 org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
201 List<DocumentType> dtypes = _documentTypeService
202 .selectTypesOf(step);
203 if (dtypes.size() > 0) {
204 DocumentType dtype = dtypes.get(0);
205 // Create a document published in the scenario
206 // document<i>: document type[0] - first type used on the step
207 // <source-file>.brep
208 // <attached-file>.med
210 dprop.setName("document" + stepNum).setType(dtype);
211 if (step.getNumber() > 3) {
212 dprop.setFormat("med");
214 dprop.setFormat("py");
216 Publication pub = createDoc(projElem, aScStep, dprop, "med",
218 if (usedPub != null) {
219 pub.addDependency(usedPub);
220 LOG.debug("Add dependency: " + pub.value().getTitle()
221 + " from " + usedPub.value().getTitle());
222 ht.saveOrUpdate(pub.value());
225 usedMap.put(pub.getIndex(), usedPub.getIndex());
229 if (dtypes.size() <= 0) {
230 LOG.debug("No document types are found for scenario step " + i);
234 // Check that the scenario and its documents have been created correctly.
236 Assert.assertNotNull(ht.find("from Document"),
237 "No documents in the database.");
238 Assert.assertTrue(ht.find("from Document").size() > 0,
239 "No documents in the database.");
241 Assert.assertNotNull(ht.find("from Publication where owner="
242 + aScenario.getIndex()), "No publications in the database.");
244 ht.find("from Publication where owner=" + aScenario.getIndex())
245 .size() > 0, "No publications in the database.");
247 for (Publication p : (List<Publication>) ht
248 .find("from Publication where owner=" + aScenario.getIndex())) {
249 LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
250 + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
252 Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
253 "The publication was not attached to the scenario.");
256 // Remove the scenario from the current hibernate session.
258 // Check that the scenario is created in the database.
259 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
260 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
261 Assert.assertTrue(aScen.getDocums().size() > 0,
262 "No publications in the scenario.");
264 Assert.assertTrue(i > 0,
265 "More then one document must be in the database");
267 // Check created uses relations
269 .assertTrue(usedMap.size() > 0,
270 "Uses relations must be created.");
271 boolean foundAny = false;
272 for (Long usingId : usedMap.keySet()) {
273 for (Publication pub : aScen.getDocums()) {
274 if (pub.getIndex() == usingId) {
275 boolean found = false;
276 for (Publication used : aScen.getDocums()) {
277 found = (used.getIndex() == usedMap.get(usingId));
283 for (Publication used : aStudy.getDocums()) {
284 found = (used.getIndex() == usedMap.get(usingId));
290 Assert.assertTrue(found,
291 "Uses relation was not created in the database.");
292 foundAny = foundAny || found;
296 Assert.assertTrue(foundAny,
297 "No Uses relation was created in the database.");
299 return aScenario.getOwnerStudy();
303 * Create a document published in the scenario. <BR>
305 * document type - type used on the step <BR>
306 * <source-file>.brep <BR>
307 * <attached-file>.med
310 * the scenario to add the document to
312 * scenario step where the document to be published
314 * document properties
315 * @param attachedFileExt
316 * extension of the secon attached (exported) file
318 * outdated document flag
319 * @return the publication of the created document
320 * @throws IOException
321 * @throws MultiplyDefinedException
322 * @throws InvalidPropertyException
323 * @throws MissedPropertyException
325 private Publication createDoc(final ProjectElement aScenario,
326 final org.splat.som.Step aScStep, final Properties dprop,
327 final String attachedFileExt, final boolean isOutdated)
328 throws MissedPropertyException, InvalidPropertyException,
329 MultiplyDefinedException, IOException {
330 // Create a document published in the scenario
331 // document<i>: document type - type used on the step
332 // <source-file>.brep
333 // <attached-file>.med
334 Publication pub = _stepService.createDocument(aScStep, dprop);
335 Assert.assertNotNull(pub.getOwner(),
336 "The publication must be attached to the scenario.");
337 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
338 "The publication was not attached to the scenario.");
344 HibernateTemplate ht = getHibernateTemplate();
345 ht.saveOrUpdate(pub);
348 ht.save(pub.value());
350 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
356 * Test of generating a study document index.<BR>
357 * <B>Description :</B> <BR>
358 * <i>Create a study and try to generate the next document index.</i><BR>
359 * <B>Action : </B><BR>
360 * <i>1. call DAO's read method for an existing id.</i><BR>
361 * <B>Test data : </B><BR>
362 * <i>no input parameters</i><BR>
364 * <B>Outcome results:</B><BR>
367 * <li>The new index must be equal to the incremented old one and saved into the database<BR>
372 * @throws InvalidPropertyException
373 * if an invalid property is used when creating objects
374 * @throws MultiplyDefinedException
375 * when trying to create an object with already existing id
376 * @throws MissedPropertyException
377 * if a mandatory property is not defined for an object to be created
378 * @throws SQLException
379 * if test study creation is failed
380 * @throws IOException
381 * if test study creation is failed
382 * @throws ParseException
383 * @throws InterruptedException
384 * @throws NotApplicableException
388 public void testCreateDoc() throws InvalidPropertyException,
389 MissedPropertyException, MultiplyDefinedException, IOException,
390 SQLException, NotApplicableException, InterruptedException,
392 LOG.debug(">>>>> BEGIN testCreateDoc()");
393 startNestedTransaction();
395 HibernateTemplate ht = getHibernateTemplate();
396 Study aStudy = createStudy();
397 // Call DAO's create method for a good transient study.
398 Long id = aStudy.getIndex();
399 Assert.assertNotNull(id,
400 "Create method returns null instead of a new id.");
401 Assert.assertTrue(id > 0, "The new id is not a positive number.");
403 // Call DAO's get method for an existing id.
405 getHibernateTemplate().evict(aStudy);
406 getHibernateTemplate().clear();
407 Study aStudyFound = _studyDAO.get(id);
408 ht.evict(aStudyFound);
410 long userId = aStudyFound.getAuthor().getIndex();
411 org.splat.som.Step[] studySteps = _projectElementService
412 .getSteps(aStudyFound);
413 org.splat.som.Step[] scSteps = _projectElementService
414 .getSteps(aStudyFound.getScenarii()[0]);
416 List<org.splat.som.Step> steps = new ArrayList<org.splat.som.Step>();
417 steps.addAll(Arrays.asList(studySteps));
418 steps.addAll(Arrays.asList(scSteps));
419 steps.addAll(Arrays.asList(studySteps));
420 for (org.splat.som.Step step: steps) {
421 LOG.debug("Create a document for the step " + step.getNumber());
423 List<DocumentType> dtypes = _documentTypeService
424 .selectTypesOf(step.getStep());
425 if (dtypes.size() > 0) {
426 DocumentType dtype = dtypes.get(0);
427 int oldInd = ht.get(Study.class, aStudyFound.getIndex())
428 .getLastLocalIndex();
430 // Create a file in the download directory
431 String fname = "filename" + step.getNumber() + ".py";
432 String filePath = getDownloadPath(aStudyFound.getAuthor())
434 LOG.debug(step.getStep().getKey() + ": "
435 + step.getOwner().getClass().getSimpleName()
436 + ": Create test file: " + filePath);
437 FileWriter fw = new FileWriter(filePath);
439 .write("Simulation of filename.py file for creating a new document at "
443 Publication addoc = _publicationService.createDoc(aStudyFound
444 .getIndex(), step, dtype.getIndex(), userId, fname,
445 "tstdoc", ProgressState.inWORK, "", "", new Date(),
451 int ind = ht.get(Study.class, aStudyFound.getIndex())
452 .getLastLocalIndex();
454 LOG.debug("Previous index: " + oldInd + ", new index: " + ind);
455 Assert.assertEquals(ht.get(Study.class, aStudyFound.getIndex())
456 .getLastLocalIndex(), oldInd + 1,
457 "Incremented index must be saved in the database.");
458 aStudy = (Study) ht.find(
459 "from Study where rid = " + aStudyFound.getIndex())
461 Assert.assertEquals(aStudy.getLastLocalIndex(), oldInd + 1,
462 "Incremented index must be saved in the database.");
466 rollbackNestedTransaction();
467 LOG.debug(">>>>> END testCreateDoc()");
471 * Get path to the user's downloads directory. The directory is created if it is not exist yet.
475 * @return absolute path to downloads directory followed by slash
477 private String getDownloadPath(final User user) {
478 // Prepare download directory
479 File tmpDir = _repositoryService.getDownloadDirectory(user);
480 if (!tmpDir.exists()) {
481 Assert.assertTrue(tmpDir.mkdir(),
482 "Can't create temporary directory: "
483 + tmpDir.getAbsolutePath());
486 return tmpDir.getAbsolutePath() + "/";