Salome HOME
0f8ea31442a6bdb4bea60d485e10fe4d119b7882
[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          * Get the projectElementService.
106          * 
107          * @return the projectElementService
108          */
109         public ProjectElementService getProjectElementService() {
110                 return _projectElementService;
111         }
112
113         /**
114          * Set the projectElementService.
115          * 
116          * @param projectElementService
117          *            the projectElementService to set
118          */
119         public void setProjectElementService(
120                         ProjectElementService projectElementService) {
121                 _projectElementService = projectElementService;
122         }
123
124         /**
125          * Get the publicationService.
126          * 
127          * @return the publicationService
128          */
129         public PublicationService getPublicationService() {
130                 return _publicationService;
131         }
132
133         /**
134          * Set the publicationService.
135          * 
136          * @param publicationService
137          *            the publicationService to set
138          */
139         public void setPublicationService(PublicationService publicationService) {
140                 _publicationService = publicationService;
141         }
142
143         /**
144          * Get the stepService.
145          * 
146          * @return the stepService
147          */
148         public StepService getStepService() {
149                 return _stepService;
150         }
151
152         /**
153          * Set the stepService.
154          * 
155          * @param stepService
156          *            the stepService to set
157          */
158         public void setStepService(StepService stepService) {
159                 _stepService = stepService;
160         }
161
162         /**
163          * {@inheritDoc}
164          * 
165          * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
166          *      org.splat.dal.bo.som.KnowledgeElement.Properties)
167          */
168         @Transactional
169         public KnowledgeElement addKnowledgeElement(Scenario aScenarioDTO,
170                         KnowledgeElement.Properties kprop) throws MissedPropertyException,
171                         InvalidPropertyException, MultiplyDefinedException {
172                 KnowledgeElement kelm = null;
173                 try {
174                         long aScenarioId = aScenarioDTO.getIndex();
175                         if (logger.isDebugEnabled()) {
176                                 logger.debug("Add a knowledge element to the scenario #"
177                                                 + aScenarioId);
178                         }
179                         // Get the persistent scenario.
180                         Scenario aScenario = getScenarioDAO().get(aScenarioId);
181                         // Get persistent objects for creating a new knowledge.
182                         //TODO: Actions must use DTO instead of persistent objects.
183                         getUserDAO().merge(kprop.getAuthor());
184                         getKnowledgeElementTypeDAO().merge(kprop.getType());
185                         // Create a transient knowledge element related to the given scenario.
186                         kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
187                         // Save the new knowledge in the database.
188                         getKnowledgeElementDAO().create(kelm);
189                         // Update scenario transient data.
190                         if (kelm.getType().equals("usecase")) {
191                                 aScenarioDTO.setUcase(kelm);
192                         } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
193                                 aScenarioDTO.getKnowledgeElementsList().add(kelm);
194                         }
195                         // Update the lucene index of knowledge elements.
196                         getIndexService().add(kelm);
197                         if (logger.isDebugEnabled()) {
198                                 logger.debug("A knowledge element #" + kelm.getIndex()
199                                                 + " is added to the scenario #" + aScenario.getIndex());
200                         }
201                 } catch (IOException error) {
202                         logger.error("Unable to index the knowedge element '"
203                                         + kelm.getIndex() + "', reason:", error);
204                         kelm = null;
205                 }
206
207                 return kelm;
208         }
209
210         /**
211          * Update the scenario in the database.
212          * 
213          * @param aScenario
214          *            the scenario to update
215          * @return true if updating succeeded
216          */
217         @Transactional
218         private boolean update(Scenario aScenario) {
219                 boolean isOk = false;
220                 try {
221                         getScenarioDAO().update(aScenario); // Update of relational base
222                         isOk = true;
223                 } catch (Exception error) {
224                         logger.error("Unable to re-index the knowledge element '"
225                                         + aScenario.getIndex() + "', reason:", error);
226                 }
227                 return isOk;
228         }
229
230         /**
231          * {@inheritDoc}
232          * 
233          * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
234          */
235         public void checkin(Scenario aScenario) {
236                 aScenario.setUser(null);
237                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
238                 getScenarioDAO().update(aScenario);
239         }
240
241         /**
242          * {@inheritDoc}
243          * 
244          * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
245          */
246         public boolean checkout(Scenario aScenario, User user) {
247                 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user))
248                         return false;
249
250                 aScenario.setUser(user);
251                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
252                 getScenarioDAO().update(aScenario);
253                 return true;
254         }
255
256         /**
257          * {@inheritDoc}
258          * 
259          * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
260          */
261         public void copyContentsUpTo(Scenario scenario, Step lastep) {
262                 Scenario base = (Scenario) lastep.getOwner();
263                 Step[] from = getProjectElementService().getSteps(base);
264                 Step[] to = getProjectElementService().getSteps(scenario);
265                 for (int i = 0; i < from.length; i++) {
266                         Step step = from[i];
267                         if (step.getNumber() > lastep.getNumber())
268                                 break;
269
270                         List<Publication> docs = step.getAllDocuments();
271                         for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
272                                 Publication doc = getPublicationService().copy(j.next(),
273                                                 scenario); // Creation of a new reference to the document
274                                 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
275                                 getStepService().add(to[i], doc);
276                         }
277                         List<SimulationContext> ctex = step.getAllSimulationContexts();
278                         for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
279                                 getStepService().addSimulationContext(to[i], j.next());
280                         }
281                 }
282         }
283
284         /**
285          * {@inheritDoc}
286          * 
287          * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
288          */
289         public boolean isEmpty(Scenario scenario) {
290                 Step[] mystep = getProjectElementService().getSteps(scenario);
291                 boolean isEmp = true;
292                 for (int i = 0; i < mystep.length; i++) {
293                         if (mystep[i].isStarted()) {
294                                 isEmp = false;
295                                 break;
296                         }
297                 }
298                 return isEmp;
299         }
300
301         /**
302          * @param scenario
303          * @return
304          */
305         public boolean isFinished(Scenario scenario) {
306                 Step[] mystep = getProjectElementService().getSteps(scenario);
307                 boolean notempty = false; // If this is empty, this is not finished
308                 for (int i = 0; i < mystep.length; i++) {
309                         if (!mystep[i].isStarted())
310                                 continue;
311                         if (!mystep[i].isFinished())
312                                 return false;
313                         notempty = true;
314                 }
315                 return notempty;
316         }
317
318         /**
319          * {@inheritDoc}
320          * 
321          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
322          */
323         @Transactional
324         public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
325                         throws MissedPropertyException, InvalidPropertyException,
326                         MultiplyDefinedException {
327                 if (sprop.getManager() == null)
328                         sprop.setManager(aStudy.getAuthor());
329
330                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
331                 if (sprop.getBaseStep() != null)
332                         copyContentsUpTo(scenario, sprop.getBaseStep());
333                 Scenario previous = sprop.getInsertAfter();
334
335                 if (previous == null) {
336                         aStudy.getScenariiList().add(scenario);
337                 } else {
338                         aStudy.getScenariiList().add(
339                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
340                 }
341                 getStudyDAO().update(aStudy); // No need to update the Lucene index
342                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
343                 if (sprop.getBaseStep() != null) {
344                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
345                         getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
346                 }
347                 KnowledgeElementType ucase = getKnowledgeElementTypeService()
348                                 .selectType("usecase");
349                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
350                 User admin = getUserService().selectUser(1); // First user created when creating the database
351                 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
352                                 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
353                 // knowledges
354                 addKnowledgeElement(scenario, kprop);
355                 return scenario;
356         }
357
358         /**
359          * Remove a knowledge element from a scenario.
360          * 
361          * @param scenario
362          *            the scenario
363          * @param kelm
364          *            the knowledge element to remove
365          * @return true if removal succeeded
366          */
367         public boolean removeKnowledgeElement(Scenario scenario,
368                         KnowledgeElement kelm) {
369                 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
370                 if (torem == null)
371                         return false;
372                 boolean done = scenario.getKnowledgeElements().remove(torem);
373                 if (done) {
374                         // Update of my transient data
375                         // RKV: These transient data are not used indeed.
376                         // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
377                         // RKV: kelm.getType().getIndex());
378                         // RKV: kelms.remove(torem);
379                         if (scenario.getKnowledgeElementsList() != null)
380                                 scenario.getKnowledgeElementsList().remove(torem);
381                         getScenarioDAO().update(scenario);
382                         // TODO: If the owner study is not private, remove the knowledge from the Lucene index
383                         return true;
384                 } else {
385                         return false;
386                 }
387         }
388
389         /**
390          * Get the knowledgeElementDAO.
391          * 
392          * @return the knowledgeElementDAO
393          */
394         public KnowledgeElementDAO getKnowledgeElementDAO() {
395                 return _knowledgeElementDAO;
396         }
397
398         /**
399          * Set the knowledgeElementDAO.
400          * 
401          * @param knowledgeElementDAO
402          *            the knowledgeElementDAO to set
403          */
404         public void setKnowledgeElementDAO(KnowledgeElementDAO knowledgeElementDAO) {
405                 _knowledgeElementDAO = knowledgeElementDAO;
406         }
407
408         /**
409          * Get the indexService.
410          * 
411          * @return the indexService
412          */
413         public IndexService getIndexService() {
414                 return _indexService;
415         }
416
417         /**
418          * Set the indexService.
419          * 
420          * @param indexService
421          *            the indexService to set
422          */
423         public void setIndexService(IndexService indexService) {
424                 _indexService = indexService;
425         }
426
427         /**
428          * Get the scenarioDAO.
429          * 
430          * @return the scenarioDAO
431          */
432         public ScenarioDAO getScenarioDAO() {
433                 return _scenarioDAO;
434         }
435
436         /**
437          * Set the scenarioDAO.
438          * 
439          * @param scenarioDAO
440          *            the scenarioDAO to set
441          */
442         public void setScenarioDAO(ScenarioDAO scenarioDAO) {
443                 _scenarioDAO = scenarioDAO;
444         }
445
446         /**
447          * Get the studyDAO.
448          * 
449          * @return the studyDAO
450          */
451         public StudyDAO getStudyDAO() {
452                 return _studyDAO;
453         }
454
455         /**
456          * Set the studyDAO.
457          * 
458          * @param studyDAO
459          *            the studyDAO to set
460          */
461         public void setStudyDAO(StudyDAO studyDAO) {
462                 _studyDAO = studyDAO;
463         }
464
465         /**
466          * Get the knowledgeElementTypeService.
467          * 
468          * @return the knowledgeElementTypeService
469          */
470         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
471                 return _knowledgeElementTypeService;
472         }
473
474         /**
475          * Set the knowledgeElementTypeService.
476          * 
477          * @param knowledgeElementTypeService
478          *            the knowledgeElementTypeService to set
479          */
480         public void setKnowledgeElementTypeService(
481                         KnowledgeElementTypeService knowledgeElementTypeService) {
482                 _knowledgeElementTypeService = knowledgeElementTypeService;
483         }
484
485         /**
486          * Get the studyService.
487          * 
488          * @return the studyService
489          */
490         public StudyService getStudyService() {
491                 return _studyService;
492         }
493
494         /**
495          * Set the studyService.
496          * 
497          * @param studyService
498          *            the studyService to set
499          */
500         public void setStudyService(StudyService studyService) {
501                 _studyService = studyService;
502         }
503
504         /**
505          * Get the userService.
506          * 
507          * @return the userService
508          */
509         public UserService getUserService() {
510                 return _userService;
511         }
512
513         /**
514          * Set the userService.
515          * 
516          * @param userService
517          *            the userService to set
518          */
519         public void setUserService(UserService userService) {
520                 _userService = userService;
521         }
522
523         /**
524          * Get the userDAO.
525          * 
526          * @return the userDAO
527          */
528         public UserDAO getUserDAO() {
529                 return _userDAO;
530         }
531
532         /**
533          * Set the userDAO.
534          * 
535          * @param userDAO
536          *            the userDAO to set
537          */
538         public void setUserDAO(UserDAO userDAO) {
539                 _userDAO = userDAO;
540         }
541
542         /**
543          * Get the knowledgeElementTypeDAO.
544          * 
545          * @return the knowledgeElementTypeDAO
546          */
547         public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
548                 return _knowledgeElementTypeDAO;
549         }
550
551         /**
552          * Set the knowledgeElementTypeDAO.
553          * 
554          * @param knowledgeElementTypeDAO
555          *            the knowledgeElementTypeDAO to set
556          */
557         public void setKnowledgeElementTypeDAO(
558                         KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
559                 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
560         }
561
562 }