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.Document.Properties;
31 import org.splat.dal.bo.som.DocumentType;
32 import org.splat.dal.bo.som.File;
33 import org.splat.dal.bo.som.KnowledgeElement;
34 import org.splat.dal.bo.som.KnowledgeElementType;
35 import org.splat.dal.bo.som.ProgressState;
36 import org.splat.dal.bo.som.Publication;
37 import org.splat.dal.bo.som.Scenario;
38 import org.splat.dal.bo.som.SimulationContext;
39 import org.splat.dal.bo.som.SimulationContextType;
40 import org.splat.dal.bo.som.Study;
41 import org.splat.dal.bo.som.UsedByRelation;
42 import org.splat.dal.bo.som.UsesRelation;
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 simulation context type service.
145 private SimulationContextTypeService _simulationContextTypeService;
148 * Injected project service.
150 private ProjectSettingsService _projectSettings;
153 * Injected document type service.
155 private DocumentTypeService _documentTypeService;
158 * Get the projectElementService.
160 * @return the projectElementService
162 public ProjectElementService getProjectElementService() {
163 return _projectElementService;
167 * Set the projectElementService.
169 * @param projectElementService
170 * the projectElementService to set
172 public void setProjectElementService(
173 final ProjectElementService projectElementService) {
174 _projectElementService = projectElementService;
178 * Get the publicationService.
180 * @return the publicationService
182 public PublicationService getPublicationService() {
183 return _publicationService;
187 * Set the publicationService.
189 * @param publicationService
190 * the publicationService to set
192 public void setPublicationService(
193 final PublicationService publicationService) {
194 _publicationService = publicationService;
198 * Get the stepService.
200 * @return the stepService
202 public StepService getStepService() {
207 * Set the stepService.
210 * the stepService to set
212 public void setStepService(final StepService stepService) {
213 _stepService = stepService;
219 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
221 @Transactional(readOnly = true)
222 public List<StepDTO> getScenarioInfo(final long scenarioId) {
223 List<StepDTO> res = new ArrayList<StepDTO>();
224 // Get the scenario from the database by id
225 Scenario scen = getScenarioDAO().get(scenarioId);
226 if (LOG.isDebugEnabled()) {
227 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
228 + scen.getDocums().size());
230 // Get activities of the scenario
231 Step[] steps = getProjectElementService().getSteps(scen);
234 String docType, fileFormat;
237 // For each activity create a step DTO and add it to the result list
238 for (Step step : steps) {
239 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
241 if (LOG.isDebugEnabled()) {
242 LOG.debug("Step[" + stepDTO.getNumber()
243 + "]: Number of documents: "
244 + step.getDocuments().size());
246 // For each publication of the activity create a document DTO.
247 // Each file is considered as a source file.
248 for (Publication tag : step.getDocuments()) {
249 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
251 char aState = tag.getIsnew();
252 docType = tag.value().getType().getName();
253 // For each file of the document create a file DTO
254 // Process source file of the document
255 fileFormat = tag.value().getFile().getFormat();
256 doImport = getProjectSettings().doImport(docType, fileFormat);
257 if (doImport && (!tag.isOutdated())) {
258 processing = "file-import";
260 processing = "file-download";
262 File aFile = tag.value().getFile();
263 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
264 aState, processing, false);
265 // Process all exported files
266 for (Relation rel : tag.value().getRelations(
267 ConvertsRelation.class)) {
268 aFile = ((ConvertsRelation) rel).getTo();
269 fileFormat = aFile.getFormat();
270 doImport = getProjectSettings().doImport(docType,
272 if (doImport && (!tag.isOutdated())) {
273 processing = "file-import";
275 processing = "file-download";
277 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
278 aState, processing, false);
288 * @see org.splat.service.ScenarioService#createStudy(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
291 public long createStudy(final String username, final String title,
292 final String productName, final String description)
293 throws InvalidPropertyException, MissedPropertyException,
294 MultiplyDefinedException {
298 User author = getUserService().selectUser(username);
299 if (author == null) {
301 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
302 .toString(), username);
305 // Set the study properties
306 Study.Properties sprop = new Study.Properties();
307 sprop.setTitle(title).setManager(author);
308 sprop.setDescription(description);
310 // Find the product simulation context
311 SimulationContextType productContextType = getSimulationContextService()
312 .selectType("product");
313 SimulationContext.Properties cprop = new SimulationContext.Properties();
314 cprop.setType(productContextType).setValue(productName);
315 SimulationContext productCtx = getSimulationContextService()
316 .selectSimulationContext(productContextType, productName);
317 if (productCtx != null) {
318 cprop.setIndex(productCtx.getIndex());
321 // Set a first scenario properties
322 Scenario.Properties oprop = new Scenario.Properties();
323 oprop.setTitle(I18nUtils.getMessageLocaleDefault("label.scenario")
326 Study study = createStudy(sprop, oprop, cprop);
327 id = study.getIndex();
333 * Create a new study with one scenario and "product" simulation context.
336 * the study properties
338 * the scenario properties
340 * the "product" simulation context properties
341 * @return the created study
342 * @throws MissedPropertyException
343 * if a mandatory property is missed
344 * @throws InvalidPropertyException
345 * if a property is invalid
346 * @throws MultiplyDefinedException
347 * if some property occurs several times
350 public Study createStudy(final Study.Properties sprop,
351 final Scenario.Properties oprop,
352 final SimulationContext.Properties cprop)
353 throws MissedPropertyException, InvalidPropertyException,
354 MultiplyDefinedException {
355 Study study = getStudyService().createStudy(sprop);
356 addScenario(study, oprop);
357 if (cprop.getIndex() == 0) { // Input of new project context
358 cprop.setType(getSimulationContextService().selectType("product"))
359 .setValue(cprop.getValue());
360 getStudyService().addProjectContext(study, cprop);
361 } else { // Selection of existing project context
362 SimulationContext context = getSimulationContextService()
363 .selectSimulationContext(cprop.getIndex());
364 getStudyService().addProjectContext(study, context);
371 * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
374 public void assignStudyContext(final Long studyId, final String ctxType,
375 final String ctxValue) throws MissedPropertyException,
376 InvalidPropertyException, MultiplyDefinedException {
377 // Find the study by the given id
378 Study study = getStudyDAO().get(studyId);
380 throw new InvalidPropertyException(MessageKeyEnum.STD_000002
381 .toString(), studyId);
383 // Find the context type by its name
384 SimulationContextType celt = getSimulationContextService().selectType(
387 // Creation of a new context type
388 celt = getSimulationContextTypeService().createType(ctxType,
389 getProjectElementService().getFirstStep(study).getStep());
391 // Find the given context value of the given type
392 SimulationContext context = getSimulationContextService()
393 .selectSimulationContext(celt, ctxValue);
394 if (context == null) { // Input of a new project context
395 SimulationContext.Properties cprop = new SimulationContext.Properties();
396 cprop.setType(celt).setValue(ctxValue);
397 getStudyService().addProjectContext(study, cprop);
398 } else { // Selection of existing project context
399 getStudyService().addProjectContext(study, context);
406 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
407 * org.splat.dal.bo.som.KnowledgeElement.Properties)
410 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
411 final KnowledgeElement.Properties kprop)
412 throws MissedPropertyException, InvalidPropertyException,
413 MultiplyDefinedException {
414 KnowledgeElement kelm = null;
416 long aScenarioId = aScenarioDTO.getIndex();
417 if (LOG.isDebugEnabled()) {
419 .debug("Add a knowledge element to the scenario #"
422 // Get the persistent scenario.
423 Scenario aScenario = getScenarioDAO().get(aScenarioId);
424 // Get persistent objects for creating a new knowledge.
425 // TODO: Actions must use DTO instead of persistent objects.
426 getUserDAO().merge(kprop.getAuthor());
427 getKnowledgeElementTypeDAO().merge(kprop.getType());
428 // Create a transient knowledge element related to the given scenario.
429 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
430 // Save the new knowledge in the database.
431 getKnowledgeElementDAO().create(kelm);
432 // Update scenario transient data.
433 if (kelm.getType().equals("usecase")) {
434 aScenarioDTO.setUcase(kelm);
435 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
436 aScenarioDTO.getKnowledgeElementsList().add(kelm);
439 // Load the workflow for the parent study to take into account
440 // all study actors durng reindexing.
441 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
443 // // Update the lucene index of knowledge elements.
444 // getIndexService().add(kelm);
445 if (LOG.isDebugEnabled()) {
446 LOG.debug("A knowledge element #" + kelm.getIndex()
447 + " is added to the scenario #" + aScenario.getIndex());
449 // } catch (IOException error) {
450 // LOG.error("Unable to index the knowedge element '"
451 // + kelm.getIndex() + "', reason:", error);
459 * Update the scenario in the database.
462 * the scenario to update
463 * @return true if updating succeeded
466 private boolean update(final Scenario aScenario) {
467 boolean isOk = false;
469 getScenarioDAO().update(aScenario); // Update of relational base
471 } catch (Exception error) {
472 LOG.error("Unable to re-index the knowledge element '"
473 + aScenario.getIndex() + "', reason:", error);
481 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
484 public void checkin(final long scenId, final long userId,
485 final List<StepDTO> scInfo) throws InvalidPropertyException,
486 MissedPropertyException, MultiplyDefinedException,
487 MismatchException, IOException, NotApplicableException {
488 // Get the scenario from the database by id
489 Scenario aScenario = getScenarioDAO().get(scenId);
490 // Get the user who perform this check-in operation
491 User aUser = getUserService().selectUser(userId);
492 // Get activities of the scenario
493 Step[] steps = getProjectElementService().getSteps(aScenario);
494 // Find result document types
495 List<DocumentType> resTypes = getDocumentTypeService()
496 .selectResultTypes();
498 // Keep newly created documents to create uses relations to results of a previous step.
499 // For each processed existing document keep its new version
500 Map<Document, Document> newVersion = new HashMap<Document, Document>();
501 // Created publications of new created versions of existing documents
502 List<Publication> newVers = new ArrayList<Publication>();
503 // The list of publications of new created documents not existing before the checkin
504 List<Publication> newDocs = new ArrayList<Publication>();
506 DocumentType resType;
507 Date aDate = new Date(); // The timestamp of the checkin operation
508 for (StepDTO stepDTO : scInfo) {
509 if (LOG.isDebugEnabled()) {
510 LOG.debug("Checkin the step:\n" + stepDTO);
512 // Find a result document type of the step
516 if (resTypes.get(i).isResultOf(
517 getProjectSettings().getStep(stepDTO.getNumber()))) {
518 resType = resTypes.get(i);
521 } while ((resType == null) && (i < resTypes.size()));
523 // Find the appropriate scenario step
524 Step step = findStep(stepDTO, steps);
526 // Process each document of the step
527 for (DocumentDTO doc : stepDTO.getDocs()) {
528 checkinDoc(step, doc, aUser, resType, aDate, newVersion,
533 // Set uses/used relations
534 updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
536 // Mark the scenario as checked in
541 * Updated uses/used relations after checkin operation:<BR>
543 * <li>For each new version copy uses relations from the previous version.</li>
544 * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
545 * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
549 * the checked in scenario
551 * the mapping of documents existed before the checkin to their new created versions
553 * the list of publications of new created versions of documents existed before the checkin
555 * the list of publications of new created documents not existed before the checkin
557 private void updateRelationsAfterCheckin(final Scenario aScenario,
558 final Map<Document, Document> newVersion,
559 final List<Publication> newVers, final List<Publication> newDocs) {
560 // For each new version copy uses relations from the previous version.
561 for (Publication newVer : newVers) {
562 // For each Uses relation of the previous version
563 Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
564 if (LOG.isDebugEnabled()) {
565 LOG.debug("Previous version for publication #"
566 + newVer.getIndex() + " is found: " + prevDoc);
568 List<Relation> usesRelations = prevDoc
569 .getRelations(UsesRelation.class);
570 for (Relation rel : usesRelations) {
571 // If used document has been also versioned then refer to its new version.
572 Document usedDoc = ((UsesRelation) rel).getTo();
573 if (newVersion.containsKey(usedDoc)) {
574 usedDoc = newVersion.get(usedDoc);
576 // Build the appropriate relation for the new version.
577 newVer.addDependency(usedDoc);
579 // Outdate documents which depend from the previous version and
580 // were not checked in during this operation.
581 // 1. Get all usedBy relations of the previous document version
582 for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
583 Document using = ((UsedByRelation) rel).getTo();
584 // Check that not checked in dependent documents became outdated
585 Publication usingPub = aScenario.getPublication(using);
586 if (usingPub != null) { // if the document using the old version is still published
587 usingPub.setIsnew('O');
592 // For each new document create uses relation to the last versions of
593 // results of the previous step.
594 for (Publication newPub : newDocs) {
595 // Find used document type according to the configuration.
596 Set<DocumentType> usedTypes = newPub.value().getType()
598 // Find documents of used type in the previous study step.
599 for (Publication pub : aScenario.getDocums()) {
600 if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
601 && (!pub.isOutdated())
602 && usedTypes.contains(pub.value().getType())) {
603 // Create uses relation from the new document
604 // to the found document in the previous step.
605 newPub.addDependency(pub);
612 * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
613 * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
614 * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
617 * the destination scenario step
619 * the DTO of the document to checkin
621 * the user who performs checkin
623 * the result document type of the given step
625 * timestamp of the checkin operation
627 * the mapping of existing documents to their new created versions
629 * the list of publications of new created versions of existing documents
631 * the list of publications of new created documents not existing before the checkin
632 * @throws InvalidPropertyException
633 * if the scenario hasn't some of given steps or documents
634 * @throws IOException
635 * if a file can't be moved into the vault
636 * @throws MismatchException
637 * if version creation in some of steps is failed
638 * @throws MissedPropertyException
639 * if some mandatory property is missed when new document or new document version is created
640 * @throws MultiplyDefinedException
641 * if some property is defined several times when new document or new document version is created
642 * @throws NotApplicableException
643 * if failed saving of a new publication with a given state
645 private void checkinDoc(final Step step, final DocumentDTO doc,
646 final User aUser, final DocumentType resType, final Date aDate,
647 final Map<Document, Document> newVersion,
648 final List<Publication> newVers, final List<Publication> newDocs)
649 throws InvalidPropertyException, MismatchException,
650 MissedPropertyException, MultiplyDefinedException, IOException,
651 NotApplicableException {
652 if (doc.getFiles().size() > 0) {
653 Document.Properties dprop = new Document.Properties();
654 // NOTE: Process only the first attached file for each document
655 FileDTO file = doc.getFiles().get(0);
656 dprop.setLocalPath(file.getPath());
658 // Get document title as the file name
659 java.io.File upfile = new java.io.File(file.getPath());
660 String fileFormat = upfile.getName().substring(
661 upfile.getName().lastIndexOf('.') + 1);
663 // Attach the file via ConvertsRelation, create a new document or
664 // create a new version of the document
665 dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
667 if (doc.getId() > 0) {
668 checkinExistingDoc(step, doc, dprop, fileFormat, upfile,
669 newVersion, newVers);
672 // Otherwise create a new document of the result type
673 // If result type is not found try to get type by file extension
674 if (resType == null) {
675 dprop.setType(getProjectSettings().getDefaultDocumentType(
676 step.getStep(), fileFormat));
678 dprop.setType(resType);
680 // New document title generation as <document type name>_N
681 String docname = dprop.getType().getName();
683 for (Publication scenPub : step.getOwner().getDocums()) {
684 if (scenPub.value().getTitle().startsWith(docname)) {
688 docname += "_" + i; // The generated new document title
690 dprop.setDescription("Checked in").setName(docname);
691 Publication newPub = getStepService().createDocument(step,
694 // Remeber the new document
697 saveFile(newPub, step, upfile);
703 * Check in existing document.
706 * study step to check in
708 * document DTO to check in
710 * document properties
712 * checked in file format
714 * the file to check in
716 * the map of created versions during this check in
718 * the list of new versions created during this check in
719 * @throws InvalidPropertyException
720 * if publication of the document is not found in the step
721 * @throws MismatchException
722 * if the found publication does not point to a document
723 * @throws IOException
724 * if can not move the file into the vault
725 * @throws MultiplyDefinedException
726 * thrown by versionDocument
727 * @throws MissedPropertyException
728 * thrown by versionDocument
729 * @throws NotApplicableException
730 * if failed saving of a new publication with a given state
732 private void checkinExistingDoc(final Step step, final DocumentDTO doc,
733 final Properties dprop, final String fileFormat,
734 final java.io.File upfile,
735 final Map<Document, Document> newVersion,
736 final List<Publication> newVers) throws InvalidPropertyException,
737 MismatchException, MissedPropertyException,
738 MultiplyDefinedException, IOException, NotApplicableException {
739 // If the document already exists then
740 // Attach the file via ConvertsRelation if the extension of the
741 // new file differs from the old one.
742 // If file format (i.e. extension) is the same then create a new
743 // version of the document.
744 // Find the document publication
745 Publication pub = step.getDocument(doc.getId());
747 throw new InvalidPropertyException(MessageKeyEnum.SCN_000002
748 .toString(), doc.getId());
750 if (pub.value() == null) {
751 throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
754 if (LOG.isDebugEnabled()) {
755 LOG.debug("Old format: " + pub.value().getFormat()
756 + " => New format: " + fileFormat);
758 // If formats are same then create a new document version
759 if (pub.value().getFormat() != null
760 && pub.value().getFormat().equals(fileFormat)) {
761 Publication newPub = getStepService().versionDocument(step, pub,
763 if (LOG.isDebugEnabled()) {
764 LOG.debug("Created document type: "
765 + newPub.value().getType().getName() + ", format: "
766 + newPub.value().getFormat());
768 // Remeber the link from the old document to the new document version
769 newVersion.put(pub.value(), newPub.value());
770 // Remember the new version publication
773 saveFile(newPub, step, upfile);
775 } else { // If formats are different then attach the new file via ConvertsRelation
776 File attach = pub.value().getAttachedFile(fileFormat);
777 if (attach == null) {
778 // If there is no attachment with this extension then attach the new one
779 ConvertsRelation export = getPublicationService().attach(pub,
781 if (LOG.isDebugEnabled()) {
782 LOG.debug("Moving " + upfile.getName() + " to "
783 + export.getTo().asFile().getPath());
785 upfile.renameTo(export.getTo().asFile());
787 // If an attachment with this extension already exists then
788 // replace it by the new one
789 upfile.renameTo(attach.asFile());
790 // Update attached file modification date
791 attach.setDate(new Date());
797 * Save the file in the vault and create its publication in the step.
800 * the new publication to save
802 * the study step to publish the document
804 * the downloaded file
805 * @throws IOException
806 * if a file can't be moved into the vault
807 * @throws NotApplicableException
808 * if failed saving of a new publication with a given state
810 private void saveFile(final Publication newPub, final Step step,
811 final java.io.File upfile) throws IOException,
812 NotApplicableException {
813 // Attach the file to the created document
814 java.io.File updir = newPub.getSourceFile().asFile();
815 if (LOG.isDebugEnabled()) {
816 LOG.debug("Moving \"" + upfile.getName() + "\" to \""
817 + updir.getPath() + "\".");
819 if (updir.exists()) {
820 if (updir.delete()) {
821 LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
822 .getAbsoluteFile(), step.getOwner().getIndex());
824 throw new IOException(
825 "Can't delete the existing destination file to move file from "
826 + upfile.getAbsolutePath() + " to "
827 + updir.getAbsolutePath());
830 if (upfile.renameTo(updir)) {
831 // Save the new publication in the scenario.
832 // The old publication is removed from the scenario here.
833 getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
835 throw new IOException("Can't move file from "
836 + upfile.getAbsolutePath() + " to "
837 + updir.getAbsolutePath());
842 * Find appropriate step in the array of scenario steps according to the given step DTO.
848 * @return appropriate scenario step
849 * @throws InvalidPropertyException
850 * if appropriate step is not found
852 private Step findStep(final StepDTO stepDTO, final Step[] steps)
853 throws InvalidPropertyException {
857 if (steps[i].getNumber() == stepDTO.getNumber()) {
861 } while ((step == null) && (i < steps.length));
864 throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
865 .toString(), stepDTO.getNumber());
873 * @see org.splat.service.ScenarioService#checkin(long)
876 public void checkin(final long scenarioId) throws InvalidPropertyException {
877 Scenario aScenario = getScenarioDAO().get(scenarioId);
878 if (aScenario == null) {
879 // Scenario not found
880 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
881 .toString(), scenarioId);
887 * Mark the scenario as checked in.
890 * the scenario to check in.
892 private void checkin(final Scenario aScenario) {
893 aScenario.setUser(null);
894 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
895 // getScenarioDAO().update(aScenario);
901 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
903 public boolean checkout(final Scenario aScenario, final User user) {
904 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
907 aScenario.setUser(user);
908 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
909 // RKV: getScenarioDAO().update(aScenario);
915 * Mark the given scenario as checked out by the given user.
920 * the id of the user performing the check out
921 * @throws InvalidPropertyException
922 * if the user or the scenario is not found in the database
923 * @throws NotApplicableException
924 * if the given user can not check out the scenario
927 public void checkout(final long scenarioId, final long userId)
928 throws InvalidPropertyException, NotApplicableException {
929 User aUser = getUserService().selectUser(userId);
932 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
933 .toString(), userId);
935 Scenario aScenario = getScenarioDAO().get(scenarioId);
936 if (aScenario == null) {
937 // Scenario not found
938 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
939 .toString(), scenarioId);
941 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
944 if (aScenario.isCheckedout()
945 && (!aScenario.getUser().getUsername().equals(
946 aUser.getUsername()))) {
947 throw new NotApplicableException(MessageKeyEnum.SCN_000008
948 .toString(), scenarioId, aScenario.getUser()
951 aScenario.setUser(aUser);
952 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
954 // User doesn't participate in the scenario
955 throw new NotApplicableException(MessageKeyEnum.SCN_000007
956 .toString(), aUser.getUsername(), scenarioId);
963 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
965 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
966 Scenario base = (Scenario) lastep.getOwner();
967 Step[] from = getProjectElementService().getSteps(base);
968 Step[] to = getProjectElementService().getSteps(scenario);
969 for (int i = 0; i < from.length; i++) {
971 if (step.getNumber() > lastep.getNumber()) {
975 List<Publication> docs = step.getAllDocuments();
976 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
977 Publication doc = getPublicationService().copy(j.next(),
978 scenario); // Creation of a new reference to the document
979 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
980 getStepService().add(to[i], doc);
982 List<SimulationContext> ctex = step.getAllSimulationContexts();
983 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
984 getStepService().addSimulationContext(to[i], j.next());
992 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
994 public boolean isEmpty(final Scenario scenario) {
995 Step[] mystep = getProjectElementService().getSteps(scenario);
996 boolean isEmp = true;
997 for (int i = 0; i < mystep.length; i++) {
998 if (mystep[i].isStarted()) {
1010 public boolean isFinished(final Scenario scenario) {
1011 Step[] mystep = getProjectElementService().getSteps(scenario);
1012 boolean notempty = false; // If this is empty, this is not finished
1013 for (int i = 0; i < mystep.length; i++) {
1014 if (!mystep[i].isStarted()) {
1017 if (!mystep[i].isFinished()) {
1028 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
1031 public Scenario addScenario(final Study aStudy,
1032 final Scenario.Properties sprop) throws MissedPropertyException,
1033 InvalidPropertyException, MultiplyDefinedException {
1034 if (sprop.getManager() == null) {
1035 sprop.setManager(aStudy.getAuthor());
1038 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
1039 if (sprop.getBaseStep() != null) {
1040 copyContentsUpTo(scenario, sprop.getBaseStep());
1042 Scenario previous = sprop.getInsertAfter();
1044 if (previous == null) {
1045 aStudy.getScenariiList().add(scenario);
1047 aStudy.getScenariiList().add(
1048 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
1050 getStudyDAO().update(aStudy); // No need to update the Lucene index
1051 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
1052 if (sprop.getBaseStep() != null) {
1053 // No need to update the Knowledge Element index as Knowledge Elements are not copied
1054 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
1056 KnowledgeElementType ucase = getKnowledgeElementTypeService()
1057 .selectType("usecase");
1058 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
1059 // TODO: Get appropriate user by its role: UserService.getAdmin();
1060 // User admin = getUserService().selectUser(1); // First user created when creating the database
1061 Role adminRole = getRoleDAO().getFilteredList(
1062 Restrictions.like("role", "%sysadmin%")).get(0);
1063 User admin = getUserDAO().getFilteredList(
1064 Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
1066 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
1067 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
1069 addKnowledgeElement(scenario, kprop);
1074 * Remove a knowledge element from a scenario.
1079 * the knowledge element to remove
1080 * @return true if removal succeeded
1083 public boolean removeKnowledgeElement(final Scenario scenario,
1084 final KnowledgeElement kelm) {
1085 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
1086 boolean isOk = (torem != null);
1088 isOk = scenario.getKnowledgeElements().remove(torem);
1090 getScenarioDAO().merge(scenario);
1091 // Update of my transient data
1092 // RKV: These transient data are not used indeed.
1093 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
1094 // RKV: kelm.getType().getIndex());
1095 // RKV: kelms.remove(torem);
1096 if (scenario.getKnowledgeElementsList() != null) {
1097 scenario.getKnowledgeElementsList().remove(torem);
1099 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
1109 * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
1112 public void renameScenario(final Scenario scenario) {
1113 getScenarioDAO().merge(scenario);
1117 * Get the knowledgeElementDAO.
1119 * @return the knowledgeElementDAO
1121 public KnowledgeElementDAO getKnowledgeElementDAO() {
1122 return _knowledgeElementDAO;
1126 * Set the knowledgeElementDAO.
1128 * @param knowledgeElementDAO
1129 * the knowledgeElementDAO to set
1131 public void setKnowledgeElementDAO(
1132 final KnowledgeElementDAO knowledgeElementDAO) {
1133 _knowledgeElementDAO = knowledgeElementDAO;
1137 * Get the indexService.
1139 * @return the indexService
1141 public IndexService getIndexService() {
1142 return _indexService;
1146 * Set the indexService.
1148 * @param indexService
1149 * the indexService to set
1151 public void setIndexService(final IndexService indexService) {
1152 _indexService = indexService;
1156 * Get the scenarioDAO.
1158 * @return the scenarioDAO
1160 public ScenarioDAO getScenarioDAO() {
1161 return _scenarioDAO;
1165 * Set the scenarioDAO.
1167 * @param scenarioDAO
1168 * the scenarioDAO to set
1170 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
1171 _scenarioDAO = scenarioDAO;
1177 * @return the studyDAO
1179 public StudyDAO getStudyDAO() {
1187 * the studyDAO to set
1189 public void setStudyDAO(final StudyDAO studyDAO) {
1190 _studyDAO = studyDAO;
1194 * Get the knowledgeElementTypeService.
1196 * @return the knowledgeElementTypeService
1198 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
1199 return _knowledgeElementTypeService;
1203 * Set the knowledgeElementTypeService.
1205 * @param knowledgeElementTypeService
1206 * the knowledgeElementTypeService to set
1208 public void setKnowledgeElementTypeService(
1209 final KnowledgeElementTypeService knowledgeElementTypeService) {
1210 _knowledgeElementTypeService = knowledgeElementTypeService;
1214 * Get the studyService.
1216 * @return the studyService
1218 public StudyService getStudyService() {
1219 return _studyService;
1223 * Set the studyService.
1225 * @param studyService
1226 * the studyService to set
1228 public void setStudyService(final StudyService studyService) {
1229 _studyService = studyService;
1233 * Get the userService.
1235 * @return the userService
1237 public UserService getUserService() {
1238 return _userService;
1242 * Set the userService.
1244 * @param userService
1245 * the userService to set
1247 public void setUserService(final UserService userService) {
1248 _userService = userService;
1254 * @return the userDAO
1256 public UserDAO getUserDAO() {
1264 * the userDAO to set
1266 public void setUserDAO(final UserDAO userDAO) {
1271 * Get the knowledgeElementTypeDAO.
1273 * @return the knowledgeElementTypeDAO
1275 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
1276 return _knowledgeElementTypeDAO;
1280 * Set the knowledgeElementTypeDAO.
1282 * @param knowledgeElementTypeDAO
1283 * the knowledgeElementTypeDAO to set
1285 public void setKnowledgeElementTypeDAO(
1286 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
1287 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
1291 * Get the simulationContextService.
1293 * @return the simulationContextService
1295 public SimulationContextService getSimulationContextService() {
1296 return _simulationContextService;
1300 * Set the simulationContextService.
1302 * @param simulationContextService
1303 * the simulationContextService to set
1305 public void setSimulationContextService(
1306 final SimulationContextService simulationContextService) {
1307 _simulationContextService = simulationContextService;
1311 * Get project settings.
1313 * @return Project settings service
1315 private ProjectSettingsService getProjectSettings() {
1316 return _projectSettings;
1320 * Set project settings service.
1322 * @param projectSettingsService
1323 * project settings service
1325 public void setProjectSettings(
1326 final ProjectSettingsService projectSettingsService) {
1327 _projectSettings = projectSettingsService;
1331 * Get the documentTypeService.
1333 * @return the documentTypeService
1335 public DocumentTypeService getDocumentTypeService() {
1336 return _documentTypeService;
1340 * Set the documentTypeService.
1342 * @param documentTypeService
1343 * the documentTypeService to set
1345 public void setDocumentTypeService(
1346 final DocumentTypeService documentTypeService) {
1347 _documentTypeService = documentTypeService;
1353 * @return the roleDAO
1355 public RoleDAO getRoleDAO() {
1363 * the roleDAO to set
1365 public void setRoleDAO(final RoleDAO roleDAO) {
1370 * Get the simulationContextTypeService.
1372 * @return the simulationContextTypeService
1374 public SimulationContextTypeService getSimulationContextTypeService() {
1375 return _simulationContextTypeService;
1379 * Set the simulationContextTypeService.
1381 * @param simulationContextTypeService
1382 * the simulationContextTypeService to set
1384 public void setSimulationContextTypeService(
1385 final SimulationContextTypeService simulationContextTypeService) {
1386 _simulationContextTypeService = simulationContextTypeService;