Salome HOME
Refactoring continues: UserService is created instead of UserDirectory. Database...
[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.som.KnowledgeElementDAO;
26 import org.splat.dal.dao.som.ScenarioDAO;
27 import org.splat.dal.dao.som.StudyDAO;
28 import org.splat.kernel.InvalidPropertyException;
29 import org.splat.kernel.MissedPropertyException;
30 import org.splat.kernel.MultiplyDefinedException;
31 import org.splat.service.technical.IndexService;
32 import org.splat.som.Step;
33 import org.springframework.transaction.annotation.Transactional;
34
35 /**
36  * Scenario service implementation.
37  * 
38  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
39  */
40 public class ScenarioServiceImpl implements ScenarioService {
41
42         /**
43          * Logger for this class.
44          */
45         protected final static Logger logger = Logger
46                         .getLogger(ScenarioServiceImpl.class);
47
48         /**
49          * Injected index service.
50          */
51         private IndexService _indexService;
52         /**
53          * Injected step service.
54          */
55         private StepService _stepService;
56         /**
57          * Injected study service.
58          */
59         private StudyService _studyService;
60         /**
61          * Injected publication service.
62          */
63         private PublicationService _publicationService;
64         /**
65          * Injected project element service.
66          */
67         private ProjectElementService _projectElementService;
68         /**
69          * Injected knowledge element DAO.
70          */
71         private KnowledgeElementDAO _knowledgeElementDAO;
72         /**
73          * Injected scenario DAO.
74          */
75         private ScenarioDAO _scenarioDAO;
76
77         /**
78          * Injected study DAO.
79          */
80         private StudyDAO _studyDAO;
81
82         /**
83          * Injected knowledge element service.
84          */
85         private KnowledgeElementTypeService _knowledgeElementTypeService;
86
87         /**
88          * Injected user service.
89          */
90         private UserService _userService;
91
92         /**
93          * Get the projectElementService.
94          * 
95          * @return the projectElementService
96          */
97         public ProjectElementService getProjectElementService() {
98                 return _projectElementService;
99         }
100
101         /**
102          * Set the projectElementService.
103          * 
104          * @param projectElementService
105          *            the projectElementService to set
106          */
107         public void setProjectElementService(
108                         ProjectElementService projectElementService) {
109                 _projectElementService = projectElementService;
110         }
111
112         /**
113          * Get the publicationService.
114          * 
115          * @return the publicationService
116          */
117         public PublicationService getPublicationService() {
118                 return _publicationService;
119         }
120
121         /**
122          * Set the publicationService.
123          * 
124          * @param publicationService
125          *            the publicationService to set
126          */
127         public void setPublicationService(PublicationService publicationService) {
128                 _publicationService = publicationService;
129         }
130
131         /**
132          * Get the stepService.
133          * 
134          * @return the stepService
135          */
136         public StepService getStepService() {
137                 return _stepService;
138         }
139
140         /**
141          * Set the stepService.
142          * 
143          * @param stepService
144          *            the stepService to set
145          */
146         public void setStepService(StepService stepService) {
147                 _stepService = stepService;
148         }
149
150         /**
151          * {@inheritDoc}
152          * 
153          * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
154          *      org.splat.dal.bo.som.KnowledgeElement.Properties)
155          */
156         @Transactional
157         public KnowledgeElement addKnowledgeElement(Scenario aScenario,
158                         KnowledgeElement.Properties kprop) throws MissedPropertyException,
159                         InvalidPropertyException, MultiplyDefinedException {
160                 KnowledgeElement kelm = null;
161                 try {
162                         // Attach the detached scenario to the new hibernate session.
163                         aScenario = getScenarioDAO().merge(aScenario); // RKV
164                         kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
165                         getKnowledgeElementDAO().create(kelm);
166                         // RKV: commented because of BatchUpdateException during creation of a new study: session.flush(); //RKV
167                         // Update of my persistent data
168                         // RKV aScenario.getKnowledgeElements().add(kelm);
169                         // RKV getKnowledgeElementDAO().flush();
170                         // RKV: commented because of NullPointerException during creation of a new study: session.merge(aScenario); //RKV
171                         // Update of my transient data
172                         List<KnowledgeElement> known = aScenario
173                                         .getKnowledgeElementsOf(kelm.getType()); // Initializes this.known, if not yet done
174                         // RKV: knowledge is already added into persistent set and "known" is constructed from it in the above call: known.add(kelm);
175                         if (kelm.getType().equals("usecase")) {
176                                 aScenario.setUcase(kelm);
177                         } else if (aScenario.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
178                                 aScenario.getKnowledgeElementsList().add(kelm);
179                         }
180                         // Update of the index of Knowledge Elements
181                         getIndexService().add(kelm);
182                         update(aScenario);
183
184                 } catch (IOException error) {
185                         logger.error(
186                                         "Unable to index the knowedge element '" + kelm.getIndex()
187                                                         + "', reason:", error);
188                         kelm = null;
189                 }
190
191                 return kelm;
192         }
193
194         /**
195          * Update the scenario in the database.
196          * 
197          * @param aScenario
198          *            the scenario to update
199          * @return true if updating succeeded
200          */
201         @Transactional
202         private boolean update(Scenario aScenario) {
203                 boolean isOk = false;
204                 try {
205                         getScenarioDAO().update(aScenario); // Update of relational base
206                         isOk = true;
207                 } catch (Exception error) {
208                         logger.error("Unable to re-index the knowledge element '"
209                                         + aScenario.getIndex() + "', reason:", error);
210                 }
211                 return isOk;
212         }
213
214         /**
215          * {@inheritDoc}
216          * 
217          * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
218          */
219         public void checkin(Scenario aScenario) {
220                 aScenario.setUser(null);
221                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
222                 getScenarioDAO().update(aScenario);
223         }
224
225         /**
226          * {@inheritDoc}
227          * 
228          * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
229          */
230         public boolean checkout(Scenario aScenario, User user) {
231                 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user))
232                         return false;
233
234                 aScenario.setUser(user);
235                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
236                 getScenarioDAO().update(aScenario);
237                 return true;
238         }
239
240         /**
241          * {@inheritDoc}
242          * 
243          * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
244          */
245         public void copyContentsUpTo(Scenario scenario, Step lastep) {
246                 Scenario base = (Scenario) lastep.getOwner();
247                 Step[] from = getProjectElementService().getSteps(base);
248                 Step[] to = getProjectElementService().getSteps(scenario);
249                 for (int i = 0; i < from.length; i++) {
250                         Step step = from[i];
251                         if (step.getNumber() > lastep.getNumber())
252                                 break;
253
254                         List<Publication> docs = step.getAllDocuments();
255                         for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
256                                 Publication doc = getPublicationService().copy(j.next(),
257                                                 scenario); // Creation of a new reference to the document
258                                 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
259                                 getStepService().add(to[i], doc);
260                         }
261                         List<SimulationContext> ctex = step.getAllSimulationContexts();
262                         for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
263                                 getStepService().addSimulationContext(to[i], j.next());
264                         }
265                 }
266         }
267
268         /**
269          * {@inheritDoc}
270          * 
271          * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
272          */
273         public boolean isEmpty(Scenario scenario) {
274                 Step[] mystep = getProjectElementService().getSteps(scenario);
275                 boolean isEmp = true;
276                 for (int i = 0; i < mystep.length; i++) {
277                         if (mystep[i].isStarted()) {
278                                 isEmp = false;
279                                 break;
280                         }
281                 }
282                 return isEmp;
283         }
284
285         /**
286          * @param scenario
287          * @return
288          */
289         public boolean isFinished(Scenario scenario) {
290                 Step[] mystep = getProjectElementService().getSteps(scenario);
291                 boolean notempty = false; // If this is empty, this is not finished
292                 for (int i = 0; i < mystep.length; i++) {
293                         if (!mystep[i].isStarted())
294                                 continue;
295                         if (!mystep[i].isFinished())
296                                 return false;
297                         notempty = true;
298                 }
299                 return notempty;
300         }
301
302         /**
303          * {@inheritDoc}
304          * 
305          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
306          */
307         @Transactional
308         public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
309                         throws MissedPropertyException, InvalidPropertyException,
310                         MultiplyDefinedException {
311                 if (sprop.getManager() == null)
312                         sprop.setManager(aStudy.getAuthor());
313
314                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
315                 if (sprop.getBaseStep() != null)
316                         copyContentsUpTo(scenario, sprop.getBaseStep());
317                 Scenario previous = sprop.getInsertAfter();
318
319                 if (previous == null) {
320                         aStudy.getScenariiList().add(scenario);
321                 } else {
322                         aStudy.getScenariiList().add(
323                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
324                 }
325                 getStudyDAO().update(aStudy); // No need to update the Lucene index
326                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
327                 if (sprop.getBaseStep() != null) {
328                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
329                         getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
330                 }
331                 KnowledgeElementType ucase = getKnowledgeElementTypeService()
332                                 .selectType("usecase");
333                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
334                 User admin = getUserService().selectUser(1); // First user created when creating the database
335                 kprop.setType(ucase).setTitle(aStudy.getTitle())
336                                 .setValue(scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
337                 // knowledges
338                 addKnowledgeElement(scenario, kprop);
339                 return scenario;
340         }
341
342         /**
343          * Remove a knowledge element from a scenario.
344          * 
345          * @param scenario
346          *            the scenario
347          * @param kelm
348          *            the knowledge element to remove
349          * @return true if removal succeeded
350          */
351         public boolean removeKnowledgeElement(Scenario scenario,
352                         KnowledgeElement kelm) {
353                 // -------------------------------------------------------------
354                 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
355                 if (torem == null)
356                         return false;
357                 boolean done = scenario.getKnowledgeElements().remove(torem);
358                 if (done) {
359                         // Update of my transient data
360                         List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
361                                         kelm.getType().getIndex());
362                         kelms.remove(torem);
363                         if (scenario.getKnowledgeElementsList() != null)
364                                 scenario.getKnowledgeElementsList().remove(torem);
365                         getScenarioDAO().update(scenario);
366                         // TODO: If the owner study is not private, remove the knowledge from the Lucene index
367                         return true;
368                 } else {
369                         return false;
370                 }
371         }
372
373         /**
374          * Get the knowledgeElementDAO.
375          * 
376          * @return the knowledgeElementDAO
377          */
378         public KnowledgeElementDAO getKnowledgeElementDAO() {
379                 return _knowledgeElementDAO;
380         }
381
382         /**
383          * Set the knowledgeElementDAO.
384          * 
385          * @param knowledgeElementDAO
386          *            the knowledgeElementDAO to set
387          */
388         public void setKnowledgeElementDAO(KnowledgeElementDAO knowledgeElementDAO) {
389                 _knowledgeElementDAO = knowledgeElementDAO;
390         }
391
392         /**
393          * Get the indexService.
394          * 
395          * @return the indexService
396          */
397         public IndexService getIndexService() {
398                 return _indexService;
399         }
400
401         /**
402          * Set the indexService.
403          * 
404          * @param indexService
405          *            the indexService to set
406          */
407         public void setIndexService(IndexService indexService) {
408                 _indexService = indexService;
409         }
410
411         /**
412          * Get the scenarioDAO.
413          * 
414          * @return the scenarioDAO
415          */
416         public ScenarioDAO getScenarioDAO() {
417                 return _scenarioDAO;
418         }
419
420         /**
421          * Set the scenarioDAO.
422          * 
423          * @param scenarioDAO
424          *            the scenarioDAO to set
425          */
426         public void setScenarioDAO(ScenarioDAO scenarioDAO) {
427                 _scenarioDAO = scenarioDAO;
428         }
429
430         /**
431          * Get the studyDAO.
432          * 
433          * @return the studyDAO
434          */
435         public StudyDAO getStudyDAO() {
436                 return _studyDAO;
437         }
438
439         /**
440          * Set the studyDAO.
441          * 
442          * @param studyDAO
443          *            the studyDAO to set
444          */
445         public void setStudyDAO(StudyDAO studyDAO) {
446                 _studyDAO = studyDAO;
447         }
448
449         /**
450          * Get the knowledgeElementTypeService.
451          * 
452          * @return the knowledgeElementTypeService
453          */
454         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
455                 return _knowledgeElementTypeService;
456         }
457
458         /**
459          * Set the knowledgeElementTypeService.
460          * 
461          * @param knowledgeElementTypeService
462          *            the knowledgeElementTypeService to set
463          */
464         public void setKnowledgeElementTypeService(
465                         KnowledgeElementTypeService knowledgeElementTypeService) {
466                 _knowledgeElementTypeService = knowledgeElementTypeService;
467         }
468
469         /**
470          * Get the studyService.
471          * 
472          * @return the studyService
473          */
474         public StudyService getStudyService() {
475                 return _studyService;
476         }
477
478         /**
479          * Set the studyService.
480          * 
481          * @param studyService
482          *            the studyService to set
483          */
484         public void setStudyService(StudyService studyService) {
485                 _studyService = studyService;
486         }
487
488         /**
489          * Get the userService.
490          * @return the userService
491          */
492         public UserService getUserService() {
493                 return _userService;
494         }
495
496         /**
497          * Set the userService.
498          * @param userService the userService to set
499          */
500         public void setUserService(UserService userService) {
501                 _userService = userService;
502         }
503
504 }