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(final PublicationService publicationService) {
152 _publicationService = publicationService;
156 * Get the stepService.
158 * @return the stepService
160 public StepService getStepService() {
165 * Set the stepService.
168 * the stepService to set
170 public void setStepService(final StepService stepService) {
171 _stepService = stepService;
176 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
179 public List<StepDTO> getScenarioInfo(final long scenarioId) {
180 List<StepDTO> res = new ArrayList<StepDTO>();
181 Scenario scen = getScenarioDAO().get(scenarioId);
182 Step[] steps = getProjectElementService().getSteps(scen);
185 for (Step step: steps) {
186 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
188 for (Publication tag: step.getDocuments()) {
189 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value().getTitle());
190 char aState = tag.getIsnew();
191 docDTO.addFile(tag.value().getFile().getRelativePath(), aState);
192 for(Relation rel: tag.value().getRelations(ConvertsRelation.class)) {
193 File aFile = ((ConvertsRelation)rel).getTo();
194 docDTO.addFile(aFile.getRelativePath(), aState);
202 * Create a new study with one scenario and "product" simulation context.
205 * the study properties
207 * the scenario properties
209 * the "product" simulation context properties
210 * @return the created study
211 * @throws MissedPropertyException
212 * if a mandatory property is missed
213 * @throws InvalidPropertyException
214 * if a property is invalid
215 * @throws MultiplyDefinedException
216 * if some property occurs several times
219 public Study createStudy(final Study.Properties sprop, final Scenario.Properties oprop,
220 final SimulationContext.Properties cprop) throws MissedPropertyException,
221 InvalidPropertyException, MultiplyDefinedException {
222 Study study = getStudyService().createStudy(sprop);
223 addScenario(study, oprop);
224 if (cprop.getIndex() == 0) { // Input of new project context
225 cprop.setType(getSimulationContextService().selectType("product"))
226 .setValue(cprop.getValue());
227 getStudyService().addProjectContext(study, cprop);
228 } else { // Selection of existing project context
229 SimulationContext context = getSimulationContextService()
230 .selectSimulationContext(cprop.getIndex());
231 getStudyService().addProjectContext(study, context);
239 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
240 * org.splat.dal.bo.som.KnowledgeElement.Properties)
243 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
244 final KnowledgeElement.Properties kprop) throws MissedPropertyException,
245 InvalidPropertyException, MultiplyDefinedException {
246 KnowledgeElement kelm = null;
248 long aScenarioId = aScenarioDTO.getIndex();
249 if (LOG.isDebugEnabled()) {
250 LOG.debug("Add a knowledge element to the scenario #"
253 // Get the persistent scenario.
254 Scenario aScenario = getScenarioDAO().get(aScenarioId);
255 // Get persistent objects for creating a new knowledge.
256 // TODO: Actions must use DTO instead of persistent objects.
257 getUserDAO().merge(kprop.getAuthor());
258 getKnowledgeElementTypeDAO().merge(kprop.getType());
259 // Create a transient knowledge element related to the given scenario.
260 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
261 // Save the new knowledge in the database.
262 getKnowledgeElementDAO().create(kelm);
263 // Update scenario transient data.
264 if (kelm.getType().equals("usecase")) {
265 aScenarioDTO.setUcase(kelm);
266 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
267 aScenarioDTO.getKnowledgeElementsList().add(kelm);
270 // Load the workflow for the parent study to take into account
271 // all study actors durng reindexing.
272 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
274 // Update the lucene index of knowledge elements.
275 getIndexService().add(kelm);
276 if (LOG.isDebugEnabled()) {
277 LOG.debug("A knowledge element #" + kelm.getIndex()
278 + " is added to the scenario #" + aScenario.getIndex());
280 } catch (IOException error) {
281 LOG.error("Unable to index the knowedge element '"
282 + kelm.getIndex() + "', reason:", error);
290 * Update the scenario in the database.
293 * the scenario to update
294 * @return true if updating succeeded
297 private boolean update(final Scenario aScenario) {
298 boolean isOk = false;
300 getScenarioDAO().update(aScenario); // Update of relational base
302 } catch (Exception error) {
303 LOG.error("Unable to re-index the knowledge element '"
304 + aScenario.getIndex() + "', reason:", error);
312 * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
314 public void checkin(final Scenario aScenario) {
315 aScenario.setUser(null);
316 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
317 getScenarioDAO().update(aScenario);
323 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
325 public boolean checkout(final Scenario aScenario, final User user) {
326 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user)) {
330 aScenario.setUser(user);
331 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
332 getScenarioDAO().update(aScenario);
339 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
341 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
342 Scenario base = (Scenario) lastep.getOwner();
343 Step[] from = getProjectElementService().getSteps(base);
344 Step[] to = getProjectElementService().getSteps(scenario);
345 for (int i = 0; i < from.length; i++) {
347 if (step.getNumber() > lastep.getNumber()) {
351 List<Publication> docs = step.getAllDocuments();
352 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
353 Publication doc = getPublicationService().copy(j.next(),
354 scenario); // Creation of a new reference to the document
355 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
356 getStepService().add(to[i], doc);
358 List<SimulationContext> ctex = step.getAllSimulationContexts();
359 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
360 getStepService().addSimulationContext(to[i], j.next());
368 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
370 public boolean isEmpty(final Scenario scenario) {
371 Step[] mystep = getProjectElementService().getSteps(scenario);
372 boolean isEmp = true;
373 for (int i = 0; i < mystep.length; i++) {
374 if (mystep[i].isStarted()) {
386 public boolean isFinished(final Scenario scenario) {
387 Step[] mystep = getProjectElementService().getSteps(scenario);
388 boolean notempty = false; // If this is empty, this is not finished
389 for (int i = 0; i < mystep.length; i++) {
390 if (!mystep[i].isStarted()) {
393 if (!mystep[i].isFinished()) {
404 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
407 public Scenario addScenario(final Study aStudy, final Scenario.Properties sprop)
408 throws MissedPropertyException, InvalidPropertyException,
409 MultiplyDefinedException {
410 if (sprop.getManager() == null) {
411 sprop.setManager(aStudy.getAuthor());
414 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
415 if (sprop.getBaseStep() != null) {
416 copyContentsUpTo(scenario, sprop.getBaseStep());
418 Scenario previous = sprop.getInsertAfter();
420 if (previous == null) {
421 aStudy.getScenariiList().add(scenario);
423 aStudy.getScenariiList().add(
424 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
426 getStudyDAO().update(aStudy); // No need to update the Lucene index
427 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
428 if (sprop.getBaseStep() != null) {
429 // No need to update the Knowledge Element index as Knowledge Elements are not copied
430 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
432 KnowledgeElementType ucase = getKnowledgeElementTypeService()
433 .selectType("usecase");
434 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
435 User admin = getUserService().selectUser(1); // First user created when creating the database
436 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
437 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
439 addKnowledgeElement(scenario, kprop);
444 * Remove a knowledge element from a scenario.
449 * the knowledge element to remove
450 * @return true if removal succeeded
452 public boolean removeKnowledgeElement(final Scenario scenario,
453 final KnowledgeElement kelm) {
454 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
458 boolean done = scenario.getKnowledgeElements().remove(torem);
460 // Update of my transient data
461 // RKV: These transient data are not used indeed.
462 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
463 // RKV: kelm.getType().getIndex());
464 // RKV: kelms.remove(torem);
465 if (scenario.getKnowledgeElementsList() != null) {
466 scenario.getKnowledgeElementsList().remove(torem);
468 getScenarioDAO().update(scenario);
469 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
477 * Get the knowledgeElementDAO.
479 * @return the knowledgeElementDAO
481 public KnowledgeElementDAO getKnowledgeElementDAO() {
482 return _knowledgeElementDAO;
486 * Set the knowledgeElementDAO.
488 * @param knowledgeElementDAO
489 * the knowledgeElementDAO to set
491 public void setKnowledgeElementDAO(final KnowledgeElementDAO knowledgeElementDAO) {
492 _knowledgeElementDAO = knowledgeElementDAO;
496 * Get the indexService.
498 * @return the indexService
500 public IndexService getIndexService() {
501 return _indexService;
505 * Set the indexService.
507 * @param indexService
508 * the indexService to set
510 public void setIndexService(final IndexService indexService) {
511 _indexService = indexService;
515 * Get the scenarioDAO.
517 * @return the scenarioDAO
519 public ScenarioDAO getScenarioDAO() {
524 * Set the scenarioDAO.
527 * the scenarioDAO to set
529 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
530 _scenarioDAO = scenarioDAO;
536 * @return the studyDAO
538 public StudyDAO getStudyDAO() {
546 * the studyDAO to set
548 public void setStudyDAO(final StudyDAO studyDAO) {
549 _studyDAO = studyDAO;
553 * Get the knowledgeElementTypeService.
555 * @return the knowledgeElementTypeService
557 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
558 return _knowledgeElementTypeService;
562 * Set the knowledgeElementTypeService.
564 * @param knowledgeElementTypeService
565 * the knowledgeElementTypeService to set
567 public void setKnowledgeElementTypeService(
568 final KnowledgeElementTypeService knowledgeElementTypeService) {
569 _knowledgeElementTypeService = knowledgeElementTypeService;
573 * Get the studyService.
575 * @return the studyService
577 public StudyService getStudyService() {
578 return _studyService;
582 * Set the studyService.
584 * @param studyService
585 * the studyService to set
587 public void setStudyService(final StudyService studyService) {
588 _studyService = studyService;
592 * Get the userService.
594 * @return the userService
596 public UserService getUserService() {
601 * Set the userService.
604 * the userService to set
606 public void setUserService(final UserService userService) {
607 _userService = userService;
613 * @return the userDAO
615 public UserDAO getUserDAO() {
625 public void setUserDAO(final UserDAO userDAO) {
630 * Get the knowledgeElementTypeDAO.
632 * @return the knowledgeElementTypeDAO
634 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
635 return _knowledgeElementTypeDAO;
639 * Set the knowledgeElementTypeDAO.
641 * @param knowledgeElementTypeDAO
642 * the knowledgeElementTypeDAO to set
644 public void setKnowledgeElementTypeDAO(
645 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
646 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
650 * Get the simulationContextService.
652 * @return the simulationContextService
654 public SimulationContextService getSimulationContextService() {
655 return _simulationContextService;
659 * Set the simulationContextService.
661 * @param simulationContextService
662 * the simulationContextService to set
664 public void setSimulationContextService(
665 final SimulationContextService simulationContextService) {
666 _simulationContextService = simulationContextService;