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.dao.kernel.RoleDAO;
42 import org.splat.dal.dao.kernel.UserDAO;
43 import org.splat.dal.dao.som.KnowledgeElementDAO;
44 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
45 import org.splat.dal.dao.som.ScenarioDAO;
46 import org.splat.dal.dao.som.StudyDAO;
47 import org.splat.kernel.InvalidPropertyException;
48 import org.splat.kernel.MismatchException;
49 import org.splat.kernel.MissedPropertyException;
50 import org.splat.kernel.MultiplyDefinedException;
51 import org.splat.kernel.NotApplicableException;
52 import org.splat.log.AppLogger;
53 import org.splat.service.dto.DocumentDTO;
54 import org.splat.service.dto.FileDTO;
55 import org.splat.service.dto.StepDTO;
56 import org.splat.service.technical.IndexService;
57 import org.splat.service.technical.ProjectSettingsService;
58 import org.splat.som.Step;
59 import org.splat.util.BeanHelper;
60 import org.springframework.transaction.annotation.Transactional;
63 * Scenario service implementation.
65 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
67 public class ScenarioServiceImpl implements ScenarioService {
70 * The logger for the service.
72 public final static AppLogger LOG = AppLogger
73 .getLogger(ScenarioServiceImpl.class);
76 * Injected index service.
78 private IndexService _indexService;
80 * Injected step service.
82 private StepService _stepService;
84 * Injected study service.
86 private StudyService _studyService;
88 * Injected publication service.
90 private PublicationService _publicationService;
92 * Injected project element service.
94 private ProjectElementService _projectElementService;
96 * Injected knowledge element DAO.
98 private KnowledgeElementDAO _knowledgeElementDAO;
100 * Injected scenario DAO.
102 private ScenarioDAO _scenarioDAO;
105 * Injected study DAO.
107 private StudyDAO _studyDAO;
110 * Injected knowledge element service.
112 private KnowledgeElementTypeService _knowledgeElementTypeService;
115 * Injected user service.
117 private UserService _userService;
122 private UserDAO _userDAO;
127 private RoleDAO _roleDAO;
130 * Injected knowledge element type DAO.
132 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
135 * Injected simulation context service.
137 private SimulationContextService _simulationContextService;
140 * Injected project service.
142 private ProjectSettingsService _projectSettings;
145 * Injected document type service.
147 private DocumentTypeService _documentTypeService;
150 * Get the projectElementService.
152 * @return the projectElementService
154 public ProjectElementService getProjectElementService() {
155 return _projectElementService;
159 * Set the projectElementService.
161 * @param projectElementService
162 * the projectElementService to set
164 public void setProjectElementService(
165 final ProjectElementService projectElementService) {
166 _projectElementService = projectElementService;
170 * Get the publicationService.
172 * @return the publicationService
174 public PublicationService getPublicationService() {
175 return _publicationService;
179 * Set the publicationService.
181 * @param publicationService
182 * the publicationService to set
184 public void setPublicationService(
185 final PublicationService publicationService) {
186 _publicationService = publicationService;
190 * Get the stepService.
192 * @return the stepService
194 public StepService getStepService() {
199 * Set the stepService.
202 * the stepService to set
204 public void setStepService(final StepService stepService) {
205 _stepService = stepService;
211 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
213 @Transactional(readOnly = true)
214 public List<StepDTO> getScenarioInfo(final long scenarioId) {
215 List<StepDTO> res = new ArrayList<StepDTO>();
216 // Get the scenario from the database by id
217 Scenario scen = getScenarioDAO().get(scenarioId);
218 if (LOG.isDebugEnabled()) {
219 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
220 + scen.getDocums().size());
222 // Get activities of the scenario
223 Step[] steps = getProjectElementService().getSteps(scen);
226 String docType, fileFormat;
229 // For each activity create a step DTO and add it to the result list
230 for (Step step : steps) {
231 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
233 if (LOG.isDebugEnabled()) {
234 LOG.debug("Step[" + stepDTO.getNumber()
235 + "]: Number of documents: "
236 + step.getDocuments().size());
238 // For each publication of the activity create a document DTO.
239 // Each file is considered as a source file.
240 for (Publication tag : step.getDocuments()) {
241 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
243 char aState = tag.getIsnew();
244 docType = tag.value().getType().getName();
245 // For each file of the document create a file DTO
246 // Process source file of the document
247 fileFormat = tag.value().getFile().getFormat();
248 doImport = getProjectSettings().doImport(docType, fileFormat);
249 if (doImport && (!tag.isOutdated())) {
250 processing = "file-import";
252 processing = "file-download";
254 File aFile = tag.value().getFile();
255 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
256 aState, processing, false);
257 // Process all exported files
258 for (Relation rel : tag.value().getRelations(
259 ConvertsRelation.class)) {
260 aFile = ((ConvertsRelation) rel).getTo();
261 fileFormat = aFile.getFormat();
262 doImport = getProjectSettings().doImport(docType,
264 if (doImport && (!tag.isOutdated())) {
265 processing = "file-import";
267 processing = "file-download";
269 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
270 aState, processing, false);
278 * Create a new study with one scenario and "product" simulation context.
281 * the study properties
283 * the scenario properties
285 * the "product" simulation context properties
286 * @return the created study
287 * @throws MissedPropertyException
288 * if a mandatory property is missed
289 * @throws InvalidPropertyException
290 * if a property is invalid
291 * @throws MultiplyDefinedException
292 * if some property occurs several times
295 public Study createStudy(final Study.Properties sprop,
296 final Scenario.Properties oprop,
297 final SimulationContext.Properties cprop)
298 throws MissedPropertyException, InvalidPropertyException,
299 MultiplyDefinedException {
300 Study study = getStudyService().createStudy(sprop);
301 addScenario(study, oprop);
302 if (cprop.getIndex() == 0) { // Input of new project context
303 cprop.setType(getSimulationContextService().selectType("product"))
304 .setValue(cprop.getValue());
305 getStudyService().addProjectContext(study, cprop);
306 } else { // Selection of existing project context
307 SimulationContext context = getSimulationContextService()
308 .selectSimulationContext(cprop.getIndex());
309 getStudyService().addProjectContext(study, context);
317 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
318 * org.splat.dal.bo.som.KnowledgeElement.Properties)
321 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
322 final KnowledgeElement.Properties kprop)
323 throws MissedPropertyException, InvalidPropertyException,
324 MultiplyDefinedException {
325 KnowledgeElement kelm = null;
327 long aScenarioId = aScenarioDTO.getIndex();
328 if (LOG.isDebugEnabled()) {
329 LOG.debug("Add a knowledge element to the scenario #"
332 // Get the persistent scenario.
333 Scenario aScenario = getScenarioDAO().get(aScenarioId);
334 // Get persistent objects for creating a new knowledge.
335 // TODO: Actions must use DTO instead of persistent objects.
336 getUserDAO().merge(kprop.getAuthor());
337 getKnowledgeElementTypeDAO().merge(kprop.getType());
338 // Create a transient knowledge element related to the given scenario.
339 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
340 // Save the new knowledge in the database.
341 getKnowledgeElementDAO().create(kelm);
342 // Update scenario transient data.
343 if (kelm.getType().equals("usecase")) {
344 aScenarioDTO.setUcase(kelm);
345 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
346 aScenarioDTO.getKnowledgeElementsList().add(kelm);
349 // Load the workflow for the parent study to take into account
350 // all study actors durng reindexing.
351 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
353 // Update the lucene index of knowledge elements.
354 getIndexService().add(kelm);
355 if (LOG.isDebugEnabled()) {
356 LOG.debug("A knowledge element #" + kelm.getIndex()
357 + " is added to the scenario #" + aScenario.getIndex());
359 } catch (IOException error) {
360 LOG.error("Unable to index the knowedge element '"
361 + kelm.getIndex() + "', reason:", error);
369 * Update the scenario in the database.
372 * the scenario to update
373 * @return true if updating succeeded
376 private boolean update(final Scenario aScenario) {
377 boolean isOk = false;
379 getScenarioDAO().update(aScenario); // Update of relational base
381 } catch (Exception error) {
382 LOG.error("Unable to re-index the knowledge element '"
383 + aScenario.getIndex() + "', reason:", error);
391 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
394 public void checkin(final long scenId, final long userId,
395 final List<StepDTO> scInfo) throws InvalidPropertyException,
396 MissedPropertyException, MultiplyDefinedException,
397 MismatchException, IOException, NotApplicableException {
398 // Get the scenario from the database by id
399 Scenario aScenario = getScenarioDAO().get(scenId);
400 // Get the user who perform this check-in operation
401 User aUser = getUserService().selectUser(userId);
402 // Get activities of the scenario
403 Step[] steps = getProjectElementService().getSteps(aScenario);
404 // Find result document types
405 List<DocumentType> resTypes = getDocumentTypeService()
406 .selectResultTypes();
408 // Keep newly created documents to create uses relations to results of a previous step.
409 // For each processed existing document keep its new version
410 Map<Document, Document> newVersion = new HashMap<Document, Document>();
411 // Created publications of new created versions of existing documents
412 List<Publication> newVers = new ArrayList<Publication>();
413 // The list of publications of new created documents not existing before the checkin
414 List<Publication> newDocs = new ArrayList<Publication>();
416 DocumentType resType;
417 Date aDate = new Date(); // The timestamp of the checkin operation
418 for (StepDTO stepDTO : scInfo) {
419 if (LOG.isDebugEnabled()) {
420 LOG.debug("Checkin the step:\n" + stepDTO);
422 // Find a result document type of the step
426 if (resTypes.get(i).isResultOf(
427 getProjectSettings().getStep(stepDTO.getNumber()))) {
428 resType = resTypes.get(i);
431 } while ((resType == null) && (i < resTypes.size()));
433 // Find the appropriate scenario step
434 Step step = findStep(stepDTO, steps);
436 // Process each document of the step
437 for (DocumentDTO doc : stepDTO.getDocs()) {
438 checkinDoc(step, doc, aUser, resType, aDate, newVersion,
443 // Set uses/used relations
444 updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
446 // Mark the scenario as checked in
451 * Updated uses/used relations after checkin operation:<BR>
453 * <li>For each new version copy uses relations from the previous version.</li>
454 * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
455 * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
459 * the checked in scenario
461 * the mapping of documents existed before the checkin to their new created versions
463 * the list of publications of new created versions of documents existed before the checkin
465 * the list of publications of new created documents not existed before the checkin
467 private void updateRelationsAfterCheckin(final Scenario aScenario,
468 final Map<Document, Document> newVersion,
469 final List<Publication> newVers, final List<Publication> newDocs) {
470 // For each new version copy uses relations from the previous version.
471 for (Publication newVer : newVers) {
472 // For each Uses relation of the previous version
473 Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
474 if (LOG.isDebugEnabled()) {
475 LOG.debug("Previous version for publication #"
476 + newVer.getIndex() + " is found: " + prevDoc);
478 List<Relation> usesRelations = prevDoc
479 .getRelations(UsesRelation.class);
480 for (Relation rel : usesRelations) {
481 // If used document has been also versioned then refer to its new version.
482 Document usedDoc = ((UsesRelation) rel).getTo();
483 if (newVersion.containsKey(usedDoc)) {
484 usedDoc = newVersion.get(usedDoc);
486 // Build the appropriate relation for the new version.
487 newVer.addDependency(usedDoc);
489 // Outdate documents which depend from the previous version and
490 // were not checked in during this operation.
491 // 1. Get all usedBy relations of the previous document version
492 for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
493 Document using = ((UsedByRelation) rel).getTo();
494 // Check that not checked in dependent documents became outdated
495 Publication usingPub = aScenario.getPublication(using);
496 if (usingPub != null) { // if the document using the old version is still published
497 usingPub.setIsnew('O');
502 // For each new document create uses relation to the last versions of
503 // results of the previous step.
504 for (Publication newPub : newDocs) {
505 // Find used document type according to the configuration.
506 Set<DocumentType> usedTypes = newPub.value().getType()
508 // Find documents of used type in the previous study step.
509 for (Publication pub : aScenario.getDocums()) {
510 if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
511 && (!pub.isOutdated())
512 && usedTypes.contains(pub.value().getType())) {
513 // Create uses relation from the new document
514 // to the found document in the previous step.
515 newPub.addDependency(pub);
522 * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
523 * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
524 * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
527 * the destination scenario step
529 * the DTO of the document to checkin
531 * the user who performs checkin
533 * the result document type of the given step
535 * timestamp of the checkin operation
537 * the mapping of existing documents to their new created versions
539 * the list of publications of new created versions of existing documents
541 * the list of publications of new created documents not existing before the checkin
542 * @throws InvalidPropertyException
543 * if the scenario hasn't some of given steps or documents
544 * @throws IOException
545 * if a file can't be moved into the vault
546 * @throws MismatchException
547 * if version creation in some of steps is failed
548 * @throws MissedPropertyException
549 * if some mandatory property is missed when new document or new document version is created
550 * @throws MultiplyDefinedException
551 * if some property is defined several times when new document or new document version is created
552 * @throws NotApplicableException
553 * if failed saving of a new publication with a given state
555 private void checkinDoc(final Step step, final DocumentDTO doc,
556 final User aUser, final DocumentType resType, final Date aDate,
557 final Map<Document, Document> newVersion,
558 final List<Publication> newVers, final List<Publication> newDocs)
559 throws InvalidPropertyException, MismatchException,
560 MissedPropertyException, MultiplyDefinedException, IOException,
561 NotApplicableException {
562 if (doc.getFiles().size() > 0) {
563 Document.Properties dprop = new Document.Properties();
564 // NOTE: Process only the first attached file for each document
565 FileDTO file = doc.getFiles().get(0);
567 // Get document title as the file name
568 java.io.File upfile = new java.io.File(file.getPath());
569 String fileFormat = upfile.getName().substring(
570 upfile.getName().lastIndexOf('.') + 1);
572 // Create a new document or a new version of the document
573 dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
574 Publication pub, newPub;
576 if (doc.getId() > 0) {
577 // If the document already exists then create a new version of it
578 // Find the document publication
579 pub = step.getDocument(doc.getId());
581 throw new InvalidPropertyException(
582 MessageKeyEnum.SCN_000002.toString(), doc.getId());
584 if (pub.value() == null) {
585 throw new MismatchException(MessageKeyEnum.SCN_000002
586 .toString(), doc.getId());
588 if (LOG.isDebugEnabled()) {
589 LOG.debug("Old format: " + pub.value().getFormat()
590 + " => New format: " + fileFormat);
592 newPub = getStepService().versionDocument(step, pub, dprop);
593 if (LOG.isDebugEnabled()) {
594 LOG.debug("Created document type: "
595 + newPub.value().getType().getName() + ", format: "
596 + newPub.value().getFormat());
598 // Remeber the link from the old document to the new document version
599 newVersion.put(pub.value(), newPub.value());
600 // Remember the new version publication
604 // Otherwise create a new document of the result type
605 // If result type is not found try to get type by file extension
606 if (resType == null) {
607 dprop.setType(getProjectSettings().getDefaultDocumentType(
608 step.getStep(), fileFormat));
610 dprop.setType(resType);
612 // New document title generation as <document type name>_N
613 String docname = dprop.getType().getName();
615 for (Publication scenPub : step.getOwner().getDocums()) {
616 if (scenPub.value().getTitle().startsWith(docname)) {
620 docname += "_" + i; // The generated new document title
622 dprop.setDescription("Checked in").setName(docname);
623 newPub = getStepService().createDocument(step, dprop);
625 // Remeber the new document
629 // Attach the file to the created document
630 java.io.File updir = newPub.getSourceFile().asFile();
631 if (LOG.isDebugEnabled()) {
632 LOG.debug("Moving \"" + upfile.getName() + "\" to \""
633 + updir.getPath() + "\".");
635 if (updir.exists()) {
636 if (updir.delete()) {
637 LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
638 .getAbsoluteFile(), step.getOwner().getIndex());
640 throw new IOException(
641 "Can't delete the existing destination file to move file from "
642 + file.getPath() + " to "
643 + updir.getAbsolutePath());
646 if (upfile.renameTo(updir)) {
647 // Save the new publication in the scenario.
648 // The old publication is removed from the scenario here.
649 getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
651 throw new IOException("Can't move file from " + file.getPath()
652 + " to " + updir.getAbsolutePath());
658 * Find appropriate step in the array of scenario steps according to the given step DTO.
664 * @return appropriate scenario step
665 * @throws InvalidPropertyException
666 * if appropriate step is not found
668 private Step findStep(final StepDTO stepDTO, final Step[] steps)
669 throws InvalidPropertyException {
673 if (steps[i].getNumber() == stepDTO.getNumber()) {
677 } while ((step == null) && (i < steps.length));
680 throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
681 .toString(), stepDTO.getNumber());
689 * @see org.splat.service.ScenarioService#checkin(long)
692 public void checkin(final long scenarioId) throws InvalidPropertyException {
693 Scenario aScenario = getScenarioDAO().get(scenarioId);
694 if (aScenario == null) {
695 // Scenario not found
696 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
697 .toString(), scenarioId);
703 * Mark the scenario as checked in.
706 * the scenario to check in.
708 private void checkin(final Scenario aScenario) {
709 aScenario.setUser(null);
710 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
711 // getScenarioDAO().update(aScenario);
717 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
719 public boolean checkout(final Scenario aScenario, final User user) {
720 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
723 aScenario.setUser(user);
724 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
725 // RKV: getScenarioDAO().update(aScenario);
731 * Mark the given scenario as checked out by the given user.
736 * the id of the user performing the check out
737 * @throws InvalidPropertyException
738 * if the user or the scenario is not found in the database
739 * @throws NotApplicableException
740 * if the given user can not check out the scenario
743 public void checkout(final long scenarioId, final long userId)
744 throws InvalidPropertyException, NotApplicableException {
745 User aUser = getUserService().selectUser(userId);
748 throw new InvalidPropertyException(MessageKeyEnum.USR_000001
749 .toString(), userId);
751 Scenario aScenario = getScenarioDAO().get(scenarioId);
752 if (aScenario == null) {
753 // Scenario not found
754 throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
755 .toString(), scenarioId);
757 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
760 if (aScenario.isCheckedout()
761 && (!aScenario.getUser().getUsername().equals(
762 aUser.getUsername()))) {
763 throw new NotApplicableException(MessageKeyEnum.SCN_000008
764 .toString(), scenarioId, aScenario.getUser()
767 aScenario.setUser(aUser);
768 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
770 // User doesn't participate in the scenario
771 throw new NotApplicableException(MessageKeyEnum.SCN_000007
772 .toString(), aUser.getUsername(), scenarioId);
779 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
781 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
782 Scenario base = (Scenario) lastep.getOwner();
783 Step[] from = getProjectElementService().getSteps(base);
784 Step[] to = getProjectElementService().getSteps(scenario);
785 for (int i = 0; i < from.length; i++) {
787 if (step.getNumber() > lastep.getNumber()) {
791 List<Publication> docs = step.getAllDocuments();
792 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
793 Publication doc = getPublicationService().copy(j.next(),
794 scenario); // Creation of a new reference to the document
795 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
796 getStepService().add(to[i], doc);
798 List<SimulationContext> ctex = step.getAllSimulationContexts();
799 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
800 getStepService().addSimulationContext(to[i], j.next());
808 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
810 public boolean isEmpty(final Scenario scenario) {
811 Step[] mystep = getProjectElementService().getSteps(scenario);
812 boolean isEmp = true;
813 for (int i = 0; i < mystep.length; i++) {
814 if (mystep[i].isStarted()) {
826 public boolean isFinished(final Scenario scenario) {
827 Step[] mystep = getProjectElementService().getSteps(scenario);
828 boolean notempty = false; // If this is empty, this is not finished
829 for (int i = 0; i < mystep.length; i++) {
830 if (!mystep[i].isStarted()) {
833 if (!mystep[i].isFinished()) {
844 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
847 public Scenario addScenario(final Study aStudy,
848 final Scenario.Properties sprop) throws MissedPropertyException,
849 InvalidPropertyException, MultiplyDefinedException {
850 if (sprop.getManager() == null) {
851 sprop.setManager(aStudy.getAuthor());
854 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
855 if (sprop.getBaseStep() != null) {
856 copyContentsUpTo(scenario, sprop.getBaseStep());
858 Scenario previous = sprop.getInsertAfter();
860 if (previous == null) {
861 aStudy.getScenariiList().add(scenario);
863 aStudy.getScenariiList().add(
864 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
866 getStudyDAO().update(aStudy); // No need to update the Lucene index
867 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
868 if (sprop.getBaseStep() != null) {
869 // No need to update the Knowledge Element index as Knowledge Elements are not copied
870 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
872 KnowledgeElementType ucase = getKnowledgeElementTypeService()
873 .selectType("usecase");
874 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
875 // TODO: Get appropriate user by its role: UserService.getAdmin();
876 // User admin = getUserService().selectUser(1); // First user created when creating the database
877 Role adminRole = getRoleDAO().getFilteredList(
878 Restrictions.like("role", "%sysadmin%")).get(0);
879 User admin = getUserDAO().getFilteredList(
880 Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
882 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
883 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
885 addKnowledgeElement(scenario, kprop);
890 * Remove a knowledge element from a scenario.
895 * the knowledge element to remove
896 * @return true if removal succeeded
899 public boolean removeKnowledgeElement(final Scenario scenario,
900 final KnowledgeElement kelm) {
901 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
902 boolean isOk = (torem != null);
904 isOk = scenario.getKnowledgeElements().remove(torem);
906 getScenarioDAO().merge(scenario);
907 // Update of my transient data
908 // RKV: These transient data are not used indeed.
909 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
910 // RKV: kelm.getType().getIndex());
911 // RKV: kelms.remove(torem);
912 if (scenario.getKnowledgeElementsList() != null) {
913 scenario.getKnowledgeElementsList().remove(torem);
915 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
922 * Get the knowledgeElementDAO.
924 * @return the knowledgeElementDAO
926 public KnowledgeElementDAO getKnowledgeElementDAO() {
927 return _knowledgeElementDAO;
931 * Set the knowledgeElementDAO.
933 * @param knowledgeElementDAO
934 * the knowledgeElementDAO to set
936 public void setKnowledgeElementDAO(
937 final KnowledgeElementDAO knowledgeElementDAO) {
938 _knowledgeElementDAO = knowledgeElementDAO;
942 * Get the indexService.
944 * @return the indexService
946 public IndexService getIndexService() {
947 return _indexService;
951 * Set the indexService.
953 * @param indexService
954 * the indexService to set
956 public void setIndexService(final IndexService indexService) {
957 _indexService = indexService;
961 * Get the scenarioDAO.
963 * @return the scenarioDAO
965 public ScenarioDAO getScenarioDAO() {
970 * Set the scenarioDAO.
973 * the scenarioDAO to set
975 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
976 _scenarioDAO = scenarioDAO;
982 * @return the studyDAO
984 public StudyDAO getStudyDAO() {
992 * the studyDAO to set
994 public void setStudyDAO(final StudyDAO studyDAO) {
995 _studyDAO = studyDAO;
999 * Get the knowledgeElementTypeService.
1001 * @return the knowledgeElementTypeService
1003 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
1004 return _knowledgeElementTypeService;
1008 * Set the knowledgeElementTypeService.
1010 * @param knowledgeElementTypeService
1011 * the knowledgeElementTypeService to set
1013 public void setKnowledgeElementTypeService(
1014 final KnowledgeElementTypeService knowledgeElementTypeService) {
1015 _knowledgeElementTypeService = knowledgeElementTypeService;
1019 * Get the studyService.
1021 * @return the studyService
1023 public StudyService getStudyService() {
1024 return _studyService;
1028 * Set the studyService.
1030 * @param studyService
1031 * the studyService to set
1033 public void setStudyService(final StudyService studyService) {
1034 _studyService = studyService;
1038 * Get the userService.
1040 * @return the userService
1042 public UserService getUserService() {
1043 return _userService;
1047 * Set the userService.
1049 * @param userService
1050 * the userService to set
1052 public void setUserService(final UserService userService) {
1053 _userService = userService;
1059 * @return the userDAO
1061 public UserDAO getUserDAO() {
1069 * the userDAO to set
1071 public void setUserDAO(final UserDAO userDAO) {
1076 * Get the knowledgeElementTypeDAO.
1078 * @return the knowledgeElementTypeDAO
1080 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
1081 return _knowledgeElementTypeDAO;
1085 * Set the knowledgeElementTypeDAO.
1087 * @param knowledgeElementTypeDAO
1088 * the knowledgeElementTypeDAO to set
1090 public void setKnowledgeElementTypeDAO(
1091 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
1092 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
1096 * Get the simulationContextService.
1098 * @return the simulationContextService
1100 public SimulationContextService getSimulationContextService() {
1101 return _simulationContextService;
1105 * Set the simulationContextService.
1107 * @param simulationContextService
1108 * the simulationContextService to set
1110 public void setSimulationContextService(
1111 final SimulationContextService simulationContextService) {
1112 _simulationContextService = simulationContextService;
1116 * Get project settings.
1118 * @return Project settings service
1120 private ProjectSettingsService getProjectSettings() {
1121 return _projectSettings;
1125 * Set project settings service.
1127 * @param projectSettingsService
1128 * project settings service
1130 public void setProjectSettings(
1131 final ProjectSettingsService projectSettingsService) {
1132 _projectSettings = projectSettingsService;
1136 * Get the documentTypeService.
1138 * @return the documentTypeService
1140 public DocumentTypeService getDocumentTypeService() {
1141 return _documentTypeService;
1145 * Set the documentTypeService.
1147 * @param documentTypeService
1148 * the documentTypeService to set
1150 public void setDocumentTypeService(
1151 final DocumentTypeService documentTypeService) {
1152 _documentTypeService = documentTypeService;
1158 * @return the roleDAO
1160 public RoleDAO getRoleDAO() {
1168 * the roleDAO to set
1170 public void setRoleDAO(final RoleDAO roleDAO) {