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.service.technical.ProjectSettingsService;
41 import org.splat.som.Step;
42 import org.splat.util.BeanHelper;
43 import org.springframework.transaction.annotation.Transactional;
46 * Scenario service implementation.
48 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
50 public class ScenarioServiceImpl implements ScenarioService {
53 * Logger for this class.
55 protected final static Logger LOG = Logger
56 .getLogger(ScenarioServiceImpl.class);
59 * Injected index service.
61 private IndexService _indexService;
63 * Injected step service.
65 private StepService _stepService;
67 * Injected study service.
69 private StudyService _studyService;
71 * Injected publication service.
73 private PublicationService _publicationService;
75 * Injected project element service.
77 private ProjectElementService _projectElementService;
79 * Injected knowledge element DAO.
81 private KnowledgeElementDAO _knowledgeElementDAO;
83 * Injected scenario DAO.
85 private ScenarioDAO _scenarioDAO;
90 private StudyDAO _studyDAO;
93 * Injected knowledge element service.
95 private KnowledgeElementTypeService _knowledgeElementTypeService;
98 * Injected user service.
100 private UserService _userService;
105 private UserDAO _userDAO;
108 * Injected knowledge element type DAO.
110 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
113 * Injected simulation context service.
115 private SimulationContextService _simulationContextService;
118 * Injected project service.
120 private ProjectSettingsService _projectSettings;
123 * Get the projectElementService.
125 * @return the projectElementService
127 public ProjectElementService getProjectElementService() {
128 return _projectElementService;
132 * Set the projectElementService.
134 * @param projectElementService
135 * the projectElementService to set
137 public void setProjectElementService(
138 final ProjectElementService projectElementService) {
139 _projectElementService = projectElementService;
143 * Get the publicationService.
145 * @return the publicationService
147 public PublicationService getPublicationService() {
148 return _publicationService;
152 * Set the publicationService.
154 * @param publicationService
155 * the publicationService to set
157 public void setPublicationService(
158 final PublicationService publicationService) {
159 _publicationService = publicationService;
163 * Get the stepService.
165 * @return the stepService
167 public StepService getStepService() {
172 * Set the stepService.
175 * the stepService to set
177 public void setStepService(final StepService stepService) {
178 _stepService = stepService;
184 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
187 public List<StepDTO> getScenarioInfo(final long scenarioId) {
188 List<StepDTO> res = new ArrayList<StepDTO>();
189 // Get the scenario from the database by id
190 Scenario scen = getScenarioDAO().get(scenarioId);
191 if (LOG.isDebugEnabled()) {
192 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
193 + scen.getDocums().size());
195 // Get activities of the scenario
196 Step[] steps = getProjectElementService().getSteps(scen);
199 String docType, fileFormat;
202 // For each activity create a step DTO and add it to the result list
203 for (Step step : steps) {
204 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
206 if (LOG.isDebugEnabled()) {
207 LOG.debug("Step[" + stepDTO.getNumber()
208 + "]: Number of documents: "
209 + step.getDocuments().size());
211 // For each publication of the activity create a document DTO.
212 // Each file is considered as a source file.
213 for (Publication tag : step.getDocuments()) {
214 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
216 char aState = tag.getIsnew();
217 docType = tag.value().getType().getName();
218 // For each file of the document create a file DTO
219 // Process source file of the document
220 fileFormat = tag.value().getFile().getFormat();
221 doImport = getProjectSettings().doImport(docType, fileFormat);
222 if (doImport && (!tag.isOutdated())) {
223 processing = "file-import";
225 processing = "file-download";
227 docDTO.addFile(tag.value().getFile().getRelativePath(), aState,
229 // Process all exported files
230 for (Relation rel : tag.value().getRelations(
231 ConvertsRelation.class)) {
232 File aFile = ((ConvertsRelation) rel).getTo();
233 fileFormat = aFile.getFormat();
234 doImport = getProjectSettings().doImport(docType,
236 if (doImport && (!tag.isOutdated())) {
237 processing = "file-import";
239 processing = "file-download";
241 docDTO.addFile(aFile.getRelativePath(), aState, processing,
250 * Create a new study with one scenario and "product" simulation context.
253 * the study properties
255 * the scenario properties
257 * the "product" simulation context properties
258 * @return the created study
259 * @throws MissedPropertyException
260 * if a mandatory property is missed
261 * @throws InvalidPropertyException
262 * if a property is invalid
263 * @throws MultiplyDefinedException
264 * if some property occurs several times
267 public Study createStudy(final Study.Properties sprop,
268 final Scenario.Properties oprop,
269 final SimulationContext.Properties cprop)
270 throws MissedPropertyException, InvalidPropertyException,
271 MultiplyDefinedException {
272 Study study = getStudyService().createStudy(sprop);
273 addScenario(study, oprop);
274 if (cprop.getIndex() == 0) { // Input of new project context
275 cprop.setType(getSimulationContextService().selectType("product"))
276 .setValue(cprop.getValue());
277 getStudyService().addProjectContext(study, cprop);
278 } else { // Selection of existing project context
279 SimulationContext context = getSimulationContextService()
280 .selectSimulationContext(cprop.getIndex());
281 getStudyService().addProjectContext(study, context);
289 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
290 * org.splat.dal.bo.som.KnowledgeElement.Properties)
293 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
294 final KnowledgeElement.Properties kprop)
295 throws MissedPropertyException, InvalidPropertyException,
296 MultiplyDefinedException {
297 KnowledgeElement kelm = null;
299 long aScenarioId = aScenarioDTO.getIndex();
300 if (LOG.isDebugEnabled()) {
301 LOG.debug("Add a knowledge element to the scenario #"
304 // Get the persistent scenario.
305 Scenario aScenario = getScenarioDAO().get(aScenarioId);
306 // Get persistent objects for creating a new knowledge.
307 // TODO: Actions must use DTO instead of persistent objects.
308 getUserDAO().merge(kprop.getAuthor());
309 getKnowledgeElementTypeDAO().merge(kprop.getType());
310 // Create a transient knowledge element related to the given scenario.
311 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
312 // Save the new knowledge in the database.
313 getKnowledgeElementDAO().create(kelm);
314 // Update scenario transient data.
315 if (kelm.getType().equals("usecase")) {
316 aScenarioDTO.setUcase(kelm);
317 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
318 aScenarioDTO.getKnowledgeElementsList().add(kelm);
321 // Load the workflow for the parent study to take into account
322 // all study actors durng reindexing.
323 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
325 // Update the lucene index of knowledge elements.
326 getIndexService().add(kelm);
327 if (LOG.isDebugEnabled()) {
328 LOG.debug("A knowledge element #" + kelm.getIndex()
329 + " is added to the scenario #" + aScenario.getIndex());
331 } catch (IOException error) {
332 LOG.error("Unable to index the knowedge element '"
333 + kelm.getIndex() + "', reason:", error);
341 * Update the scenario in the database.
344 * the scenario to update
345 * @return true if updating succeeded
348 private boolean update(final Scenario aScenario) {
349 boolean isOk = false;
351 getScenarioDAO().update(aScenario); // Update of relational base
353 } catch (Exception error) {
354 LOG.error("Unable to re-index the knowledge element '"
355 + aScenario.getIndex() + "', reason:", error);
363 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
365 public void checkin(final long scenId, final long userId,
366 final List<StepDTO> scInfo) {
373 * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
375 public void checkin(final Scenario aScenario) {
376 aScenario.setUser(null);
377 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
378 getScenarioDAO().update(aScenario);
384 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
386 public boolean checkout(final Scenario aScenario, final User user) {
387 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
390 aScenario.setUser(user);
391 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
392 getScenarioDAO().update(aScenario);
400 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
402 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
403 Scenario base = (Scenario) lastep.getOwner();
404 Step[] from = getProjectElementService().getSteps(base);
405 Step[] to = getProjectElementService().getSteps(scenario);
406 for (int i = 0; i < from.length; i++) {
408 if (step.getNumber() > lastep.getNumber()) {
412 List<Publication> docs = step.getAllDocuments();
413 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
414 Publication doc = getPublicationService().copy(j.next(),
415 scenario); // Creation of a new reference to the document
416 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
417 getStepService().add(to[i], doc);
419 List<SimulationContext> ctex = step.getAllSimulationContexts();
420 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
421 getStepService().addSimulationContext(to[i], j.next());
429 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
431 public boolean isEmpty(final Scenario scenario) {
432 Step[] mystep = getProjectElementService().getSteps(scenario);
433 boolean isEmp = true;
434 for (int i = 0; i < mystep.length; i++) {
435 if (mystep[i].isStarted()) {
447 public boolean isFinished(final Scenario scenario) {
448 Step[] mystep = getProjectElementService().getSteps(scenario);
449 boolean notempty = false; // If this is empty, this is not finished
450 for (int i = 0; i < mystep.length; i++) {
451 if (!mystep[i].isStarted()) {
454 if (!mystep[i].isFinished()) {
465 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
468 public Scenario addScenario(final Study aStudy,
469 final Scenario.Properties sprop) throws MissedPropertyException,
470 InvalidPropertyException, MultiplyDefinedException {
471 if (sprop.getManager() == null) {
472 sprop.setManager(aStudy.getAuthor());
475 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
476 if (sprop.getBaseStep() != null) {
477 copyContentsUpTo(scenario, sprop.getBaseStep());
479 Scenario previous = sprop.getInsertAfter();
481 if (previous == null) {
482 aStudy.getScenariiList().add(scenario);
484 aStudy.getScenariiList().add(
485 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
487 getStudyDAO().update(aStudy); // No need to update the Lucene index
488 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
489 if (sprop.getBaseStep() != null) {
490 // No need to update the Knowledge Element index as Knowledge Elements are not copied
491 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
493 KnowledgeElementType ucase = getKnowledgeElementTypeService()
494 .selectType("usecase");
495 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
496 User admin = getUserService().selectUser(1); // First user created when creating the database
497 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
498 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
500 addKnowledgeElement(scenario, kprop);
505 * Remove a knowledge element from a scenario.
510 * the knowledge element to remove
511 * @return true if removal succeeded
513 public boolean removeKnowledgeElement(final Scenario scenario,
514 final KnowledgeElement kelm) {
515 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
519 boolean done = scenario.getKnowledgeElements().remove(torem);
521 // Update of my transient data
522 // RKV: These transient data are not used indeed.
523 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
524 // RKV: kelm.getType().getIndex());
525 // RKV: kelms.remove(torem);
526 if (scenario.getKnowledgeElementsList() != null) {
527 scenario.getKnowledgeElementsList().remove(torem);
529 getScenarioDAO().update(scenario);
530 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
538 * Get the knowledgeElementDAO.
540 * @return the knowledgeElementDAO
542 public KnowledgeElementDAO getKnowledgeElementDAO() {
543 return _knowledgeElementDAO;
547 * Set the knowledgeElementDAO.
549 * @param knowledgeElementDAO
550 * the knowledgeElementDAO to set
552 public void setKnowledgeElementDAO(
553 final KnowledgeElementDAO knowledgeElementDAO) {
554 _knowledgeElementDAO = knowledgeElementDAO;
558 * Get the indexService.
560 * @return the indexService
562 public IndexService getIndexService() {
563 return _indexService;
567 * Set the indexService.
569 * @param indexService
570 * the indexService to set
572 public void setIndexService(final IndexService indexService) {
573 _indexService = indexService;
577 * Get the scenarioDAO.
579 * @return the scenarioDAO
581 public ScenarioDAO getScenarioDAO() {
586 * Set the scenarioDAO.
589 * the scenarioDAO to set
591 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
592 _scenarioDAO = scenarioDAO;
598 * @return the studyDAO
600 public StudyDAO getStudyDAO() {
608 * the studyDAO to set
610 public void setStudyDAO(final StudyDAO studyDAO) {
611 _studyDAO = studyDAO;
615 * Get the knowledgeElementTypeService.
617 * @return the knowledgeElementTypeService
619 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
620 return _knowledgeElementTypeService;
624 * Set the knowledgeElementTypeService.
626 * @param knowledgeElementTypeService
627 * the knowledgeElementTypeService to set
629 public void setKnowledgeElementTypeService(
630 final KnowledgeElementTypeService knowledgeElementTypeService) {
631 _knowledgeElementTypeService = knowledgeElementTypeService;
635 * Get the studyService.
637 * @return the studyService
639 public StudyService getStudyService() {
640 return _studyService;
644 * Set the studyService.
646 * @param studyService
647 * the studyService to set
649 public void setStudyService(final StudyService studyService) {
650 _studyService = studyService;
654 * Get the userService.
656 * @return the userService
658 public UserService getUserService() {
663 * Set the userService.
666 * the userService to set
668 public void setUserService(final UserService userService) {
669 _userService = userService;
675 * @return the userDAO
677 public UserDAO getUserDAO() {
687 public void setUserDAO(final UserDAO userDAO) {
692 * Get the knowledgeElementTypeDAO.
694 * @return the knowledgeElementTypeDAO
696 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
697 return _knowledgeElementTypeDAO;
701 * Set the knowledgeElementTypeDAO.
703 * @param knowledgeElementTypeDAO
704 * the knowledgeElementTypeDAO to set
706 public void setKnowledgeElementTypeDAO(
707 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
708 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
712 * Get the simulationContextService.
714 * @return the simulationContextService
716 public SimulationContextService getSimulationContextService() {
717 return _simulationContextService;
721 * Set the simulationContextService.
723 * @param simulationContextService
724 * the simulationContextService to set
726 public void setSimulationContextService(
727 final SimulationContextService simulationContextService) {
728 _simulationContextService = simulationContextService;
732 * Get project settings.
734 * @return Project settings service
736 private ProjectSettingsService getProjectSettings() {
737 return _projectSettings;
741 * Set project settings service.
743 * @param projectSettingsService
744 * project settings service
746 public void setProjectSettings(
747 final ProjectSettingsService projectSettingsService) {
748 _projectSettings = projectSettingsService;