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(org.splat.dal.bo.som.Scenario)
365 public void checkin(final Scenario aScenario) {
366 aScenario.setUser(null);
367 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
368 getScenarioDAO().update(aScenario);
374 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
376 public boolean checkout(final Scenario aScenario, final User user) {
377 if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user)) {
381 aScenario.setUser(user);
382 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
383 getScenarioDAO().update(aScenario);
390 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
392 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
393 Scenario base = (Scenario) lastep.getOwner();
394 Step[] from = getProjectElementService().getSteps(base);
395 Step[] to = getProjectElementService().getSteps(scenario);
396 for (int i = 0; i < from.length; i++) {
398 if (step.getNumber() > lastep.getNumber()) {
402 List<Publication> docs = step.getAllDocuments();
403 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
404 Publication doc = getPublicationService().copy(j.next(),
405 scenario); // Creation of a new reference to the document
406 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
407 getStepService().add(to[i], doc);
409 List<SimulationContext> ctex = step.getAllSimulationContexts();
410 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
411 getStepService().addSimulationContext(to[i], j.next());
419 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
421 public boolean isEmpty(final Scenario scenario) {
422 Step[] mystep = getProjectElementService().getSteps(scenario);
423 boolean isEmp = true;
424 for (int i = 0; i < mystep.length; i++) {
425 if (mystep[i].isStarted()) {
437 public boolean isFinished(final Scenario scenario) {
438 Step[] mystep = getProjectElementService().getSteps(scenario);
439 boolean notempty = false; // If this is empty, this is not finished
440 for (int i = 0; i < mystep.length; i++) {
441 if (!mystep[i].isStarted()) {
444 if (!mystep[i].isFinished()) {
455 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
458 public Scenario addScenario(final Study aStudy,
459 final Scenario.Properties sprop) throws MissedPropertyException,
460 InvalidPropertyException, MultiplyDefinedException {
461 if (sprop.getManager() == null) {
462 sprop.setManager(aStudy.getAuthor());
465 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
466 if (sprop.getBaseStep() != null) {
467 copyContentsUpTo(scenario, sprop.getBaseStep());
469 Scenario previous = sprop.getInsertAfter();
471 if (previous == null) {
472 aStudy.getScenariiList().add(scenario);
474 aStudy.getScenariiList().add(
475 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
477 getStudyDAO().update(aStudy); // No need to update the Lucene index
478 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
479 if (sprop.getBaseStep() != null) {
480 // No need to update the Knowledge Element index as Knowledge Elements are not copied
481 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
483 KnowledgeElementType ucase = getKnowledgeElementTypeService()
484 .selectType("usecase");
485 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
486 User admin = getUserService().selectUser(1); // First user created when creating the database
487 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
488 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
490 addKnowledgeElement(scenario, kprop);
495 * Remove a knowledge element from a scenario.
500 * the knowledge element to remove
501 * @return true if removal succeeded
503 public boolean removeKnowledgeElement(final Scenario scenario,
504 final KnowledgeElement kelm) {
505 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
509 boolean done = scenario.getKnowledgeElements().remove(torem);
511 // Update of my transient data
512 // RKV: These transient data are not used indeed.
513 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
514 // RKV: kelm.getType().getIndex());
515 // RKV: kelms.remove(torem);
516 if (scenario.getKnowledgeElementsList() != null) {
517 scenario.getKnowledgeElementsList().remove(torem);
519 getScenarioDAO().update(scenario);
520 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
528 * Get the knowledgeElementDAO.
530 * @return the knowledgeElementDAO
532 public KnowledgeElementDAO getKnowledgeElementDAO() {
533 return _knowledgeElementDAO;
537 * Set the knowledgeElementDAO.
539 * @param knowledgeElementDAO
540 * the knowledgeElementDAO to set
542 public void setKnowledgeElementDAO(
543 final KnowledgeElementDAO knowledgeElementDAO) {
544 _knowledgeElementDAO = knowledgeElementDAO;
548 * Get the indexService.
550 * @return the indexService
552 public IndexService getIndexService() {
553 return _indexService;
557 * Set the indexService.
559 * @param indexService
560 * the indexService to set
562 public void setIndexService(final IndexService indexService) {
563 _indexService = indexService;
567 * Get the scenarioDAO.
569 * @return the scenarioDAO
571 public ScenarioDAO getScenarioDAO() {
576 * Set the scenarioDAO.
579 * the scenarioDAO to set
581 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
582 _scenarioDAO = scenarioDAO;
588 * @return the studyDAO
590 public StudyDAO getStudyDAO() {
598 * the studyDAO to set
600 public void setStudyDAO(final StudyDAO studyDAO) {
601 _studyDAO = studyDAO;
605 * Get the knowledgeElementTypeService.
607 * @return the knowledgeElementTypeService
609 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
610 return _knowledgeElementTypeService;
614 * Set the knowledgeElementTypeService.
616 * @param knowledgeElementTypeService
617 * the knowledgeElementTypeService to set
619 public void setKnowledgeElementTypeService(
620 final KnowledgeElementTypeService knowledgeElementTypeService) {
621 _knowledgeElementTypeService = knowledgeElementTypeService;
625 * Get the studyService.
627 * @return the studyService
629 public StudyService getStudyService() {
630 return _studyService;
634 * Set the studyService.
636 * @param studyService
637 * the studyService to set
639 public void setStudyService(final StudyService studyService) {
640 _studyService = studyService;
644 * Get the userService.
646 * @return the userService
648 public UserService getUserService() {
653 * Set the userService.
656 * the userService to set
658 public void setUserService(final UserService userService) {
659 _userService = userService;
665 * @return the userDAO
667 public UserDAO getUserDAO() {
677 public void setUserDAO(final UserDAO userDAO) {
682 * Get the knowledgeElementTypeDAO.
684 * @return the knowledgeElementTypeDAO
686 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
687 return _knowledgeElementTypeDAO;
691 * Set the knowledgeElementTypeDAO.
693 * @param knowledgeElementTypeDAO
694 * the knowledgeElementTypeDAO to set
696 public void setKnowledgeElementTypeDAO(
697 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
698 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
702 * Get the simulationContextService.
704 * @return the simulationContextService
706 public SimulationContextService getSimulationContextService() {
707 return _simulationContextService;
711 * Set the simulationContextService.
713 * @param simulationContextService
714 * the simulationContextService to set
716 public void setSimulationContextService(
717 final SimulationContextService simulationContextService) {
718 _simulationContextService = simulationContextService;
722 * Get project settings.
724 * @return Project settings service
726 private ProjectSettingsService getProjectSettings() {
727 return _projectSettings;
731 * Set project settings service.
733 * @param projectSettingsService
734 * project settings service
736 public void setProjectSettings(
737 final ProjectSettingsService projectSettingsService) {
738 _projectSettings = projectSettingsService;