Salome HOME
KnowledgeElementDTO is now used in KnowledgeElementFacade. Edit and rename knowledge...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / ScenarioServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   06.10.2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package org.splat.service;
11
12 import java.io.IOException;
13 import java.util.Calendar;
14 import java.util.Iterator;
15 import java.util.List;
16
17 import org.apache.log4j.Logger;
18 import org.splat.dal.bo.kernel.User;
19 import org.splat.dal.bo.som.KnowledgeElement;
20 import org.splat.dal.bo.som.KnowledgeElementType;
21 import org.splat.dal.bo.som.Publication;
22 import org.splat.dal.bo.som.Scenario;
23 import org.splat.dal.bo.som.SimulationContext;
24 import org.splat.dal.bo.som.Study;
25 import org.splat.dal.dao.kernel.UserDAO;
26 import org.splat.dal.dao.som.KnowledgeElementDAO;
27 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
28 import org.splat.dal.dao.som.ScenarioDAO;
29 import org.splat.dal.dao.som.StudyDAO;
30 import org.splat.kernel.InvalidPropertyException;
31 import org.splat.kernel.MissedPropertyException;
32 import org.splat.kernel.MultiplyDefinedException;
33 import org.splat.service.technical.IndexService;
34 import org.splat.som.Step;
35 import org.springframework.transaction.annotation.Transactional;
36
37 /**
38  * Scenario service implementation.
39  * 
40  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
41  */
42 public class ScenarioServiceImpl implements ScenarioService {
43
44         /**
45          * Logger for this class.
46          */
47         protected final static Logger logger = Logger
48                         .getLogger(ScenarioServiceImpl.class);
49
50         /**
51          * Injected index service.
52          */
53         private IndexService _indexService;
54         /**
55          * Injected step service.
56          */
57         private StepService _stepService;
58         /**
59          * Injected study service.
60          */
61         private StudyService _studyService;
62         /**
63          * Injected publication service.
64          */
65         private PublicationService _publicationService;
66         /**
67          * Injected project element service.
68          */
69         private ProjectElementService _projectElementService;
70         /**
71          * Injected knowledge element DAO.
72          */
73         private KnowledgeElementDAO _knowledgeElementDAO;
74         /**
75          * Injected scenario DAO.
76          */
77         private ScenarioDAO _scenarioDAO;
78
79         /**
80          * Injected study DAO.
81          */
82         private StudyDAO _studyDAO;
83
84         /**
85          * Injected knowledge element service.
86          */
87         private KnowledgeElementTypeService _knowledgeElementTypeService;
88
89         /**
90          * Injected user service.
91          */
92         private UserService _userService;
93
94         /**
95          * Injected user DAO.
96          */
97         private UserDAO _userDAO;
98
99         /**
100          * Injected knowledge element type DAO.
101          */
102         private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
103
104         /**
105          * Injected simulation context service.
106          */
107         private SimulationContextService _simulationContextService;
108
109         /**
110          * Get the projectElementService.
111          * 
112          * @return the projectElementService
113          */
114         public ProjectElementService getProjectElementService() {
115                 return _projectElementService;
116         }
117
118         /**
119          * Set the projectElementService.
120          * 
121          * @param projectElementService
122          *            the projectElementService to set
123          */
124         public void setProjectElementService(
125                         final ProjectElementService projectElementService) {
126                 _projectElementService = projectElementService;
127         }
128
129         /**
130          * Get the publicationService.
131          * 
132          * @return the publicationService
133          */
134         public PublicationService getPublicationService() {
135                 return _publicationService;
136         }
137
138         /**
139          * Set the publicationService.
140          * 
141          * @param publicationService
142          *            the publicationService to set
143          */
144         public void setPublicationService(final PublicationService publicationService) {
145                 _publicationService = publicationService;
146         }
147
148         /**
149          * Get the stepService.
150          * 
151          * @return the stepService
152          */
153         public StepService getStepService() {
154                 return _stepService;
155         }
156
157         /**
158          * Set the stepService.
159          * 
160          * @param stepService
161          *            the stepService to set
162          */
163         public void setStepService(final StepService stepService) {
164                 _stepService = stepService;
165         }
166
167         /**
168          * Create a new study with one scenario and "product" simulation context.
169          * 
170          * @param sprop
171          *            the study properties
172          * @param oprop
173          *            the scenario properties
174          * @param cprop
175          *            the "product" simulation context properties
176          * @return the created study
177          * @throws MissedPropertyException
178          *             if a mandatory property is missed
179          * @throws InvalidPropertyException
180          *             if a property is invalid
181          * @throws MultiplyDefinedException
182          *             if some property occurs several times
183          */
184         @Transactional
185         public Study createStudy(final Study.Properties sprop, final Scenario.Properties oprop,
186                         final SimulationContext.Properties cprop) throws MissedPropertyException,
187                         InvalidPropertyException, MultiplyDefinedException {
188                 Study study = getStudyService().createStudy(sprop);
189                 addScenario(study, oprop);
190                 if (cprop.getIndex() == 0) { // Input of new project context
191                         cprop.setType(getSimulationContextService().selectType("product"))
192                                         .setValue(cprop.getValue());
193                         getStudyService().addProjectContext(study, cprop);
194                 } else { // Selection of existing project context
195                         SimulationContext context = getSimulationContextService()
196                                         .selectSimulationContext(cprop.getIndex());
197                         getStudyService().addProjectContext(study, context);
198                 }
199                 return study;
200         }
201
202         /**
203          * {@inheritDoc}
204          * 
205          * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
206          *      org.splat.dal.bo.som.KnowledgeElement.Properties)
207          */
208         @Transactional
209         public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
210                         final KnowledgeElement.Properties kprop) throws MissedPropertyException,
211                         InvalidPropertyException, MultiplyDefinedException {
212                 KnowledgeElement kelm = null;
213                 try {
214                         long aScenarioId = aScenarioDTO.getIndex();
215                         if (logger.isDebugEnabled()) {
216                                 logger.debug("Add a knowledge element to the scenario #"
217                                                 + aScenarioId);
218                         }
219                         // Get the persistent scenario.
220                         Scenario aScenario = getScenarioDAO().get(aScenarioId);
221                         // Get persistent objects for creating a new knowledge.
222                         // TODO: Actions must use DTO instead of persistent objects.
223                         getUserDAO().merge(kprop.getAuthor());
224                         getKnowledgeElementTypeDAO().merge(kprop.getType());
225                         // Create a transient knowledge element related to the given scenario.
226                         kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
227                         // Save the new knowledge in the database.
228                         getKnowledgeElementDAO().create(kelm);
229                         // Update scenario transient data.
230                         if (kelm.getType().equals("usecase")) {
231                                 aScenarioDTO.setUcase(kelm);
232                         } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
233                                 aScenarioDTO.getKnowledgeElementsList().add(kelm);
234                         }
235                         
236                         // Load the workflow for the parent study to take into account 
237                         // all study actors durng reindexing.
238                         getStudyService().loadWorkflow(aScenario.getOwnerStudy());
239                         
240                         // Update the lucene index of knowledge elements.
241                         getIndexService().add(kelm);
242                         if (logger.isDebugEnabled()) {
243                                 logger.debug("A knowledge element #" + kelm.getIndex()
244                                                 + " is added to the scenario #" + aScenario.getIndex());
245                         }
246                 } catch (IOException error) {
247                         logger.error("Unable to index the knowedge element '"
248                                         + kelm.getIndex() + "', reason:", error);
249                         kelm = null;
250                 }
251
252                 return kelm;
253         }
254
255         /**
256          * Update the scenario in the database.
257          * 
258          * @param aScenario
259          *            the scenario to update
260          * @return true if updating succeeded
261          */
262         @Transactional
263         private boolean update(final Scenario aScenario) {
264                 boolean isOk = false;
265                 try {
266                         getScenarioDAO().update(aScenario); // Update of relational base
267                         isOk = true;
268                 } catch (Exception error) {
269                         logger.error("Unable to re-index the knowledge element '"
270                                         + aScenario.getIndex() + "', reason:", error);
271                 }
272                 return isOk;
273         }
274
275         /**
276          * {@inheritDoc}
277          * 
278          * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
279          */
280         public void checkin(final Scenario aScenario) {
281                 aScenario.setUser(null);
282                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
283                 getScenarioDAO().update(aScenario);
284         }
285
286         /**
287          * {@inheritDoc}
288          * 
289          * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
290          */
291         public boolean checkout(final Scenario aScenario, final User user) {
292                 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user)) {
293                         return false;
294                 }
295
296                 aScenario.setUser(user);
297                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
298                 getScenarioDAO().update(aScenario);
299                 return true;
300         }
301
302         /**
303          * {@inheritDoc}
304          * 
305          * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
306          */
307         public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
308                 Scenario base = (Scenario) lastep.getOwner();
309                 Step[] from = getProjectElementService().getSteps(base);
310                 Step[] to = getProjectElementService().getSteps(scenario);
311                 for (int i = 0; i < from.length; i++) {
312                         Step step = from[i];
313                         if (step.getNumber() > lastep.getNumber()) {
314                                 break;
315                         }
316
317                         List<Publication> docs = step.getAllDocuments();
318                         for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
319                                 Publication doc = getPublicationService().copy(j.next(),
320                                                 scenario); // Creation of a new reference to the document
321                                 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
322                                 getStepService().add(to[i], doc);
323                         }
324                         List<SimulationContext> ctex = step.getAllSimulationContexts();
325                         for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
326                                 getStepService().addSimulationContext(to[i], j.next());
327                         }
328                 }
329         }
330
331         /**
332          * {@inheritDoc}
333          * 
334          * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
335          */
336         public boolean isEmpty(final Scenario scenario) {
337                 Step[] mystep = getProjectElementService().getSteps(scenario);
338                 boolean isEmp = true;
339                 for (int i = 0; i < mystep.length; i++) {
340                         if (mystep[i].isStarted()) {
341                                 isEmp = false;
342                                 break;
343                         }
344                 }
345                 return isEmp;
346         }
347
348         /**
349          * @param scenario
350          * @return
351          */
352         public boolean isFinished(final Scenario scenario) {
353                 Step[] mystep = getProjectElementService().getSteps(scenario);
354                 boolean notempty = false; // If this is empty, this is not finished
355                 for (int i = 0; i < mystep.length; i++) {
356                         if (!mystep[i].isStarted()) {
357                                 continue;
358                         }
359                         if (!mystep[i].isFinished()) {
360                                 return false;
361                         }
362                         notempty = true;
363                 }
364                 return notempty;
365         }
366
367         /**
368          * {@inheritDoc}
369          * 
370          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
371          */
372         @Transactional
373         public Scenario addScenario(final Study aStudy, final Scenario.Properties sprop)
374                         throws MissedPropertyException, InvalidPropertyException,
375                         MultiplyDefinedException {
376                 if (sprop.getManager() == null) {
377                         sprop.setManager(aStudy.getAuthor());
378                 }
379
380                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
381                 if (sprop.getBaseStep() != null) {
382                         copyContentsUpTo(scenario, sprop.getBaseStep());
383                 }
384                 Scenario previous = sprop.getInsertAfter();
385
386                 if (previous == null) {
387                         aStudy.getScenariiList().add(scenario);
388                 } else {
389                         aStudy.getScenariiList().add(
390                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
391                 }
392                 getStudyDAO().update(aStudy); // No need to update the Lucene index
393                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
394                 if (sprop.getBaseStep() != null) {
395                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
396                         getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
397                 }
398                 KnowledgeElementType ucase = getKnowledgeElementTypeService()
399                                 .selectType("usecase");
400                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
401                 User admin = getUserService().selectUser(1); // First user created when creating the database
402                 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
403                                 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
404                 // knowledges
405                 addKnowledgeElement(scenario, kprop);
406                 return scenario;
407         }
408
409         /**
410          * Remove a knowledge element from a scenario.
411          * 
412          * @param scenario
413          *            the scenario
414          * @param kelm
415          *            the knowledge element to remove
416          * @return true if removal succeeded
417          */
418         public boolean removeKnowledgeElement(final Scenario scenario,
419                         final KnowledgeElement kelm) {
420                 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
421                 if (torem == null) {
422                         return false;
423                 }
424                 boolean done = scenario.getKnowledgeElements().remove(torem);
425                 if (done) {
426                         // Update of my transient data
427                         // RKV: These transient data are not used indeed.
428                         // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
429                         // RKV: kelm.getType().getIndex());
430                         // RKV: kelms.remove(torem);
431                         if (scenario.getKnowledgeElementsList() != null) {
432                                 scenario.getKnowledgeElementsList().remove(torem);
433                         }
434                         getScenarioDAO().update(scenario);
435                         // TODO: If the owner study is not private, remove the knowledge from the Lucene index
436                         return true;
437                 } else {
438                         return false;
439                 }
440         }
441
442         /**
443          * Get the knowledgeElementDAO.
444          * 
445          * @return the knowledgeElementDAO
446          */
447         public KnowledgeElementDAO getKnowledgeElementDAO() {
448                 return _knowledgeElementDAO;
449         }
450
451         /**
452          * Set the knowledgeElementDAO.
453          * 
454          * @param knowledgeElementDAO
455          *            the knowledgeElementDAO to set
456          */
457         public void setKnowledgeElementDAO(final KnowledgeElementDAO knowledgeElementDAO) {
458                 _knowledgeElementDAO = knowledgeElementDAO;
459         }
460
461         /**
462          * Get the indexService.
463          * 
464          * @return the indexService
465          */
466         public IndexService getIndexService() {
467                 return _indexService;
468         }
469
470         /**
471          * Set the indexService.
472          * 
473          * @param indexService
474          *            the indexService to set
475          */
476         public void setIndexService(final IndexService indexService) {
477                 _indexService = indexService;
478         }
479
480         /**
481          * Get the scenarioDAO.
482          * 
483          * @return the scenarioDAO
484          */
485         public ScenarioDAO getScenarioDAO() {
486                 return _scenarioDAO;
487         }
488
489         /**
490          * Set the scenarioDAO.
491          * 
492          * @param scenarioDAO
493          *            the scenarioDAO to set
494          */
495         public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
496                 _scenarioDAO = scenarioDAO;
497         }
498
499         /**
500          * Get the studyDAO.
501          * 
502          * @return the studyDAO
503          */
504         public StudyDAO getStudyDAO() {
505                 return _studyDAO;
506         }
507
508         /**
509          * Set the studyDAO.
510          * 
511          * @param studyDAO
512          *            the studyDAO to set
513          */
514         public void setStudyDAO(final StudyDAO studyDAO) {
515                 _studyDAO = studyDAO;
516         }
517
518         /**
519          * Get the knowledgeElementTypeService.
520          * 
521          * @return the knowledgeElementTypeService
522          */
523         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
524                 return _knowledgeElementTypeService;
525         }
526
527         /**
528          * Set the knowledgeElementTypeService.
529          * 
530          * @param knowledgeElementTypeService
531          *            the knowledgeElementTypeService to set
532          */
533         public void setKnowledgeElementTypeService(
534                         final KnowledgeElementTypeService knowledgeElementTypeService) {
535                 _knowledgeElementTypeService = knowledgeElementTypeService;
536         }
537
538         /**
539          * Get the studyService.
540          * 
541          * @return the studyService
542          */
543         public StudyService getStudyService() {
544                 return _studyService;
545         }
546
547         /**
548          * Set the studyService.
549          * 
550          * @param studyService
551          *            the studyService to set
552          */
553         public void setStudyService(final StudyService studyService) {
554                 _studyService = studyService;
555         }
556
557         /**
558          * Get the userService.
559          * 
560          * @return the userService
561          */
562         public UserService getUserService() {
563                 return _userService;
564         }
565
566         /**
567          * Set the userService.
568          * 
569          * @param userService
570          *            the userService to set
571          */
572         public void setUserService(final UserService userService) {
573                 _userService = userService;
574         }
575
576         /**
577          * Get the userDAO.
578          * 
579          * @return the userDAO
580          */
581         public UserDAO getUserDAO() {
582                 return _userDAO;
583         }
584
585         /**
586          * Set the userDAO.
587          * 
588          * @param userDAO
589          *            the userDAO to set
590          */
591         public void setUserDAO(final UserDAO userDAO) {
592                 _userDAO = userDAO;
593         }
594
595         /**
596          * Get the knowledgeElementTypeDAO.
597          * 
598          * @return the knowledgeElementTypeDAO
599          */
600         public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
601                 return _knowledgeElementTypeDAO;
602         }
603
604         /**
605          * Set the knowledgeElementTypeDAO.
606          * 
607          * @param knowledgeElementTypeDAO
608          *            the knowledgeElementTypeDAO to set
609          */
610         public void setKnowledgeElementTypeDAO(
611                         final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
612                 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
613         }
614
615         /**
616          * Get the simulationContextService.
617          * 
618          * @return the simulationContextService
619          */
620         public SimulationContextService getSimulationContextService() {
621                 return _simulationContextService;
622         }
623
624         /**
625          * Set the simulationContextService.
626          * 
627          * @param simulationContextService
628          *            the simulationContextService to set
629          */
630         public void setSimulationContextService(
631                         final SimulationContextService simulationContextService) {
632                 _simulationContextService = simulationContextService;
633         }
634
635 }