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.SimulationContextType;
39 import org.splat.dal.bo.som.Study;
40 import org.splat.dal.bo.som.UsedByRelation;
41 import org.splat.dal.bo.som.UsesRelation;
42 import org.splat.dal.bo.som.Document.Properties;
43 import org.splat.dal.dao.kernel.RoleDAO;
44 import org.splat.dal.dao.kernel.UserDAO;
45 import org.splat.dal.dao.som.KnowledgeElementDAO;
46 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
47 import org.splat.dal.dao.som.ScenarioDAO;
48 import org.splat.dal.dao.som.StudyDAO;
49 import org.splat.i18n.I18nUtils;
50 import org.splat.kernel.InvalidPropertyException;
51 import org.splat.kernel.MismatchException;
52 import org.splat.kernel.MissedPropertyException;
53 import org.splat.kernel.MultiplyDefinedException;
54 import org.splat.kernel.NotApplicableException;
55 import org.splat.log.AppLogger;
56 import org.splat.service.dto.DocumentDTO;
57 import org.splat.service.dto.FileDTO;
58 import org.splat.service.dto.StepDTO;
59 import org.splat.service.technical.IndexService;
60 import org.splat.service.technical.ProjectSettingsService;
61 import org.splat.som.Step;
62 import org.splat.util.BeanHelper;
63 import org.springframework.transaction.annotation.Transactional;
66 * Scenario service implementation.
68 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
70 public class ScenarioServiceImpl implements ScenarioService {
73 * The logger for the service.
75 public final static AppLogger LOG = AppLogger
76 .getLogger(ScenarioServiceImpl.class);
79 * Injected index service.
81 private IndexService _indexService;
83 * Injected step service.
85 private StepService _stepService;
87 * Injected study service.
89 private StudyService _studyService;
91 * Injected publication service.
93 private PublicationService _publicationService;
95 * Injected project element service.
97 private ProjectElementService _projectElementService;
99 * Injected knowledge element DAO.
101 private KnowledgeElementDAO _knowledgeElementDAO;
103 * Injected scenario DAO.
105 private ScenarioDAO _scenarioDAO;
108 * Injected study DAO.
110 private StudyDAO _studyDAO;
113 * Injected knowledge element service.
115 private KnowledgeElementTypeService _knowledgeElementTypeService;
118 * Injected user service.
120 private UserService _userService;
125 private UserDAO _userDAO;
130 private RoleDAO _roleDAO;
133 * Injected knowledge element type DAO.
135 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
138 * Injected simulation context service.
140 private SimulationContextService _simulationContextService;
143 * Injected project service.
145 private ProjectSettingsService _projectSettings;
148 * Injected document type service.
150 private DocumentTypeService _documentTypeService;
153 * Get the projectElementService.
155 * @return the projectElementService
157 public ProjectElementService getProjectElementService() {
158 return _projectElementService;
162 * Set the projectElementService.
164 * @param projectElementService
165 * the projectElementService to set
167 public void setProjectElementService(
168 final ProjectElementService projectElementService) {
169 _projectElementService = projectElementService;
173 * Get the publicationService.
175 * @return the publicationService
177 public PublicationService getPublicationService() {
178 return _publicationService;
182 * Set the publicationService.
184 * @param publicationService
185 * the publicationService to set
187 public void setPublicationService(
188 final PublicationService publicationService) {
189 _publicationService = publicationService;
193 * Get the stepService.
195 * @return the stepService
197 public StepService getStepService() {
202 * Set the stepService.
205 * the stepService to set
207 public void setStepService(final StepService stepService) {
208 _stepService = stepService;
214 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
216 @Transactional(readOnly = true)
217 public List<StepDTO> getScenarioInfo(final long scenarioId) {
218 List<StepDTO> res = new ArrayList<StepDTO>();
219 // Get the scenario from the database by id
220 Scenario scen = getScenarioDAO().get(scenarioId);
221 if (LOG.isDebugEnabled()) {
222 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
223 + scen.getDocums().size());
225 // Get activities of the scenario
226 Step[] steps = getProjectElementService().getSteps(scen);
229 String docType, fileFormat;
232 // For each activity create a step DTO and add it to the result list
233 for (Step step : steps) {
234 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
236 if (LOG.isDebugEnabled()) {
237 LOG.debug("Step[" + stepDTO.getNumber()
238 + "]: Number of documents: "
239 + step.getDocuments().size());
241 // For each publication of the activity create a document DTO.
242 // Each file is considered as a source file.
243 for (Publication tag : step.getDocuments()) {
244 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
246 char aState = tag.getIsnew();
247 docType = tag.value().getType().getName();
248 // For each file of the document create a file DTO
249 // Process source file of the document
250 fileFormat = tag.value().getFile().getFormat();
251 doImport = getProjectSettings().doImport(docType, fileFormat);
252 if (doImport && (!tag.isOutdated())) {
253 processing = "file-import";
255 processing = "file-download";
257 File aFile = tag.value().getFile();
258 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
259 aState, processing, false);
260 // Process all exported files
261 for (Relation rel : tag.value().getRelations(
262 ConvertsRelation.class)) {
263 aFile = ((ConvertsRelation) rel).getTo();
264 fileFormat = aFile.getFormat();
265 doImport = getProjectSettings().doImport(docType,
267 if (doImport && (!tag.isOutdated())) {
268 processing = "file-import";
270 processing = "file-download";
272 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
273 aState, processing, false);
283 * @see org.splat.service.ScenarioService#createStudy(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
286 public long createStudy(final String username, final String title,
287 final String productName, final String description)
288 throws InvalidPropertyException, MissedPropertyException,
289 MultiplyDefinedException {
293 User author = getUserService().selectUser(username);
294 if (author == null) {
296 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
297 .toString(), username);
300 // Set the study properties
301 Study.Properties sprop = new Study.Properties();
302 sprop.setTitle(title).setManager(author);
303 sprop.setDescription(description);
305 // Find the product simulation context
306 SimulationContextType productContextType = getSimulationContextService()
307 .selectType("product");
308 SimulationContext.Properties cprop = new SimulationContext.Properties();
309 cprop.setType(productContextType).setValue(productName);
310 SimulationContext productCtx = getSimulationContextService()
311 .selectSimulationContext(productContextType, productName);
312 if (productCtx != null) {
313 cprop.setIndex(productCtx.getIndex());
316 // Set a first scenario properties
317 Scenario.Properties oprop = new Scenario.Properties();
318 oprop.setTitle(I18nUtils.getMessageLocaleDefault("label.scenario")
321 Study study = createStudy(sprop, oprop, cprop);
322 id = study.getIndex();
328 * Create a new study with one scenario and "product" simulation context.
331 * the study properties
333 * the scenario properties
335 * the "product" simulation context properties
336 * @return the created study
337 * @throws MissedPropertyException
338 * if a mandatory property is missed
339 * @throws InvalidPropertyException
340 * if a property is invalid
341 * @throws MultiplyDefinedException
342 * if some property occurs several times
345 public Study createStudy(final Study.Properties sprop,
346 final Scenario.Properties oprop,
347 final SimulationContext.Properties cprop)
348 throws MissedPropertyException, InvalidPropertyException,
349 MultiplyDefinedException {
350 Study study = getStudyService().createStudy(sprop);
351 addScenario(study, oprop);
352 if (cprop.getIndex() == 0) { // Input of new project context
353 cprop.setType(getSimulationContextService().selectType("product"))
354 .setValue(cprop.getValue());
355 getStudyService().addProjectContext(study, cprop);
356 } else { // Selection of existing project context
357 SimulationContext context = getSimulationContextService()
358 .selectSimulationContext(cprop.getIndex());
359 getStudyService().addProjectContext(study, context);
365 public void assignContext() throws MissedPropertyException,
366 InvalidPropertyException, MultiplyDefinedException {
367 //TODO: complete the method
368 SimulationContext.Properties cprop = new SimulationContext.Properties();
370 Study study = getStudyDAO().get(id);
371 if (cprop.getIndex() == 0) { // Input of new project context
372 cprop.setType(getSimulationContextService().selectType("product"))
373 .setValue(cprop.getValue());
374 getStudyService().addProjectContext(study, cprop);
375 } else { // Selection of existing project context
376 SimulationContext context = getSimulationContextService()
377 .selectSimulationContext(cprop.getIndex());
378 getStudyService().addProjectContext(study, context);
385 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
386 * org.splat.dal.bo.som.KnowledgeElement.Properties)
389 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
390 final KnowledgeElement.Properties kprop)
391 throws MissedPropertyException, InvalidPropertyException,
392 MultiplyDefinedException {
393 KnowledgeElement kelm = null;
395 long aScenarioId = aScenarioDTO.getIndex();
396 if (LOG.isDebugEnabled()) {
398 .debug("Add a knowledge element to the scenario #"
401 // Get the persistent scenario.
402 Scenario aScenario = getScenarioDAO().get(aScenarioId);
403 // Get persistent objects for creating a new knowledge.
404 // TODO: Actions must use DTO instead of persistent objects.
405 getUserDAO().merge(kprop.getAuthor());
406 getKnowledgeElementTypeDAO().merge(kprop.getType());
407 // Create a transient knowledge element related to the given scenario.
408 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
409 // Save the new knowledge in the database.
410 getKnowledgeElementDAO().create(kelm);
411 // Update scenario transient data.
412 if (kelm.getType().equals("usecase")) {
413 aScenarioDTO.setUcase(kelm);
414 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
415 aScenarioDTO.getKnowledgeElementsList().add(kelm);
418 // Load the workflow for the parent study to take into account
419 // all study actors durng reindexing.
420 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
422 // // Update the lucene index of knowledge elements.
423 // getIndexService().add(kelm);
424 if (LOG.isDebugEnabled()) {
425 LOG.debug("A knowledge element #" + kelm.getIndex()
426 + " is added to the scenario #" + aScenario.getIndex());
428 // } catch (IOException error) {
429 // LOG.error("Unable to index the knowedge element '"
430 // + kelm.getIndex() + "', reason:", error);
438 * Update the scenario in the database.
441 * the scenario to update
442 * @return true if updating succeeded
445 private boolean update(final Scenario aScenario) {
446 boolean isOk = false;
448 getScenarioDAO().update(aScenario); // Update of relational base
450 } catch (Exception error) {
451 LOG.error("Unable to re-index the knowledge element '"
452 + aScenario.getIndex() + "', reason:", error);
460 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
463 public void checkin(final long scenId, final long userId,
464 final List<StepDTO> scInfo) throws InvalidPropertyException,
465 MissedPropertyException, MultiplyDefinedException,
466 MismatchException, IOException, NotApplicableException {
467 // Get the scenario from the database by id
468 Scenario aScenario = getScenarioDAO().get(scenId);
469 // Get the user who perform this check-in operation
470 User aUser = getUserService().selectUser(userId);
471 // Get activities of the scenario
472 Step[] steps = getProjectElementService().getSteps(aScenario);
473 // Find result document types
474 List<DocumentType> resTypes = getDocumentTypeService()
475 .selectResultTypes();
477 // Keep newly created documents to create uses relations to results of a previous step.
478 // For each processed existing document keep its new version
479 Map<Document, Document> newVersion = new HashMap<Document, Document>();
480 // Created publications of new created versions of existing documents
481 List<Publication> newVers = new ArrayList<Publication>();
482 // The list of publications of new created documents not existing before the checkin
483 List<Publication> newDocs = new ArrayList<Publication>();
485 DocumentType resType;
486 Date aDate = new Date(); // The timestamp of the checkin operation
487 for (StepDTO stepDTO : scInfo) {
488 if (LOG.isDebugEnabled()) {
489 LOG.debug("Checkin the step:\n" + stepDTO);
491 // Find a result document type of the step
495 if (resTypes.get(i).isResultOf(
496 getProjectSettings().getStep(stepDTO.getNumber()))) {
497 resType = resTypes.get(i);
500 } while ((resType == null) && (i < resTypes.size()));
502 // Find the appropriate scenario step
503 Step step = findStep(stepDTO, steps);
505 // Process each document of the step
506 for (DocumentDTO doc : stepDTO.getDocs()) {
507 checkinDoc(step, doc, aUser, resType, aDate, newVersion,
512 // Set uses/used relations
513 updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
515 // Mark the scenario as checked in
520 * Updated uses/used relations after checkin operation:<BR>
522 * <li>For each new version copy uses relations from the previous version.</li>
523 * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
524 * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
528 * the checked in scenario
530 * the mapping of documents existed before the checkin to their new created versions
532 * the list of publications of new created versions of documents existed before the checkin
534 * the list of publications of new created documents not existed before the checkin
536 private void updateRelationsAfterCheckin(final Scenario aScenario,
537 final Map<Document, Document> newVersion,
538 final List<Publication> newVers, final List<Publication> newDocs) {
539 // For each new version copy uses relations from the previous version.
540 for (Publication newVer : newVers) {
541 // For each Uses relation of the previous version
542 Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
543 if (LOG.isDebugEnabled()) {
544 LOG.debug("Previous version for publication #"
545 + newVer.getIndex() + " is found: " + prevDoc);
547 List<Relation> usesRelations = prevDoc
548 .getRelations(UsesRelation.class);
549 for (Relation rel : usesRelations) {
550 // If used document has been also versioned then refer to its new version.
551 Document usedDoc = ((UsesRelation) rel).getTo();
552 if (newVersion.containsKey(usedDoc)) {
553 usedDoc = newVersion.get(usedDoc);
555 // Build the appropriate relation for the new version.
556 newVer.addDependency(usedDoc);
558 // Outdate documents which depend from the previous version and
559 // were not checked in during this operation.
560 // 1. Get all usedBy relations of the previous document version
561 for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
562 Document using = ((UsedByRelation) rel).getTo();
563 // Check that not checked in dependent documents became outdated
564 Publication usingPub = aScenario.getPublication(using);
565 if (usingPub != null) { // if the document using the old version is still published
566 usingPub.setIsnew('O');
571 // For each new document create uses relation to the last versions of
572 // results of the previous step.
573 for (Publication newPub : newDocs) {
574 // Find used document type according to the configuration.
575 Set<DocumentType> usedTypes = newPub.value().getType()
577 // Find documents of used type in the previous study step.
578 for (Publication pub : aScenario.getDocums()) {
579 if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
580 && (!pub.isOutdated())
581 && usedTypes.contains(pub.value().getType())) {
582 // Create uses relation from the new document
583 // to the found document in the previous step.
584 newPub.addDependency(pub);
591 * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
592 * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
593 * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
596 * the destination scenario step
598 * the DTO of the document to checkin
600 * the user who performs checkin
602 * the result document type of the given step
604 * timestamp of the checkin operation
606 * the mapping of existing documents to their new created versions
608 * the list of publications of new created versions of existing documents
610 * the list of publications of new created documents not existing before the checkin
611 * @throws InvalidPropertyException
612 * if the scenario hasn't some of given steps or documents
613 * @throws IOException
614 * if a file can't be moved into the vault
615 * @throws MismatchException
616 * if version creation in some of steps is failed
617 * @throws MissedPropertyException
618 * if some mandatory property is missed when new document or new document version is created
619 * @throws MultiplyDefinedException
620 * if some property is defined several times when new document or new document version is created
621 * @throws NotApplicableException
622 * if failed saving of a new publication with a given state
624 private void checkinDoc(final Step step, final DocumentDTO doc,
625 final User aUser, final DocumentType resType, final Date aDate,
626 final Map<Document, Document> newVersion,
627 final List<Publication> newVers, final List<Publication> newDocs)
628 throws InvalidPropertyException, MismatchException,
629 MissedPropertyException, MultiplyDefinedException, IOException,
630 NotApplicableException {
631 if (doc.getFiles().size() > 0) {
632 Document.Properties dprop = new Document.Properties();
633 // NOTE: Process only the first attached file for each document
634 FileDTO file = doc.getFiles().get(0);
635 dprop.setLocalPath(file.getPath());
637 // Get document title as the file name
638 java.io.File upfile = new java.io.File(file.getPath());
639 String fileFormat = upfile.getName().substring(
640 upfile.getName().lastIndexOf('.') + 1);
642 // Attach the file via ConvertsRelation, create a new document or
643 // create a new version of the document
644 dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
646 if (doc.getId() > 0) {
647 checkinExistingDoc(step, doc, dprop, fileFormat, upfile,
648 newVersion, newVers);
651 // Otherwise create a new document of the result type
652 // If result type is not found try to get type by file extension
653 if (resType == null) {
654 dprop.setType(getProjectSettings().getDefaultDocumentType(
655 step.getStep(), fileFormat));
657 dprop.setType(resType);
659 // New document title generation as <document type name>_N
660 String docname = dprop.getType().getName();
662 for (Publication scenPub : step.getOwner().getDocums()) {
663 if (scenPub.value().getTitle().startsWith(docname)) {
667 docname += "_" + i; // The generated new document title
669 dprop.setDescription("Checked in").setName(docname);
670 Publication newPub = getStepService().createDocument(step,
673 // Remeber the new document
676 saveFile(newPub, step, upfile);
682 * Check in existing document.
685 * study step to check in
687 * document DTO to check in
689 * document properties
691 * checked in file format
693 * the file to check in
695 * the map of created versions during this check in
697 * the list of new versions created during this check in
698 * @throws InvalidPropertyException
699 * if publication of the document is not found in the step
700 * @throws MismatchException
701 * if the found publication does not point to a document
702 * @throws IOException
703 * if can not move the file into the vault
704 * @throws MultiplyDefinedException
705 * thrown by versionDocument
706 * @throws MissedPropertyException
707 * thrown by versionDocument
708 * @throws NotApplicableException
709 * if failed saving of a new publication with a given state
711 private void checkinExistingDoc(final Step step, final DocumentDTO doc,
712 final Properties dprop, final String fileFormat,
713 final java.io.File upfile,
714 final Map<Document, Document> newVersion,
715 final List<Publication> newVers) throws InvalidPropertyException,
716 MismatchException, MissedPropertyException,
717 MultiplyDefinedException, IOException, NotApplicableException {
718 // If the document already exists then
719 // Attach the file via ConvertsRelation if the extension of the
720 // new file differs from the old one.
721 // If file format (i.e. extension) is the same then create a new
722 // version of the document.
723 // Find the document publication
724 Publication pub = step.getDocument(doc.getId());
726 throw new InvalidPropertyException(MessageKeyEnum.SCN_000002
727 .toString(), doc.getId());
729 if (pub.value() == null) {
730 throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
733 if (LOG.isDebugEnabled()) {
734 LOG.debug("Old format: " + pub.value().getFormat()
735 + " => New format: " + fileFormat);
737 // If formats are same then create a new document version
738 if (pub.value().getFormat() != null
739 && pub.value().getFormat().equals(fileFormat)) {
740 Publication newPub = getStepService().versionDocument(step, pub,
742 if (LOG.isDebugEnabled()) {
743 LOG.debug("Created document type: "
744 + newPub.value().getType().getName() + ", format: "
745 + newPub.value().getFormat());
747 // Remeber the link from the old document to the new document version
748 newVersion.put(pub.value(), newPub.value());
749 // Remember the new version publication
752 saveFile(newPub, step, upfile);
754 } else { // If formats are different then attach the new file via ConvertsRelation
755 File attach = pub.value().getAttachedFile(fileFormat);
756 if (attach == null) {
757 // If there is no attachment with this extension then attach the new one
758 ConvertsRelation export = getPublicationService().attach(pub,
760 if (LOG.isDebugEnabled()) {
761 LOG.debug("Moving " + upfile.getName() + " to "
762 + export.getTo().asFile().getPath());
764 upfile.renameTo(export.getTo().asFile());
766 // If an attachment with this extension already exists then
767 // replace it by the new one
768 upfile.renameTo(attach.asFile());
769 // Update attached file modification date
770 attach.setDate(new Date());
776 * Save the file in the vault and create its publication in the step.
779 * the new publication to save
781 * the study step to publish the document
783 * the downloaded file
784 * @throws IOException
785 * if a file can't be moved into the vault
786 * @throws NotApplicableException
787 * if failed saving of a new publication with a given state
789 private void saveFile(final Publication newPub, final Step step,
790 final java.io.File upfile) throws IOException,
791 NotApplicableException {
792 // Attach the file to the created document
793 java.io.File updir = newPub.getSourceFile().asFile();
794 if (LOG.isDebugEnabled()) {
795 LOG.debug("Moving \"" + upfile.getName() + "\" to \""
796 + updir.getPath() + "\".");
798 if (updir.exists()) {
799 if (updir.delete()) {
800 LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
801 .getAbsoluteFile(), step.getOwner().getIndex());
803 throw new IOException(
804 "Can't delete the existing destination file to move file from "
805 + upfile.getAbsolutePath() + " to "
806 + updir.getAbsolutePath());
809 if (upfile.renameTo(updir)) {
810 // Save the new publication in the scenario.
811 // The old publication is removed from the scenario here.
812 getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
814 throw new IOException("Can't move file from "
815 + upfile.getAbsolutePath() + " to "
816 + updir.getAbsolutePath());
821 * Find appropriate step in the array of scenario steps according to the given step DTO.
827 * @return appropriate scenario step
828 * @throws InvalidPropertyException
829 * if appropriate step is not found
831 private Step findStep(final StepDTO stepDTO, final Step[] steps)
832 throws InvalidPropertyException {
836 if (steps[i].getNumber() == stepDTO.getNumber()) {
840 } while ((step == null) && (i < steps.length));
843 throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
844 .toString(), stepDTO.getNumber());
852 * @see org.splat.service.ScenarioService#checkin(long)
855 public void checkin(final long scenarioId) throws InvalidPropertyException {
856 Scenario aScenario = getScenarioDAO().get(scenarioId);
857 if (aScenario == null) {
858 // Scenario not found
859 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
860 .toString(), scenarioId);
866 * Mark the scenario as checked in.
869 * the scenario to check in.
871 private void checkin(final Scenario aScenario) {
872 aScenario.setUser(null);
873 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
874 // getScenarioDAO().update(aScenario);
880 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
882 public boolean checkout(final Scenario aScenario, final User user) {
883 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
886 aScenario.setUser(user);
887 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
888 // RKV: getScenarioDAO().update(aScenario);
894 * Mark the given scenario as checked out by the given user.
899 * the id of the user performing the check out
900 * @throws InvalidPropertyException
901 * if the user or the scenario is not found in the database
902 * @throws NotApplicableException
903 * if the given user can not check out the scenario
906 public void checkout(final long scenarioId, final long userId)
907 throws InvalidPropertyException, NotApplicableException {
908 User aUser = getUserService().selectUser(userId);
911 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
912 .toString(), userId);
914 Scenario aScenario = getScenarioDAO().get(scenarioId);
915 if (aScenario == null) {
916 // Scenario not found
917 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
918 .toString(), scenarioId);
920 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
923 if (aScenario.isCheckedout()
924 && (!aScenario.getUser().getUsername().equals(
925 aUser.getUsername()))) {
926 throw new NotApplicableException(MessageKeyEnum.SCN_000008
927 .toString(), scenarioId, aScenario.getUser()
930 aScenario.setUser(aUser);
931 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
933 // User doesn't participate in the scenario
934 throw new NotApplicableException(MessageKeyEnum.SCN_000007
935 .toString(), aUser.getUsername(), scenarioId);
942 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
944 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
945 Scenario base = (Scenario) lastep.getOwner();
946 Step[] from = getProjectElementService().getSteps(base);
947 Step[] to = getProjectElementService().getSteps(scenario);
948 for (int i = 0; i < from.length; i++) {
950 if (step.getNumber() > lastep.getNumber()) {
954 List<Publication> docs = step.getAllDocuments();
955 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
956 Publication doc = getPublicationService().copy(j.next(),
957 scenario); // Creation of a new reference to the document
958 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
959 getStepService().add(to[i], doc);
961 List<SimulationContext> ctex = step.getAllSimulationContexts();
962 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
963 getStepService().addSimulationContext(to[i], j.next());
971 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
973 public boolean isEmpty(final Scenario scenario) {
974 Step[] mystep = getProjectElementService().getSteps(scenario);
975 boolean isEmp = true;
976 for (int i = 0; i < mystep.length; i++) {
977 if (mystep[i].isStarted()) {
989 public boolean isFinished(final Scenario scenario) {
990 Step[] mystep = getProjectElementService().getSteps(scenario);
991 boolean notempty = false; // If this is empty, this is not finished
992 for (int i = 0; i < mystep.length; i++) {
993 if (!mystep[i].isStarted()) {
996 if (!mystep[i].isFinished()) {
1007 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
1010 public Scenario addScenario(final Study aStudy,
1011 final Scenario.Properties sprop) throws MissedPropertyException,
1012 InvalidPropertyException, MultiplyDefinedException {
1013 if (sprop.getManager() == null) {
1014 sprop.setManager(aStudy.getAuthor());
1017 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
1018 if (sprop.getBaseStep() != null) {
1019 copyContentsUpTo(scenario, sprop.getBaseStep());
1021 Scenario previous = sprop.getInsertAfter();
1023 if (previous == null) {
1024 aStudy.getScenariiList().add(scenario);
1026 aStudy.getScenariiList().add(
1027 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
1029 getStudyDAO().update(aStudy); // No need to update the Lucene index
1030 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
1031 if (sprop.getBaseStep() != null) {
1032 // No need to update the Knowledge Element index as Knowledge Elements are not copied
1033 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
1035 KnowledgeElementType ucase = getKnowledgeElementTypeService()
1036 .selectType("usecase");
1037 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
1038 // TODO: Get appropriate user by its role: UserService.getAdmin();
1039 // User admin = getUserService().selectUser(1); // First user created when creating the database
1040 Role adminRole = getRoleDAO().getFilteredList(
1041 Restrictions.like("role", "%sysadmin%")).get(0);
1042 User admin = getUserDAO().getFilteredList(
1043 Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
1045 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
1046 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
1048 addKnowledgeElement(scenario, kprop);
1053 * Remove a knowledge element from a scenario.
1058 * the knowledge element to remove
1059 * @return true if removal succeeded
1062 public boolean removeKnowledgeElement(final Scenario scenario,
1063 final KnowledgeElement kelm) {
1064 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
1065 boolean isOk = (torem != null);
1067 isOk = scenario.getKnowledgeElements().remove(torem);
1069 getScenarioDAO().merge(scenario);
1070 // Update of my transient data
1071 // RKV: These transient data are not used indeed.
1072 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
1073 // RKV: kelm.getType().getIndex());
1074 // RKV: kelms.remove(torem);
1075 if (scenario.getKnowledgeElementsList() != null) {
1076 scenario.getKnowledgeElementsList().remove(torem);
1078 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
1088 * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
1091 public void renameScenario(final Scenario scenario) {
1092 getScenarioDAO().merge(scenario);
1096 * Get the knowledgeElementDAO.
1098 * @return the knowledgeElementDAO
1100 public KnowledgeElementDAO getKnowledgeElementDAO() {
1101 return _knowledgeElementDAO;
1105 * Set the knowledgeElementDAO.
1107 * @param knowledgeElementDAO
1108 * the knowledgeElementDAO to set
1110 public void setKnowledgeElementDAO(
1111 final KnowledgeElementDAO knowledgeElementDAO) {
1112 _knowledgeElementDAO = knowledgeElementDAO;
1116 * Get the indexService.
1118 * @return the indexService
1120 public IndexService getIndexService() {
1121 return _indexService;
1125 * Set the indexService.
1127 * @param indexService
1128 * the indexService to set
1130 public void setIndexService(final IndexService indexService) {
1131 _indexService = indexService;
1135 * Get the scenarioDAO.
1137 * @return the scenarioDAO
1139 public ScenarioDAO getScenarioDAO() {
1140 return _scenarioDAO;
1144 * Set the scenarioDAO.
1146 * @param scenarioDAO
1147 * the scenarioDAO to set
1149 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
1150 _scenarioDAO = scenarioDAO;
1156 * @return the studyDAO
1158 public StudyDAO getStudyDAO() {
1166 * the studyDAO to set
1168 public void setStudyDAO(final StudyDAO studyDAO) {
1169 _studyDAO = studyDAO;
1173 * Get the knowledgeElementTypeService.
1175 * @return the knowledgeElementTypeService
1177 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
1178 return _knowledgeElementTypeService;
1182 * Set the knowledgeElementTypeService.
1184 * @param knowledgeElementTypeService
1185 * the knowledgeElementTypeService to set
1187 public void setKnowledgeElementTypeService(
1188 final KnowledgeElementTypeService knowledgeElementTypeService) {
1189 _knowledgeElementTypeService = knowledgeElementTypeService;
1193 * Get the studyService.
1195 * @return the studyService
1197 public StudyService getStudyService() {
1198 return _studyService;
1202 * Set the studyService.
1204 * @param studyService
1205 * the studyService to set
1207 public void setStudyService(final StudyService studyService) {
1208 _studyService = studyService;
1212 * Get the userService.
1214 * @return the userService
1216 public UserService getUserService() {
1217 return _userService;
1221 * Set the userService.
1223 * @param userService
1224 * the userService to set
1226 public void setUserService(final UserService userService) {
1227 _userService = userService;
1233 * @return the userDAO
1235 public UserDAO getUserDAO() {
1243 * the userDAO to set
1245 public void setUserDAO(final UserDAO userDAO) {
1250 * Get the knowledgeElementTypeDAO.
1252 * @return the knowledgeElementTypeDAO
1254 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
1255 return _knowledgeElementTypeDAO;
1259 * Set the knowledgeElementTypeDAO.
1261 * @param knowledgeElementTypeDAO
1262 * the knowledgeElementTypeDAO to set
1264 public void setKnowledgeElementTypeDAO(
1265 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
1266 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
1270 * Get the simulationContextService.
1272 * @return the simulationContextService
1274 public SimulationContextService getSimulationContextService() {
1275 return _simulationContextService;
1279 * Set the simulationContextService.
1281 * @param simulationContextService
1282 * the simulationContextService to set
1284 public void setSimulationContextService(
1285 final SimulationContextService simulationContextService) {
1286 _simulationContextService = simulationContextService;
1290 * Get project settings.
1292 * @return Project settings service
1294 private ProjectSettingsService getProjectSettings() {
1295 return _projectSettings;
1299 * Set project settings service.
1301 * @param projectSettingsService
1302 * project settings service
1304 public void setProjectSettings(
1305 final ProjectSettingsService projectSettingsService) {
1306 _projectSettings = projectSettingsService;
1310 * Get the documentTypeService.
1312 * @return the documentTypeService
1314 public DocumentTypeService getDocumentTypeService() {
1315 return _documentTypeService;
1319 * Set the documentTypeService.
1321 * @param documentTypeService
1322 * the documentTypeService to set
1324 public void setDocumentTypeService(
1325 final DocumentTypeService documentTypeService) {
1326 _documentTypeService = documentTypeService;
1332 * @return the roleDAO
1334 public RoleDAO getRoleDAO() {
1342 * the roleDAO to set
1344 public void setRoleDAO(final RoleDAO roleDAO) {