1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Calendar;
15 import java.util.Iterator;
16 import java.util.List;
18 import org.apache.log4j.Logger;
19 import org.splat.dal.bo.kernel.Relation;
20 import org.splat.dal.bo.kernel.User;
21 import org.splat.dal.bo.som.ConvertsRelation;
22 import org.splat.dal.bo.som.File;
23 import org.splat.dal.bo.som.KnowledgeElement;
24 import org.splat.dal.bo.som.KnowledgeElementType;
25 import org.splat.dal.bo.som.Publication;
26 import org.splat.dal.bo.som.Scenario;
27 import org.splat.dal.bo.som.SimulationContext;
28 import org.splat.dal.bo.som.Study;
29 import org.splat.dal.dao.kernel.UserDAO;
30 import org.splat.dal.dao.som.KnowledgeElementDAO;
31 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
32 import org.splat.dal.dao.som.ScenarioDAO;
33 import org.splat.dal.dao.som.StudyDAO;
34 import org.splat.kernel.InvalidPropertyException;
35 import org.splat.kernel.MissedPropertyException;
36 import org.splat.kernel.MultiplyDefinedException;
37 import org.splat.service.dto.DocumentDTO;
38 import org.splat.service.dto.StepDTO;
39 import org.splat.service.technical.IndexService;
40 import org.splat.som.Step;
41 import org.splat.util.BeanHelper;
42 import org.springframework.transaction.annotation.Transactional;
45 * Scenario service implementation.
47 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
49 public class ScenarioServiceImpl implements ScenarioService {
52 * Logger for this class.
54 protected final static Logger LOG = Logger
55 .getLogger(ScenarioServiceImpl.class);
58 * Injected index service.
60 private IndexService _indexService;
62 * Injected step service.
64 private StepService _stepService;
66 * Injected study service.
68 private StudyService _studyService;
70 * Injected publication service.
72 private PublicationService _publicationService;
74 * Injected project element service.
76 private ProjectElementService _projectElementService;
78 * Injected knowledge element DAO.
80 private KnowledgeElementDAO _knowledgeElementDAO;
82 * Injected scenario DAO.
84 private ScenarioDAO _scenarioDAO;
89 private StudyDAO _studyDAO;
92 * Injected knowledge element service.
94 private KnowledgeElementTypeService _knowledgeElementTypeService;
97 * Injected user service.
99 private UserService _userService;
104 private UserDAO _userDAO;
107 * Injected knowledge element type DAO.
109 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
112 * Injected simulation context service.
114 private SimulationContextService _simulationContextService;
117 * Get the projectElementService.
119 * @return the projectElementService
121 public ProjectElementService getProjectElementService() {
122 return _projectElementService;
126 * Set the projectElementService.
128 * @param projectElementService
129 * the projectElementService to set
131 public void setProjectElementService(
132 final ProjectElementService projectElementService) {
133 _projectElementService = projectElementService;
137 * Get the publicationService.
139 * @return the publicationService
141 public PublicationService getPublicationService() {
142 return _publicationService;
146 * Set the publicationService.
148 * @param publicationService
149 * the publicationService to set
151 public void setPublicationService(
152 final PublicationService publicationService) {
153 _publicationService = publicationService;
157 * Get the stepService.
159 * @return the stepService
161 public StepService getStepService() {
166 * Set the stepService.
169 * the stepService to set
171 public void setStepService(final StepService stepService) {
172 _stepService = stepService;
178 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
181 public List<StepDTO> getScenarioInfo(final long scenarioId) {
182 List<StepDTO> res = new ArrayList<StepDTO>();
183 Scenario scen = getScenarioDAO().get(scenarioId);
184 if (LOG.isDebugEnabled()) {
185 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
186 + scen.getDocums().size());
188 Step[] steps = getProjectElementService().getSteps(scen);
191 for (Step step : steps) {
192 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
194 if (LOG.isDebugEnabled()) {
195 LOG.debug("Step[" + stepDTO.getNumber()
196 + "]: Number of documents: "
197 + step.getDocuments().size());
199 for (Publication tag : step.getDocuments()) {
200 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
202 char aState = tag.getIsnew();
203 docDTO.addFile(tag.value().getFile().getRelativePath(), aState);
204 for (Relation rel : tag.value().getRelations(
205 ConvertsRelation.class)) {
206 File aFile = ((ConvertsRelation) rel).getTo();
207 docDTO.addFile(aFile.getRelativePath(), aState);
215 * Create a new study with one scenario and "product" simulation context.
218 * the study properties
220 * the scenario properties
222 * the "product" simulation context properties
223 * @return the created study
224 * @throws MissedPropertyException
225 * if a mandatory property is missed
226 * @throws InvalidPropertyException
227 * if a property is invalid
228 * @throws MultiplyDefinedException
229 * if some property occurs several times
232 public Study createStudy(final Study.Properties sprop,
233 final Scenario.Properties oprop,
234 final SimulationContext.Properties cprop)
235 throws MissedPropertyException, InvalidPropertyException,
236 MultiplyDefinedException {
237 Study study = getStudyService().createStudy(sprop);
238 addScenario(study, oprop);
239 if (cprop.getIndex() == 0) { // Input of new project context
240 cprop.setType(getSimulationContextService().selectType("product"))
241 .setValue(cprop.getValue());
242 getStudyService().addProjectContext(study, cprop);
243 } else { // Selection of existing project context
244 SimulationContext context = getSimulationContextService()
245 .selectSimulationContext(cprop.getIndex());
246 getStudyService().addProjectContext(study, context);
254 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
255 * org.splat.dal.bo.som.KnowledgeElement.Properties)
258 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
259 final KnowledgeElement.Properties kprop)
260 throws MissedPropertyException, InvalidPropertyException,
261 MultiplyDefinedException {
262 KnowledgeElement kelm = null;
264 long aScenarioId = aScenarioDTO.getIndex();
265 if (LOG.isDebugEnabled()) {
266 LOG.debug("Add a knowledge element to the scenario #"
269 // Get the persistent scenario.
270 Scenario aScenario = getScenarioDAO().get(aScenarioId);
271 // Get persistent objects for creating a new knowledge.
272 // TODO: Actions must use DTO instead of persistent objects.
273 getUserDAO().merge(kprop.getAuthor());
274 getKnowledgeElementTypeDAO().merge(kprop.getType());
275 // Create a transient knowledge element related to the given scenario.
276 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
277 // Save the new knowledge in the database.
278 getKnowledgeElementDAO().create(kelm);
279 // Update scenario transient data.
280 if (kelm.getType().equals("usecase")) {
281 aScenarioDTO.setUcase(kelm);
282 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
283 aScenarioDTO.getKnowledgeElementsList().add(kelm);
286 // Load the workflow for the parent study to take into account
287 // all study actors durng reindexing.
288 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
290 // Update the lucene index of knowledge elements.
291 getIndexService().add(kelm);
292 if (LOG.isDebugEnabled()) {
293 LOG.debug("A knowledge element #" + kelm.getIndex()
294 + " is added to the scenario #" + aScenario.getIndex());
296 } catch (IOException error) {
297 LOG.error("Unable to index the knowedge element '"
298 + kelm.getIndex() + "', reason:", error);
306 * Update the scenario in the database.
309 * the scenario to update
310 * @return true if updating succeeded
313 private boolean update(final Scenario aScenario) {
314 boolean isOk = false;
316 getScenarioDAO().update(aScenario); // Update of relational base
318 } catch (Exception error) {
319 LOG.error("Unable to re-index the knowledge element '"
320 + aScenario.getIndex() + "', reason:", error);
328 * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
330 public void checkin(final Scenario aScenario) {
331 aScenario.setUser(null);
332 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
333 getScenarioDAO().update(aScenario);
339 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
341 public boolean checkout(final Scenario aScenario, final User user) {
342 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user)) {
346 aScenario.setUser(user);
347 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
348 getScenarioDAO().update(aScenario);
355 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
357 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
358 Scenario base = (Scenario) lastep.getOwner();
359 Step[] from = getProjectElementService().getSteps(base);
360 Step[] to = getProjectElementService().getSteps(scenario);
361 for (int i = 0; i < from.length; i++) {
363 if (step.getNumber() > lastep.getNumber()) {
367 List<Publication> docs = step.getAllDocuments();
368 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
369 Publication doc = getPublicationService().copy(j.next(),
370 scenario); // Creation of a new reference to the document
371 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
372 getStepService().add(to[i], doc);
374 List<SimulationContext> ctex = step.getAllSimulationContexts();
375 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
376 getStepService().addSimulationContext(to[i], j.next());
384 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
386 public boolean isEmpty(final Scenario scenario) {
387 Step[] mystep = getProjectElementService().getSteps(scenario);
388 boolean isEmp = true;
389 for (int i = 0; i < mystep.length; i++) {
390 if (mystep[i].isStarted()) {
402 public boolean isFinished(final Scenario scenario) {
403 Step[] mystep = getProjectElementService().getSteps(scenario);
404 boolean notempty = false; // If this is empty, this is not finished
405 for (int i = 0; i < mystep.length; i++) {
406 if (!mystep[i].isStarted()) {
409 if (!mystep[i].isFinished()) {
420 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
423 public Scenario addScenario(final Study aStudy,
424 final Scenario.Properties sprop) throws MissedPropertyException,
425 InvalidPropertyException, MultiplyDefinedException {
426 if (sprop.getManager() == null) {
427 sprop.setManager(aStudy.getAuthor());
430 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
431 if (sprop.getBaseStep() != null) {
432 copyContentsUpTo(scenario, sprop.getBaseStep());
434 Scenario previous = sprop.getInsertAfter();
436 if (previous == null) {
437 aStudy.getScenariiList().add(scenario);
439 aStudy.getScenariiList().add(
440 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
442 getStudyDAO().update(aStudy); // No need to update the Lucene index
443 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
444 if (sprop.getBaseStep() != null) {
445 // No need to update the Knowledge Element index as Knowledge Elements are not copied
446 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
448 KnowledgeElementType ucase = getKnowledgeElementTypeService()
449 .selectType("usecase");
450 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
451 User admin = getUserService().selectUser(1); // First user created when creating the database
452 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
453 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
455 addKnowledgeElement(scenario, kprop);
460 * Remove a knowledge element from a scenario.
465 * the knowledge element to remove
466 * @return true if removal succeeded
468 public boolean removeKnowledgeElement(final Scenario scenario,
469 final KnowledgeElement kelm) {
470 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
474 boolean done = scenario.getKnowledgeElements().remove(torem);
476 // Update of my transient data
477 // RKV: These transient data are not used indeed.
478 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
479 // RKV: kelm.getType().getIndex());
480 // RKV: kelms.remove(torem);
481 if (scenario.getKnowledgeElementsList() != null) {
482 scenario.getKnowledgeElementsList().remove(torem);
484 getScenarioDAO().update(scenario);
485 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
493 * Get the knowledgeElementDAO.
495 * @return the knowledgeElementDAO
497 public KnowledgeElementDAO getKnowledgeElementDAO() {
498 return _knowledgeElementDAO;
502 * Set the knowledgeElementDAO.
504 * @param knowledgeElementDAO
505 * the knowledgeElementDAO to set
507 public void setKnowledgeElementDAO(
508 final KnowledgeElementDAO knowledgeElementDAO) {
509 _knowledgeElementDAO = knowledgeElementDAO;
513 * Get the indexService.
515 * @return the indexService
517 public IndexService getIndexService() {
518 return _indexService;
522 * Set the indexService.
524 * @param indexService
525 * the indexService to set
527 public void setIndexService(final IndexService indexService) {
528 _indexService = indexService;
532 * Get the scenarioDAO.
534 * @return the scenarioDAO
536 public ScenarioDAO getScenarioDAO() {
541 * Set the scenarioDAO.
544 * the scenarioDAO to set
546 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
547 _scenarioDAO = scenarioDAO;
553 * @return the studyDAO
555 public StudyDAO getStudyDAO() {
563 * the studyDAO to set
565 public void setStudyDAO(final StudyDAO studyDAO) {
566 _studyDAO = studyDAO;
570 * Get the knowledgeElementTypeService.
572 * @return the knowledgeElementTypeService
574 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
575 return _knowledgeElementTypeService;
579 * Set the knowledgeElementTypeService.
581 * @param knowledgeElementTypeService
582 * the knowledgeElementTypeService to set
584 public void setKnowledgeElementTypeService(
585 final KnowledgeElementTypeService knowledgeElementTypeService) {
586 _knowledgeElementTypeService = knowledgeElementTypeService;
590 * Get the studyService.
592 * @return the studyService
594 public StudyService getStudyService() {
595 return _studyService;
599 * Set the studyService.
601 * @param studyService
602 * the studyService to set
604 public void setStudyService(final StudyService studyService) {
605 _studyService = studyService;
609 * Get the userService.
611 * @return the userService
613 public UserService getUserService() {
618 * Set the userService.
621 * the userService to set
623 public void setUserService(final UserService userService) {
624 _userService = userService;
630 * @return the userDAO
632 public UserDAO getUserDAO() {
642 public void setUserDAO(final UserDAO userDAO) {
647 * Get the knowledgeElementTypeDAO.
649 * @return the knowledgeElementTypeDAO
651 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
652 return _knowledgeElementTypeDAO;
656 * Set the knowledgeElementTypeDAO.
658 * @param knowledgeElementTypeDAO
659 * the knowledgeElementTypeDAO to set
661 public void setKnowledgeElementTypeDAO(
662 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
663 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
667 * Get the simulationContextService.
669 * @return the simulationContextService
671 public SimulationContextService getSimulationContextService() {
672 return _simulationContextService;
676 * Set the simulationContextService.
678 * @param simulationContextService
679 * the simulationContextService to set
681 public void setSimulationContextService(
682 final SimulationContextService simulationContextService) {
683 _simulationContextService = simulationContextService;