Salome HOME
464eff57440108fcbfc1ddab8534fe110a243ce4
[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                         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(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(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(Study.Properties sprop, Scenario.Properties oprop,
186                         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(Scenario aScenarioDTO,
210                         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                         // Update the lucene index of knowledge elements.
236                         getIndexService().add(kelm);
237                         if (logger.isDebugEnabled()) {
238                                 logger.debug("A knowledge element #" + kelm.getIndex()
239                                                 + " is added to the scenario #" + aScenario.getIndex());
240                         }
241                 } catch (IOException error) {
242                         logger.error("Unable to index the knowedge element '"
243                                         + kelm.getIndex() + "', reason:", error);
244                         kelm = null;
245                 }
246
247                 return kelm;
248         }
249
250         /**
251          * Update the scenario in the database.
252          * 
253          * @param aScenario
254          *            the scenario to update
255          * @return true if updating succeeded
256          */
257         @Transactional
258         private boolean update(Scenario aScenario) {
259                 boolean isOk = false;
260                 try {
261                         getScenarioDAO().update(aScenario); // Update of relational base
262                         isOk = true;
263                 } catch (Exception error) {
264                         logger.error("Unable to re-index the knowledge element '"
265                                         + aScenario.getIndex() + "', reason:", error);
266                 }
267                 return isOk;
268         }
269
270         /**
271          * {@inheritDoc}
272          * 
273          * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
274          */
275         public void checkin(Scenario aScenario) {
276                 aScenario.setUser(null);
277                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
278                 getScenarioDAO().update(aScenario);
279         }
280
281         /**
282          * {@inheritDoc}
283          * 
284          * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
285          */
286         public boolean checkout(Scenario aScenario, User user) {
287                 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user))
288                         return false;
289
290                 aScenario.setUser(user);
291                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
292                 getScenarioDAO().update(aScenario);
293                 return true;
294         }
295
296         /**
297          * {@inheritDoc}
298          * 
299          * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
300          */
301         public void copyContentsUpTo(Scenario scenario, Step lastep) {
302                 Scenario base = (Scenario) lastep.getOwner();
303                 Step[] from = getProjectElementService().getSteps(base);
304                 Step[] to = getProjectElementService().getSteps(scenario);
305                 for (int i = 0; i < from.length; i++) {
306                         Step step = from[i];
307                         if (step.getNumber() > lastep.getNumber())
308                                 break;
309
310                         List<Publication> docs = step.getAllDocuments();
311                         for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
312                                 Publication doc = getPublicationService().copy(j.next(),
313                                                 scenario); // Creation of a new reference to the document
314                                 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
315                                 getStepService().add(to[i], doc);
316                         }
317                         List<SimulationContext> ctex = step.getAllSimulationContexts();
318                         for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
319                                 getStepService().addSimulationContext(to[i], j.next());
320                         }
321                 }
322         }
323
324         /**
325          * {@inheritDoc}
326          * 
327          * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
328          */
329         public boolean isEmpty(Scenario scenario) {
330                 Step[] mystep = getProjectElementService().getSteps(scenario);
331                 boolean isEmp = true;
332                 for (int i = 0; i < mystep.length; i++) {
333                         if (mystep[i].isStarted()) {
334                                 isEmp = false;
335                                 break;
336                         }
337                 }
338                 return isEmp;
339         }
340
341         /**
342          * @param scenario
343          * @return
344          */
345         public boolean isFinished(Scenario scenario) {
346                 Step[] mystep = getProjectElementService().getSteps(scenario);
347                 boolean notempty = false; // If this is empty, this is not finished
348                 for (int i = 0; i < mystep.length; i++) {
349                         if (!mystep[i].isStarted())
350                                 continue;
351                         if (!mystep[i].isFinished())
352                                 return false;
353                         notempty = true;
354                 }
355                 return notempty;
356         }
357
358         /**
359          * {@inheritDoc}
360          * 
361          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
362          */
363         @Transactional
364         public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
365                         throws MissedPropertyException, InvalidPropertyException,
366                         MultiplyDefinedException {
367                 if (sprop.getManager() == null)
368                         sprop.setManager(aStudy.getAuthor());
369
370                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
371                 if (sprop.getBaseStep() != null)
372                         copyContentsUpTo(scenario, sprop.getBaseStep());
373                 Scenario previous = sprop.getInsertAfter();
374
375                 if (previous == null) {
376                         aStudy.getScenariiList().add(scenario);
377                 } else {
378                         aStudy.getScenariiList().add(
379                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
380                 }
381                 getStudyDAO().update(aStudy); // No need to update the Lucene index
382                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
383                 if (sprop.getBaseStep() != null) {
384                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
385                         getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
386                 }
387                 KnowledgeElementType ucase = getKnowledgeElementTypeService()
388                                 .selectType("usecase");
389                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
390                 User admin = getUserService().selectUser(1); // First user created when creating the database
391                 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
392                                 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
393                 // knowledges
394                 addKnowledgeElement(scenario, kprop);
395                 return scenario;
396         }
397
398         /**
399          * Remove a knowledge element from a scenario.
400          * 
401          * @param scenario
402          *            the scenario
403          * @param kelm
404          *            the knowledge element to remove
405          * @return true if removal succeeded
406          */
407         public boolean removeKnowledgeElement(Scenario scenario,
408                         KnowledgeElement kelm) {
409                 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
410                 if (torem == null)
411                         return false;
412                 boolean done = scenario.getKnowledgeElements().remove(torem);
413                 if (done) {
414                         // Update of my transient data
415                         // RKV: These transient data are not used indeed.
416                         // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
417                         // RKV: kelm.getType().getIndex());
418                         // RKV: kelms.remove(torem);
419                         if (scenario.getKnowledgeElementsList() != null)
420                                 scenario.getKnowledgeElementsList().remove(torem);
421                         getScenarioDAO().update(scenario);
422                         // TODO: If the owner study is not private, remove the knowledge from the Lucene index
423                         return true;
424                 } else {
425                         return false;
426                 }
427         }
428
429         /**
430          * Get the knowledgeElementDAO.
431          * 
432          * @return the knowledgeElementDAO
433          */
434         public KnowledgeElementDAO getKnowledgeElementDAO() {
435                 return _knowledgeElementDAO;
436         }
437
438         /**
439          * Set the knowledgeElementDAO.
440          * 
441          * @param knowledgeElementDAO
442          *            the knowledgeElementDAO to set
443          */
444         public void setKnowledgeElementDAO(KnowledgeElementDAO knowledgeElementDAO) {
445                 _knowledgeElementDAO = knowledgeElementDAO;
446         }
447
448         /**
449          * Get the indexService.
450          * 
451          * @return the indexService
452          */
453         public IndexService getIndexService() {
454                 return _indexService;
455         }
456
457         /**
458          * Set the indexService.
459          * 
460          * @param indexService
461          *            the indexService to set
462          */
463         public void setIndexService(IndexService indexService) {
464                 _indexService = indexService;
465         }
466
467         /**
468          * Get the scenarioDAO.
469          * 
470          * @return the scenarioDAO
471          */
472         public ScenarioDAO getScenarioDAO() {
473                 return _scenarioDAO;
474         }
475
476         /**
477          * Set the scenarioDAO.
478          * 
479          * @param scenarioDAO
480          *            the scenarioDAO to set
481          */
482         public void setScenarioDAO(ScenarioDAO scenarioDAO) {
483                 _scenarioDAO = scenarioDAO;
484         }
485
486         /**
487          * Get the studyDAO.
488          * 
489          * @return the studyDAO
490          */
491         public StudyDAO getStudyDAO() {
492                 return _studyDAO;
493         }
494
495         /**
496          * Set the studyDAO.
497          * 
498          * @param studyDAO
499          *            the studyDAO to set
500          */
501         public void setStudyDAO(StudyDAO studyDAO) {
502                 _studyDAO = studyDAO;
503         }
504
505         /**
506          * Get the knowledgeElementTypeService.
507          * 
508          * @return the knowledgeElementTypeService
509          */
510         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
511                 return _knowledgeElementTypeService;
512         }
513
514         /**
515          * Set the knowledgeElementTypeService.
516          * 
517          * @param knowledgeElementTypeService
518          *            the knowledgeElementTypeService to set
519          */
520         public void setKnowledgeElementTypeService(
521                         KnowledgeElementTypeService knowledgeElementTypeService) {
522                 _knowledgeElementTypeService = knowledgeElementTypeService;
523         }
524
525         /**
526          * Get the studyService.
527          * 
528          * @return the studyService
529          */
530         public StudyService getStudyService() {
531                 return _studyService;
532         }
533
534         /**
535          * Set the studyService.
536          * 
537          * @param studyService
538          *            the studyService to set
539          */
540         public void setStudyService(StudyService studyService) {
541                 _studyService = studyService;
542         }
543
544         /**
545          * Get the userService.
546          * 
547          * @return the userService
548          */
549         public UserService getUserService() {
550                 return _userService;
551         }
552
553         /**
554          * Set the userService.
555          * 
556          * @param userService
557          *            the userService to set
558          */
559         public void setUserService(UserService userService) {
560                 _userService = userService;
561         }
562
563         /**
564          * Get the userDAO.
565          * 
566          * @return the userDAO
567          */
568         public UserDAO getUserDAO() {
569                 return _userDAO;
570         }
571
572         /**
573          * Set the userDAO.
574          * 
575          * @param userDAO
576          *            the userDAO to set
577          */
578         public void setUserDAO(UserDAO userDAO) {
579                 _userDAO = userDAO;
580         }
581
582         /**
583          * Get the knowledgeElementTypeDAO.
584          * 
585          * @return the knowledgeElementTypeDAO
586          */
587         public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
588                 return _knowledgeElementTypeDAO;
589         }
590
591         /**
592          * Set the knowledgeElementTypeDAO.
593          * 
594          * @param knowledgeElementTypeDAO
595          *            the knowledgeElementTypeDAO to set
596          */
597         public void setKnowledgeElementTypeDAO(
598                         KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
599                 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
600         }
601
602         /**
603          * Get the simulationContextService.
604          * 
605          * @return the simulationContextService
606          */
607         public SimulationContextService getSimulationContextService() {
608                 return _simulationContextService;
609         }
610
611         /**
612          * Set the simulationContextService.
613          * 
614          * @param simulationContextService
615          *            the simulationContextService to set
616          */
617         public void setSimulationContextService(
618                         SimulationContextService simulationContextService) {
619                 _simulationContextService = simulationContextService;
620         }
621
622 }