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.Date;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
22 import org.hibernate.criterion.Order;
23 import org.hibernate.criterion.Restrictions;
24 import org.splat.common.properties.MessageKeyEnum;
25 import org.splat.dal.bo.kernel.Relation;
26 import org.splat.dal.bo.kernel.Role;
27 import org.splat.dal.bo.kernel.User;
28 import org.splat.dal.bo.som.ConvertsRelation;
29 import org.splat.dal.bo.som.Document;
30 import org.splat.dal.bo.som.DocumentType;
31 import org.splat.dal.bo.som.File;
32 import org.splat.dal.bo.som.KnowledgeElement;
33 import org.splat.dal.bo.som.KnowledgeElementType;
34 import org.splat.dal.bo.som.ProgressState;
35 import org.splat.dal.bo.som.Publication;
36 import org.splat.dal.bo.som.Scenario;
37 import org.splat.dal.bo.som.SimulationContext;
38 import org.splat.dal.bo.som.Study;
39 import org.splat.dal.bo.som.UsedByRelation;
40 import org.splat.dal.bo.som.UsesRelation;
41 import org.splat.dal.bo.som.Document.Properties;
42 import org.splat.dal.dao.kernel.RoleDAO;
43 import org.splat.dal.dao.kernel.UserDAO;
44 import org.splat.dal.dao.som.KnowledgeElementDAO;
45 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
46 import org.splat.dal.dao.som.ScenarioDAO;
47 import org.splat.dal.dao.som.StudyDAO;
48 import org.splat.kernel.InvalidPropertyException;
49 import org.splat.kernel.MismatchException;
50 import org.splat.kernel.MissedPropertyException;
51 import org.splat.kernel.MultiplyDefinedException;
52 import org.splat.kernel.NotApplicableException;
53 import org.splat.log.AppLogger;
54 import org.splat.service.dto.DocumentDTO;
55 import org.splat.service.dto.FileDTO;
56 import org.splat.service.dto.StepDTO;
57 import org.splat.service.technical.IndexService;
58 import org.splat.service.technical.ProjectSettingsService;
59 import org.splat.som.Step;
60 import org.splat.util.BeanHelper;
61 import org.springframework.transaction.annotation.Transactional;
64 * Scenario service implementation.
66 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
68 public class ScenarioServiceImpl implements ScenarioService {
71 * The logger for the service.
73 public final static AppLogger LOG = AppLogger
74 .getLogger(ScenarioServiceImpl.class);
77 * Injected index service.
79 private IndexService _indexService;
81 * Injected step service.
83 private StepService _stepService;
85 * Injected study service.
87 private StudyService _studyService;
89 * Injected publication service.
91 private PublicationService _publicationService;
93 * Injected project element service.
95 private ProjectElementService _projectElementService;
97 * Injected knowledge element DAO.
99 private KnowledgeElementDAO _knowledgeElementDAO;
101 * Injected scenario DAO.
103 private ScenarioDAO _scenarioDAO;
106 * Injected study DAO.
108 private StudyDAO _studyDAO;
111 * Injected knowledge element service.
113 private KnowledgeElementTypeService _knowledgeElementTypeService;
116 * Injected user service.
118 private UserService _userService;
123 private UserDAO _userDAO;
128 private RoleDAO _roleDAO;
131 * Injected knowledge element type DAO.
133 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
136 * Injected simulation context service.
138 private SimulationContextService _simulationContextService;
141 * Injected project service.
143 private ProjectSettingsService _projectSettings;
146 * Injected document type service.
148 private DocumentTypeService _documentTypeService;
151 * Get the projectElementService.
153 * @return the projectElementService
155 public ProjectElementService getProjectElementService() {
156 return _projectElementService;
160 * Set the projectElementService.
162 * @param projectElementService
163 * the projectElementService to set
165 public void setProjectElementService(
166 final ProjectElementService projectElementService) {
167 _projectElementService = projectElementService;
171 * Get the publicationService.
173 * @return the publicationService
175 public PublicationService getPublicationService() {
176 return _publicationService;
180 * Set the publicationService.
182 * @param publicationService
183 * the publicationService to set
185 public void setPublicationService(
186 final PublicationService publicationService) {
187 _publicationService = publicationService;
191 * Get the stepService.
193 * @return the stepService
195 public StepService getStepService() {
200 * Set the stepService.
203 * the stepService to set
205 public void setStepService(final StepService stepService) {
206 _stepService = stepService;
212 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
214 @Transactional(readOnly = true)
215 public List<StepDTO> getScenarioInfo(final long scenarioId) {
216 List<StepDTO> res = new ArrayList<StepDTO>();
217 // Get the scenario from the database by id
218 Scenario scen = getScenarioDAO().get(scenarioId);
219 if (LOG.isDebugEnabled()) {
220 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
221 + scen.getDocums().size());
223 // Get activities of the scenario
224 Step[] steps = getProjectElementService().getSteps(scen);
227 String docType, fileFormat;
230 // For each activity create a step DTO and add it to the result list
231 for (Step step : steps) {
232 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
234 if (LOG.isDebugEnabled()) {
235 LOG.debug("Step[" + stepDTO.getNumber()
236 + "]: Number of documents: "
237 + step.getDocuments().size());
239 // For each publication of the activity create a document DTO.
240 // Each file is considered as a source file.
241 for (Publication tag : step.getDocuments()) {
242 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
244 char aState = tag.getIsnew();
245 docType = tag.value().getType().getName();
246 // For each file of the document create a file DTO
247 // Process source file of the document
248 fileFormat = tag.value().getFile().getFormat();
249 doImport = getProjectSettings().doImport(docType, fileFormat);
250 if (doImport && (!tag.isOutdated())) {
251 processing = "file-import";
253 processing = "file-download";
255 File aFile = tag.value().getFile();
256 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
257 aState, processing, false);
258 // Process all exported files
259 for (Relation rel : tag.value().getRelations(
260 ConvertsRelation.class)) {
261 aFile = ((ConvertsRelation) rel).getTo();
262 fileFormat = aFile.getFormat();
263 doImport = getProjectSettings().doImport(docType,
265 if (doImport && (!tag.isOutdated())) {
266 processing = "file-import";
268 processing = "file-download";
270 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
271 aState, processing, false);
279 * Create a new study with one scenario and "product" simulation context.
282 * the study properties
284 * the scenario properties
286 * the "product" simulation context properties
287 * @return the created study
288 * @throws MissedPropertyException
289 * if a mandatory property is missed
290 * @throws InvalidPropertyException
291 * if a property is invalid
292 * @throws MultiplyDefinedException
293 * if some property occurs several times
296 public Study createStudy(final Study.Properties sprop,
297 final Scenario.Properties oprop,
298 final SimulationContext.Properties cprop)
299 throws MissedPropertyException, InvalidPropertyException,
300 MultiplyDefinedException {
301 Study study = getStudyService().createStudy(sprop);
302 addScenario(study, oprop);
303 if (cprop.getIndex() == 0) { // Input of new project context
304 cprop.setType(getSimulationContextService().selectType("product"))
305 .setValue(cprop.getValue());
306 getStudyService().addProjectContext(study, cprop);
307 } else { // Selection of existing project context
308 SimulationContext context = getSimulationContextService()
309 .selectSimulationContext(cprop.getIndex());
310 getStudyService().addProjectContext(study, context);
318 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
319 * org.splat.dal.bo.som.KnowledgeElement.Properties)
322 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
323 final KnowledgeElement.Properties kprop)
324 throws MissedPropertyException, InvalidPropertyException,
325 MultiplyDefinedException {
326 KnowledgeElement kelm = null;
328 long aScenarioId = aScenarioDTO.getIndex();
329 if (LOG.isDebugEnabled()) {
330 LOG.debug("Add a knowledge element to the scenario #"
333 // Get the persistent scenario.
334 Scenario aScenario = getScenarioDAO().get(aScenarioId);
335 // Get persistent objects for creating a new knowledge.
336 // TODO: Actions must use DTO instead of persistent objects.
337 getUserDAO().merge(kprop.getAuthor());
338 getKnowledgeElementTypeDAO().merge(kprop.getType());
339 // Create a transient knowledge element related to the given scenario.
340 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
341 // Save the new knowledge in the database.
342 getKnowledgeElementDAO().create(kelm);
343 // Update scenario transient data.
344 if (kelm.getType().equals("usecase")) {
345 aScenarioDTO.setUcase(kelm);
346 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
347 aScenarioDTO.getKnowledgeElementsList().add(kelm);
350 // Load the workflow for the parent study to take into account
351 // all study actors durng reindexing.
352 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
354 // Update the lucene index of knowledge elements.
355 getIndexService().add(kelm);
356 if (LOG.isDebugEnabled()) {
357 LOG.debug("A knowledge element #" + kelm.getIndex()
358 + " is added to the scenario #" + aScenario.getIndex());
360 } catch (IOException error) {
361 LOG.error("Unable to index the knowedge element '"
362 + kelm.getIndex() + "', reason:", error);
370 * Update the scenario in the database.
373 * the scenario to update
374 * @return true if updating succeeded
377 private boolean update(final Scenario aScenario) {
378 boolean isOk = false;
380 getScenarioDAO().update(aScenario); // Update of relational base
382 } catch (Exception error) {
383 LOG.error("Unable to re-index the knowledge element '"
384 + aScenario.getIndex() + "', reason:", error);
392 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
395 public void checkin(final long scenId, final long userId,
396 final List<StepDTO> scInfo) throws InvalidPropertyException,
397 MissedPropertyException, MultiplyDefinedException,
398 MismatchException, IOException, NotApplicableException {
399 // Get the scenario from the database by id
400 Scenario aScenario = getScenarioDAO().get(scenId);
401 // Get the user who perform this check-in operation
402 User aUser = getUserService().selectUser(userId);
403 // Get activities of the scenario
404 Step[] steps = getProjectElementService().getSteps(aScenario);
405 // Find result document types
406 List<DocumentType> resTypes = getDocumentTypeService()
407 .selectResultTypes();
409 // Keep newly created documents to create uses relations to results of a previous step.
410 // For each processed existing document keep its new version
411 Map<Document, Document> newVersion = new HashMap<Document, Document>();
412 // Created publications of new created versions of existing documents
413 List<Publication> newVers = new ArrayList<Publication>();
414 // The list of publications of new created documents not existing before the checkin
415 List<Publication> newDocs = new ArrayList<Publication>();
417 DocumentType resType;
418 Date aDate = new Date(); // The timestamp of the checkin operation
419 for (StepDTO stepDTO : scInfo) {
420 if (LOG.isDebugEnabled()) {
421 LOG.debug("Checkin the step:\n" + stepDTO);
423 // Find a result document type of the step
427 if (resTypes.get(i).isResultOf(
428 getProjectSettings().getStep(stepDTO.getNumber()))) {
429 resType = resTypes.get(i);
432 } while ((resType == null) && (i < resTypes.size()));
434 // Find the appropriate scenario step
435 Step step = findStep(stepDTO, steps);
437 // Process each document of the step
438 for (DocumentDTO doc : stepDTO.getDocs()) {
439 checkinDoc(step, doc, aUser, resType, aDate, newVersion,
444 // Set uses/used relations
445 updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
447 // Mark the scenario as checked in
452 * Updated uses/used relations after checkin operation:<BR>
454 * <li>For each new version copy uses relations from the previous version.</li>
455 * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
456 * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
460 * the checked in scenario
462 * the mapping of documents existed before the checkin to their new created versions
464 * the list of publications of new created versions of documents existed before the checkin
466 * the list of publications of new created documents not existed before the checkin
468 private void updateRelationsAfterCheckin(final Scenario aScenario,
469 final Map<Document, Document> newVersion,
470 final List<Publication> newVers, final List<Publication> newDocs) {
471 // For each new version copy uses relations from the previous version.
472 for (Publication newVer : newVers) {
473 // For each Uses relation of the previous version
474 Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
475 if (LOG.isDebugEnabled()) {
476 LOG.debug("Previous version for publication #"
477 + newVer.getIndex() + " is found: " + prevDoc);
479 List<Relation> usesRelations = prevDoc
480 .getRelations(UsesRelation.class);
481 for (Relation rel : usesRelations) {
482 // If used document has been also versioned then refer to its new version.
483 Document usedDoc = ((UsesRelation) rel).getTo();
484 if (newVersion.containsKey(usedDoc)) {
485 usedDoc = newVersion.get(usedDoc);
487 // Build the appropriate relation for the new version.
488 newVer.addDependency(usedDoc);
490 // Outdate documents which depend from the previous version and
491 // were not checked in during this operation.
492 // 1. Get all usedBy relations of the previous document version
493 for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
494 Document using = ((UsedByRelation) rel).getTo();
495 // Check that not checked in dependent documents became outdated
496 Publication usingPub = aScenario.getPublication(using);
497 if (usingPub != null) { // if the document using the old version is still published
498 usingPub.setIsnew('O');
503 // For each new document create uses relation to the last versions of
504 // results of the previous step.
505 for (Publication newPub : newDocs) {
506 // Find used document type according to the configuration.
507 Set<DocumentType> usedTypes = newPub.value().getType()
509 // Find documents of used type in the previous study step.
510 for (Publication pub : aScenario.getDocums()) {
511 if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
512 && (!pub.isOutdated())
513 && usedTypes.contains(pub.value().getType())) {
514 // Create uses relation from the new document
515 // to the found document in the previous step.
516 newPub.addDependency(pub);
523 * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
524 * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
525 * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
528 * the destination scenario step
530 * the DTO of the document to checkin
532 * the user who performs checkin
534 * the result document type of the given step
536 * timestamp of the checkin operation
538 * the mapping of existing documents to their new created versions
540 * the list of publications of new created versions of existing documents
542 * the list of publications of new created documents not existing before the checkin
543 * @throws InvalidPropertyException
544 * if the scenario hasn't some of given steps or documents
545 * @throws IOException
546 * if a file can't be moved into the vault
547 * @throws MismatchException
548 * if version creation in some of steps is failed
549 * @throws MissedPropertyException
550 * if some mandatory property is missed when new document or new document version is created
551 * @throws MultiplyDefinedException
552 * if some property is defined several times when new document or new document version is created
553 * @throws NotApplicableException
554 * if failed saving of a new publication with a given state
556 private void checkinDoc(final Step step, final DocumentDTO doc,
557 final User aUser, final DocumentType resType, final Date aDate,
558 final Map<Document, Document> newVersion,
559 final List<Publication> newVers, final List<Publication> newDocs)
560 throws InvalidPropertyException, MismatchException,
561 MissedPropertyException, MultiplyDefinedException, IOException,
562 NotApplicableException {
563 if (doc.getFiles().size() > 0) {
564 Document.Properties dprop = new Document.Properties();
565 // NOTE: Process only the first attached file for each document
566 FileDTO file = doc.getFiles().get(0);
567 dprop.setLocalPath(file.getPath());
569 // Get document title as the file name
570 java.io.File upfile = new java.io.File(file.getPath());
571 String fileFormat = upfile.getName().substring(
572 upfile.getName().lastIndexOf('.') + 1);
574 // Attach the file via ConvertsRelation, create a new document or
575 // create a new version of the document
576 dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
578 if (doc.getId() > 0) {
579 checkinExistingDoc(step, doc, dprop, fileFormat, upfile,
580 newVersion, newVers);
583 // Otherwise create a new document of the result type
584 // If result type is not found try to get type by file extension
585 if (resType == null) {
586 dprop.setType(getProjectSettings().getDefaultDocumentType(
587 step.getStep(), fileFormat));
589 dprop.setType(resType);
591 // New document title generation as <document type name>_N
592 String docname = dprop.getType().getName();
594 for (Publication scenPub : step.getOwner().getDocums()) {
595 if (scenPub.value().getTitle().startsWith(docname)) {
599 docname += "_" + i; // The generated new document title
601 dprop.setDescription("Checked in").setName(docname);
602 Publication newPub = getStepService().createDocument(step,
605 // Remeber the new document
608 saveFile(newPub, step, upfile);
614 * Check in existing document.
617 * study step to check in
619 * document DTO to check in
621 * document properties
623 * checked in file format
625 * the file to check in
627 * the map of created versions during this check in
629 * the list of new versions created during this check in
630 * @throws InvalidPropertyException
631 * if publication of the document is not found in the step
632 * @throws MismatchException
633 * if the found publication does not point to a document
634 * @throws IOException
635 * if can not move the file into the vault
636 * @throws MultiplyDefinedException
637 * thrown by versionDocument
638 * @throws MissedPropertyException
639 * thrown by versionDocument
640 * @throws NotApplicableException
641 * if failed saving of a new publication with a given state
643 private void checkinExistingDoc(final Step step, final DocumentDTO doc,
644 final Properties dprop, final String fileFormat,
645 final java.io.File upfile,
646 final Map<Document, Document> newVersion,
647 final List<Publication> newVers) throws InvalidPropertyException,
648 MismatchException, MissedPropertyException,
649 MultiplyDefinedException, IOException, NotApplicableException {
650 // If the document already exists then
651 // Attach the file via ConvertsRelation if the extension of the
652 // new file differs from the old one.
653 // If file format (i.e. extension) is the same then create a new
654 // version of the document.
655 // Find the document publication
656 Publication pub = step.getDocument(doc.getId());
658 throw new InvalidPropertyException(MessageKeyEnum.SCN_000002
659 .toString(), doc.getId());
661 if (pub.value() == null) {
662 throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
665 if (LOG.isDebugEnabled()) {
666 LOG.debug("Old format: " + pub.value().getFormat()
667 + " => New format: " + fileFormat);
669 // If formats are same then create a new document version
670 if (pub.value().getFormat() != null
671 && pub.value().getFormat().equals(fileFormat)) {
672 Publication newPub = getStepService().versionDocument(step, pub,
674 if (LOG.isDebugEnabled()) {
675 LOG.debug("Created document type: "
676 + newPub.value().getType().getName() + ", format: "
677 + newPub.value().getFormat());
679 // Remeber the link from the old document to the new document version
680 newVersion.put(pub.value(), newPub.value());
681 // Remember the new version publication
684 saveFile(newPub, step, upfile);
686 } else { // If formats are different then attach the new file via ConvertsRelation
687 File attach = pub.value().getAttachedFile(fileFormat);
688 if (attach == null) {
689 // If there is no attachment with this extension then attach the new one
690 ConvertsRelation export = getPublicationService().attach(pub,
692 if (LOG.isDebugEnabled()) {
693 LOG.debug("Moving " + upfile.getName() + " to "
694 + export.getTo().asFile().getPath());
696 upfile.renameTo(export.getTo().asFile());
698 // If an attachment with this extension already exists then
699 // replace it by the new one
700 upfile.renameTo(attach.asFile());
701 // Update attached file modification date
702 attach.setDate(new Date());
708 * Save the file in the vault and create its publication in the step.
711 * the new publication to save
713 * the study step to publish the document
715 * the downloaded file
716 * @throws IOException
717 * if a file can't be moved into the vault
718 * @throws NotApplicableException
719 * if failed saving of a new publication with a given state
721 private void saveFile(final Publication newPub, final Step step,
722 final java.io.File upfile) throws IOException,
723 NotApplicableException {
724 // Attach the file to the created document
725 java.io.File updir = newPub.getSourceFile().asFile();
726 if (LOG.isDebugEnabled()) {
727 LOG.debug("Moving \"" + upfile.getName() + "\" to \""
728 + updir.getPath() + "\".");
730 if (updir.exists()) {
731 if (updir.delete()) {
732 LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
733 .getAbsoluteFile(), step.getOwner().getIndex());
735 throw new IOException(
736 "Can't delete the existing destination file to move file from "
737 + upfile.getAbsolutePath() + " to "
738 + updir.getAbsolutePath());
741 if (upfile.renameTo(updir)) {
742 // Save the new publication in the scenario.
743 // The old publication is removed from the scenario here.
744 getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
746 throw new IOException("Can't move file from "
747 + upfile.getAbsolutePath() + " to "
748 + updir.getAbsolutePath());
753 * Find appropriate step in the array of scenario steps according to the given step DTO.
759 * @return appropriate scenario step
760 * @throws InvalidPropertyException
761 * if appropriate step is not found
763 private Step findStep(final StepDTO stepDTO, final Step[] steps)
764 throws InvalidPropertyException {
768 if (steps[i].getNumber() == stepDTO.getNumber()) {
772 } while ((step == null) && (i < steps.length));
775 throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
776 .toString(), stepDTO.getNumber());
784 * @see org.splat.service.ScenarioService#checkin(long)
787 public void checkin(final long scenarioId) throws InvalidPropertyException {
788 Scenario aScenario = getScenarioDAO().get(scenarioId);
789 if (aScenario == null) {
790 // Scenario not found
791 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
792 .toString(), scenarioId);
798 * Mark the scenario as checked in.
801 * the scenario to check in.
803 private void checkin(final Scenario aScenario) {
804 aScenario.setUser(null);
805 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
806 // getScenarioDAO().update(aScenario);
812 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
814 public boolean checkout(final Scenario aScenario, final User user) {
815 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
818 aScenario.setUser(user);
819 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
820 // RKV: getScenarioDAO().update(aScenario);
826 * Mark the given scenario as checked out by the given user.
831 * the id of the user performing the check out
832 * @throws InvalidPropertyException
833 * if the user or the scenario is not found in the database
834 * @throws NotApplicableException
835 * if the given user can not check out the scenario
838 public void checkout(final long scenarioId, final long userId)
839 throws InvalidPropertyException, NotApplicableException {
840 User aUser = getUserService().selectUser(userId);
843 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
844 .toString(), userId);
846 Scenario aScenario = getScenarioDAO().get(scenarioId);
847 if (aScenario == null) {
848 // Scenario not found
849 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
850 .toString(), scenarioId);
852 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
855 if (aScenario.isCheckedout()
856 && (!aScenario.getUser().getUsername().equals(
857 aUser.getUsername()))) {
858 throw new NotApplicableException(MessageKeyEnum.SCN_000008
859 .toString(), scenarioId, aScenario.getUser()
862 aScenario.setUser(aUser);
863 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
865 // User doesn't participate in the scenario
866 throw new NotApplicableException(MessageKeyEnum.SCN_000007
867 .toString(), aUser.getUsername(), scenarioId);
874 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
876 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
877 Scenario base = (Scenario) lastep.getOwner();
878 Step[] from = getProjectElementService().getSteps(base);
879 Step[] to = getProjectElementService().getSteps(scenario);
880 for (int i = 0; i < from.length; i++) {
882 if (step.getNumber() > lastep.getNumber()) {
886 List<Publication> docs = step.getAllDocuments();
887 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
888 Publication doc = getPublicationService().copy(j.next(),
889 scenario); // Creation of a new reference to the document
890 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
891 getStepService().add(to[i], doc);
893 List<SimulationContext> ctex = step.getAllSimulationContexts();
894 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
895 getStepService().addSimulationContext(to[i], j.next());
903 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
905 public boolean isEmpty(final Scenario scenario) {
906 Step[] mystep = getProjectElementService().getSteps(scenario);
907 boolean isEmp = true;
908 for (int i = 0; i < mystep.length; i++) {
909 if (mystep[i].isStarted()) {
921 public boolean isFinished(final Scenario scenario) {
922 Step[] mystep = getProjectElementService().getSteps(scenario);
923 boolean notempty = false; // If this is empty, this is not finished
924 for (int i = 0; i < mystep.length; i++) {
925 if (!mystep[i].isStarted()) {
928 if (!mystep[i].isFinished()) {
939 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
942 public Scenario addScenario(final Study aStudy,
943 final Scenario.Properties sprop) throws MissedPropertyException,
944 InvalidPropertyException, MultiplyDefinedException {
945 if (sprop.getManager() == null) {
946 sprop.setManager(aStudy.getAuthor());
949 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
950 if (sprop.getBaseStep() != null) {
951 copyContentsUpTo(scenario, sprop.getBaseStep());
953 Scenario previous = sprop.getInsertAfter();
955 if (previous == null) {
956 aStudy.getScenariiList().add(scenario);
958 aStudy.getScenariiList().add(
959 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
961 getStudyDAO().update(aStudy); // No need to update the Lucene index
962 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
963 if (sprop.getBaseStep() != null) {
964 // No need to update the Knowledge Element index as Knowledge Elements are not copied
965 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
967 KnowledgeElementType ucase = getKnowledgeElementTypeService()
968 .selectType("usecase");
969 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
970 // TODO: Get appropriate user by its role: UserService.getAdmin();
971 // User admin = getUserService().selectUser(1); // First user created when creating the database
972 Role adminRole = getRoleDAO().getFilteredList(
973 Restrictions.like("role", "%sysadmin%")).get(0);
974 User admin = getUserDAO().getFilteredList(
975 Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
977 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
978 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
980 addKnowledgeElement(scenario, kprop);
985 * Remove a knowledge element from a scenario.
990 * the knowledge element to remove
991 * @return true if removal succeeded
994 public boolean removeKnowledgeElement(final Scenario scenario,
995 final KnowledgeElement kelm) {
996 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
997 boolean isOk = (torem != null);
999 isOk = scenario.getKnowledgeElements().remove(torem);
1001 getScenarioDAO().merge(scenario);
1002 // Update of my transient data
1003 // RKV: These transient data are not used indeed.
1004 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
1005 // RKV: kelm.getType().getIndex());
1006 // RKV: kelms.remove(torem);
1007 if (scenario.getKnowledgeElementsList() != null) {
1008 scenario.getKnowledgeElementsList().remove(torem);
1010 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
1020 * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
1023 public void renameScenario(final Scenario scenario) {
1024 getScenarioDAO().merge(scenario);
1028 * Get the knowledgeElementDAO.
1030 * @return the knowledgeElementDAO
1032 public KnowledgeElementDAO getKnowledgeElementDAO() {
1033 return _knowledgeElementDAO;
1037 * Set the knowledgeElementDAO.
1039 * @param knowledgeElementDAO
1040 * the knowledgeElementDAO to set
1042 public void setKnowledgeElementDAO(
1043 final KnowledgeElementDAO knowledgeElementDAO) {
1044 _knowledgeElementDAO = knowledgeElementDAO;
1048 * Get the indexService.
1050 * @return the indexService
1052 public IndexService getIndexService() {
1053 return _indexService;
1057 * Set the indexService.
1059 * @param indexService
1060 * the indexService to set
1062 public void setIndexService(final IndexService indexService) {
1063 _indexService = indexService;
1067 * Get the scenarioDAO.
1069 * @return the scenarioDAO
1071 public ScenarioDAO getScenarioDAO() {
1072 return _scenarioDAO;
1076 * Set the scenarioDAO.
1078 * @param scenarioDAO
1079 * the scenarioDAO to set
1081 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
1082 _scenarioDAO = scenarioDAO;
1088 * @return the studyDAO
1090 public StudyDAO getStudyDAO() {
1098 * the studyDAO to set
1100 public void setStudyDAO(final StudyDAO studyDAO) {
1101 _studyDAO = studyDAO;
1105 * Get the knowledgeElementTypeService.
1107 * @return the knowledgeElementTypeService
1109 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
1110 return _knowledgeElementTypeService;
1114 * Set the knowledgeElementTypeService.
1116 * @param knowledgeElementTypeService
1117 * the knowledgeElementTypeService to set
1119 public void setKnowledgeElementTypeService(
1120 final KnowledgeElementTypeService knowledgeElementTypeService) {
1121 _knowledgeElementTypeService = knowledgeElementTypeService;
1125 * Get the studyService.
1127 * @return the studyService
1129 public StudyService getStudyService() {
1130 return _studyService;
1134 * Set the studyService.
1136 * @param studyService
1137 * the studyService to set
1139 public void setStudyService(final StudyService studyService) {
1140 _studyService = studyService;
1144 * Get the userService.
1146 * @return the userService
1148 public UserService getUserService() {
1149 return _userService;
1153 * Set the userService.
1155 * @param userService
1156 * the userService to set
1158 public void setUserService(final UserService userService) {
1159 _userService = userService;
1165 * @return the userDAO
1167 public UserDAO getUserDAO() {
1175 * the userDAO to set
1177 public void setUserDAO(final UserDAO userDAO) {
1182 * Get the knowledgeElementTypeDAO.
1184 * @return the knowledgeElementTypeDAO
1186 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
1187 return _knowledgeElementTypeDAO;
1191 * Set the knowledgeElementTypeDAO.
1193 * @param knowledgeElementTypeDAO
1194 * the knowledgeElementTypeDAO to set
1196 public void setKnowledgeElementTypeDAO(
1197 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
1198 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
1202 * Get the simulationContextService.
1204 * @return the simulationContextService
1206 public SimulationContextService getSimulationContextService() {
1207 return _simulationContextService;
1211 * Set the simulationContextService.
1213 * @param simulationContextService
1214 * the simulationContextService to set
1216 public void setSimulationContextService(
1217 final SimulationContextService simulationContextService) {
1218 _simulationContextService = simulationContextService;
1222 * Get project settings.
1224 * @return Project settings service
1226 private ProjectSettingsService getProjectSettings() {
1227 return _projectSettings;
1231 * Set project settings service.
1233 * @param projectSettingsService
1234 * project settings service
1236 public void setProjectSettings(
1237 final ProjectSettingsService projectSettingsService) {
1238 _projectSettings = projectSettingsService;
1242 * Get the documentTypeService.
1244 * @return the documentTypeService
1246 public DocumentTypeService getDocumentTypeService() {
1247 return _documentTypeService;
1251 * Set the documentTypeService.
1253 * @param documentTypeService
1254 * the documentTypeService to set
1256 public void setDocumentTypeService(
1257 final DocumentTypeService documentTypeService) {
1258 _documentTypeService = documentTypeService;
1264 * @return the roleDAO
1266 public RoleDAO getRoleDAO() {
1274 * the roleDAO to set
1276 public void setRoleDAO(final RoleDAO roleDAO) {