Salome HOME
Fix for generating a description for version relation during checkin.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / ScenarioServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   06.10.2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package org.splat.service;
11
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;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.hibernate.criterion.DetachedCriteria;
23 import org.hibernate.criterion.Order;
24 import org.hibernate.criterion.Projections;
25 import org.hibernate.criterion.Restrictions;
26 import org.hibernate.transform.Transformers;
27 import org.splat.common.properties.MessageKeyEnum;
28 import org.splat.dal.bo.kernel.Relation;
29 import org.splat.dal.bo.kernel.Role;
30 import org.splat.dal.bo.kernel.User;
31 import org.splat.dal.bo.som.ConvertsRelation;
32 import org.splat.dal.bo.som.Document;
33 import org.splat.dal.bo.som.DocumentType;
34 import org.splat.dal.bo.som.File;
35 import org.splat.dal.bo.som.KnowledgeElement;
36 import org.splat.dal.bo.som.KnowledgeElementType;
37 import org.splat.dal.bo.som.ProgressState;
38 import org.splat.dal.bo.som.ProjectElement;
39 import org.splat.dal.bo.som.Publication;
40 import org.splat.dal.bo.som.Scenario;
41 import org.splat.dal.bo.som.SimulationContext;
42 import org.splat.dal.bo.som.SimulationContextType;
43 import org.splat.dal.bo.som.Study;
44 import org.splat.dal.bo.som.UsedByRelation;
45 import org.splat.dal.bo.som.UsesRelation;
46 import org.splat.dal.bo.som.ValidationCycle;
47 import org.splat.dal.bo.som.Document.Properties;
48 import org.splat.dal.dao.kernel.RoleDAO;
49 import org.splat.dal.dao.kernel.UserDAO;
50 import org.splat.dal.dao.som.KnowledgeElementDAO;
51 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
52 import org.splat.dal.dao.som.ScenarioDAO;
53 import org.splat.dal.dao.som.StudyDAO;
54 import org.splat.dal.dao.som.ValidationCycleDAO;
55 import org.splat.exception.InvalidParameterException;
56 import org.splat.i18n.I18nUtils;
57 import org.splat.kernel.InvalidPropertyException;
58 import org.splat.kernel.MismatchException;
59 import org.splat.kernel.MissedPropertyException;
60 import org.splat.kernel.MultiplyDefinedException;
61 import org.splat.kernel.NotApplicableException;
62 import org.splat.log.AppLogger;
63 import org.splat.service.dto.DocumentDTO;
64 import org.splat.service.dto.FileDTO;
65 import org.splat.service.dto.ScenarioDTO;
66 import org.splat.service.dto.StepDTO;
67 import org.splat.service.technical.IndexService;
68 import org.splat.service.technical.ProjectSettingsService;
69 import org.splat.service.technical.RepositoryService;
70 import org.splat.service.technical.StepsConfigService;
71 import org.splat.som.Step;
72 import org.splat.util.BeanHelper;
73 import org.splat.util.IOUtils;
74 import org.springframework.transaction.annotation.Transactional;
75
76 /**
77  * Scenario service implementation.
78  * 
79  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
80  */
81 public class ScenarioServiceImpl implements ScenarioService {
82
83         /**
84          * The logger for the service.
85          */
86         public final static AppLogger LOG = AppLogger
87                         .getLogger(ScenarioServiceImpl.class);
88
89         /**
90          * " to " literal.
91          */
92         private static final String TO = " to ";
93         /**
94          * Injected index service.
95          */
96         private IndexService _indexService;
97         /**
98          * Injected step service.
99          */
100         private StepService _stepService;
101         /**
102          * Injected study service.
103          */
104         private StudyService _studyService;
105         /**
106          * Injected publication service.
107          */
108         private PublicationService _publicationService;
109         /**
110          * Injected project element service.
111          */
112         private ProjectElementService _projectElementService;
113         /**
114          * Injected knowledge element DAO.
115          */
116         private KnowledgeElementDAO _knowledgeElementDAO;
117         /**
118          * Injected scenario DAO.
119          */
120         private ScenarioDAO _scenarioDAO;
121
122         /**
123          * Injected study DAO.
124          */
125         private StudyDAO _studyDAO;
126
127         /**
128          * Injected knowledge element service.
129          */
130         private KnowledgeElementTypeService _knowledgeElementTypeService;
131
132         /**
133          * Injected user service.
134          */
135         private UserService _userService;
136
137         /**
138          * Injected user DAO.
139          */
140         private UserDAO _userDAO;
141
142         /**
143          * Injected role DAO.
144          */
145         private RoleDAO _roleDAO;
146
147         /**
148          * Injected knowledge element type DAO.
149          */
150         private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
151
152         /**
153          * Injected simulation context service.
154          */
155         private SimulationContextService _simulationContextService;
156
157         /**
158          * Injected simulation context type service.
159          */
160         private SimulationContextTypeService _simulationContextTypeService;
161
162         /**
163          * Injected project service.
164          */
165         private ProjectSettingsService _projectSettings;
166
167         /**
168          * Injected document type service.
169          */
170         private DocumentTypeService _documentTypeService;
171
172         /**
173          * Injected validation cycle DAO.
174          */
175         private ValidationCycleDAO _validationCycleDAO;
176
177         /**
178          * Injected project settings service.
179          */
180         private StepsConfigService _stepsConfigService;
181
182         /**
183          * Injected repository service.
184          */
185         private RepositoryService _repositoryService;
186
187         /**
188          * Get the projectElementService.
189          * 
190          * @return the projectElementService
191          */
192         public ProjectElementService getProjectElementService() {
193                 return _projectElementService;
194         }
195
196         /**
197          * Set the projectElementService.
198          * 
199          * @param projectElementService
200          *            the projectElementService to set
201          */
202         public void setProjectElementService(
203                         final ProjectElementService projectElementService) {
204                 _projectElementService = projectElementService;
205         }
206
207         /**
208          * Get the publicationService.
209          * 
210          * @return the publicationService
211          */
212         public PublicationService getPublicationService() {
213                 return _publicationService;
214         }
215
216         /**
217          * Set the publicationService.
218          * 
219          * @param publicationService
220          *            the publicationService to set
221          */
222         public void setPublicationService(
223                         final PublicationService publicationService) {
224                 _publicationService = publicationService;
225         }
226
227         /**
228          * Get the stepService.
229          * 
230          * @return the stepService
231          */
232         public StepService getStepService() {
233                 return _stepService;
234         }
235
236         /**
237          * Set the stepService.
238          * 
239          * @param stepService
240          *            the stepService to set
241          */
242         public void setStepService(final StepService stepService) {
243                 _stepService = stepService;
244         }
245
246         /**
247          * {@inheritDoc}
248          * 
249          * @see org.splat.service.ScenarioService#getStudyScenarios(java.lang.Long)
250          */
251         @Override
252         @Transactional(readOnly = true)
253         public List<ScenarioDTO> getStudyScenarios(final Long studyId) {
254                 DetachedCriteria query = DetachedCriteria
255                                 .forClass(Scenario.class, "scen")
256                                 .add(Restrictions.eq("owner.rid", studyId))
257                                 .setProjection(
258                                                 Projections.projectionList().add(
259                                                                 Projections.property("scen.title"), "title")
260                                                                 .add(Projections.property("scen.rid"), "index"))
261                                 .setResultTransformer(
262                                                 Transformers.aliasToBean(ScenarioDTO.class));
263                 return getScenarioDAO().getFilteredDTOList(query);
264         }
265
266         /**
267          * {@inheritDoc}
268          * 
269          * @see org.splat.service.ScenarioService#copyStudyContent(long, long, int, long)
270          */
271         @Override
272         @Transactional
273         public void copyStudyContent(final long fromStudyId, final long fromScenId,
274                         final int finalStepNum, final long toStudyId)
275                         throws InvalidParameterException, MissedPropertyException,
276                         InvalidPropertyException, MultiplyDefinedException,
277                         NotApplicableException, IOException {
278                 Study fromStudy = getStudyService().selectStudy(fromStudyId);
279                 if (fromStudy == null) {
280                         throw new InvalidParameterException(MessageKeyEnum.STD_000002
281                                         .toString(), String.valueOf(fromStudyId));
282                 }
283                 Scenario fromScen = null;
284                 for (Scenario scen : fromStudy.getScenariiList()) {
285                         if (scen.getIndex() == fromScenId) {
286                                 fromScen = scen;
287                                 break;
288                         }
289                 }
290
291                 Study toStudy = getStudyService().selectStudy(toStudyId);
292                 if (toStudy == null) {
293                         throw new InvalidParameterException(MessageKeyEnum.STD_000002
294                                         .toString(), String.valueOf(toStudy));
295                 }
296
297                 // Check if the step is applied to a scenario and scenario is defined
298                 if (fromScen == null
299                                 && getStepsConfigService().stepInvolves(finalStepNum,
300                                                 Scenario.class)) {
301                         throw new InvalidParameterException(MessageKeyEnum.SCN_000006
302                                         .toString(), String.valueOf(fromScenId));
303                 }
304
305                 // Copy validation cycles
306                 copyValidationCycles(fromStudy, toStudy);
307
308                 // Copy content of the study up to the given step
309                 Map<Publication, Publication> oldToNewPub = new HashMap<Publication, Publication>();
310                 copyDocs(fromStudy, toStudy, finalStepNum, oldToNewPub);
311                 if (fromScen != null) {
312                         copyDocs(fromScen, toStudy.getScenariiList().get(0), finalStepNum,
313                                         oldToNewPub);
314                 }
315                 copyDependencies(fromStudy, finalStepNum, oldToNewPub);
316                 if (fromScen != null) {
317                         copyDependencies(fromScen, finalStepNum, oldToNewPub);
318                 }
319         }
320
321         /**
322          * Copy validation cycles from study to study.
323          * 
324          * @param fromStudy
325          *            the source study
326          * @param toStudy
327          *            the destination study
328          */
329         private void copyValidationCycles(final Study fromStudy, final Study toStudy) {
330                 for (ValidationCycle fromCycle : fromStudy.getValidationCycles()
331                                 .values()) {
332                         if (fromCycle.isAssigned()) {
333                                 ValidationCycle cycle = fromCycle.clone(toStudy);
334                                 getValidationCycleDAO().create(cycle);
335                                 toStudy.addRelation(cycle.getContext());
336                                 toStudy.getValidationCycles().put(
337                                                 cycle.getDocumentType().getName(), cycle); // Replaces the cycle if exists as default,
338                         }
339                 }
340         }
341
342         /**
343          * Copy dependencies between documents from the given project element up to <BR>
344          * the given step according to the given map of old publications to new publications.
345          * 
346          * @param from
347          *            the source project element
348          * @param finalStepNum
349          *            the final step for copy processing
350          * @param oldToNewPub
351          *            the old to new publications map
352          */
353         private void copyDependencies(final ProjectElement from,
354                         final int finalStepNum,
355                         final Map<Publication, Publication> oldToNewPub) {
356                 // Copy dependencies between copied documents
357                 for (Publication pub : from.getDocums()) {
358                         // If the document in the step before the final one
359                         if (pub.value().getStep() <= finalStepNum) {
360                                 Publication newPub = oldToNewPub.get(pub);
361                                 for (Publication used : pub.getRelations(UsesRelation.class)) {
362                                         newPub.addDependency(oldToNewPub.get(used));
363                                 }
364                         }
365                 }
366         }
367
368         /**
369          * Copy documents with dependencies up to the given step.
370          * 
371          * @param from
372          *            the source project element
373          * @param to
374          *            the destination project element
375          * @param finalStepNum
376          *            the final step for copy process
377          * @param oldToNewPub2
378          * @throws MissedPropertyException
379          *             if document creation is failed
380          * @throws InvalidPropertyException
381          *             if document creation is failed
382          * @throws MultiplyDefinedException
383          *             if document creation is failed
384          * @throws IOException
385          *             if document file creation is failed
386          * @throws NotApplicableException
387          *             if document state is not applicable
388          * @param oldToNewPub
389          *            the old to new publications map
390          * 
391          */
392         private void copyDocs(final ProjectElement from, final ProjectElement to,
393                         final int finalStepNum,
394                         final Map<Publication, Publication> oldToNewPub)
395                         throws MissedPropertyException, InvalidPropertyException,
396                         MultiplyDefinedException, NotApplicableException, IOException {
397                 Map<Integer, Step> steps = getProjectElementService().getStepsMap(to);
398                 // Copy publications without old versions and relations to not copied steps documents
399                 for (Publication pub : from.getDocums()) {
400                         // If the document in the step before the final one
401                         if (pub.value().getStep() <= finalStepNum) {
402                                 // Copy the document
403                                 oldToNewPub.put(pub, createDoc(pub.value(), steps.get(pub
404                                                 .value().getStep())));
405                         }
406                 }
407         }
408
409         /**
410          * Create a copy of the given document and publish it in the given step.
411          * 
412          * @param fromDoc
413          *            the source document
414          * @param step
415          *            the destination step
416          * @return the created publication
417          * @throws MissedPropertyException
418          *             if document creation is failed
419          * @throws InvalidPropertyException
420          *             if document creation is failed
421          * @throws MultiplyDefinedException
422          *             if document creation is failed
423          * @throws IOException
424          *             if document file creation is failed
425          * @throws NotApplicableException
426          *             if document state is not applicable
427          */
428         private Publication createDoc(final Document fromDoc, final Step step)
429                         throws MissedPropertyException, InvalidPropertyException,
430                         MultiplyDefinedException, IOException, NotApplicableException {
431
432                 java.io.File srcFile = fromDoc.getSourceFile().asFile();
433                 // Creation of the document
434                 Document.Properties dprop = new Document.Properties().setName(
435                                 fromDoc.getTitle()).setType(fromDoc.getType()).setFormat(
436                                 fromDoc.getFormat()).setAuthor(fromDoc.getAuthor());
437
438                 java.io.File tmpDir = getRepositoryService().getDownloadDirectory(
439                                 step.getOwnerStudy().getAuthor());
440
441                 // Remove local file index prefix to get original filename.
442                 java.io.File upfile = new java.io.File(tmpDir.getPath()
443                                 + "/"
444                                 + srcFile.getName().substring(
445                                                 srcFile.getName().indexOf('_') + 1));
446                 // Copy the source file into the temporary folder with original filename.
447                 copyFile(srcFile, upfile);
448
449                 dprop.setLocalPath(upfile.getPath());
450                 Publication addoc = getStepService().createDocument(step, dprop);
451
452                 // Move the temporary file into the repository
453                 moveFile(upfile, addoc.getSourceFile().asFile());
454
455                 getPublicationService().saveAs(addoc, fromDoc.getProgressState());
456
457                 // Copy attached files
458                 for (Relation rel : fromDoc.getRelations(ConvertsRelation.class)) {
459                         File attach = ((ConvertsRelation) rel).getTo();
460                         ConvertsRelation export = getPublicationService().attach(addoc,
461                                         attach.getFormat());
462                         // Copy the source document attachment file to the new study vault
463                         copyFile(attach.asFile(), export.getTo().asFile());
464                 }
465                 return addoc;
466         }
467
468         /**
469          * Copy a file. Print info message.
470          * 
471          * @param upfile
472          *            the source file.
473          * @param file
474          *            the target file
475          * @throws IOException
476          *             if failed
477          */
478         private void copyFile(final java.io.File upfile, final java.io.File file)
479                         throws IOException {
480                 if (LOG.isInfoEnabled()) {
481                         LOG.info("Copy " + upfile.getAbsolutePath() + TO + file.getPath());
482                 }
483                 IOUtils.copy(upfile, file);
484         }
485
486         /**
487          * Copy a file. Print info message.
488          * 
489          * @param upfile
490          *            the source file.
491          * @param file
492          *            the target file
493          * @return true if renamed otherwise return false
494          */
495         private boolean moveFile(final java.io.File upfile, final java.io.File file) {
496                 if (LOG.isInfoEnabled()) {
497                         LOG.info("Move " + upfile.getAbsolutePath() + TO + file.getPath());
498                 }
499                 return upfile.renameTo(file);
500         }
501
502         /**
503          * {@inheritDoc}
504          * 
505          * @see org.splat.service.ScenarioService#getScenarioInfo(long)
506          */
507         @Transactional(readOnly = true)
508         public List<StepDTO> getScenarioInfo(final long scenarioId) {
509                 List<StepDTO> res = new ArrayList<StepDTO>();
510                 // Get the scenario from the database by id
511                 Scenario scen = getScenarioDAO().get(scenarioId);
512                 if (LOG.isDebugEnabled()) {
513                         LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
514                                         + scen.getDocums().size());
515                 }
516                 // Get activities of the scenario
517                 Step[] steps = getProjectElementService().getSteps(scen);
518                 StepDTO stepDTO;
519                 DocumentDTO docDTO;
520                 String docType, fileFormat;
521                 String processing;
522                 boolean doImport;
523                 // For each activity create a step DTO and add it to the result list
524                 for (Step step : steps) {
525                         stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
526                         res.add(stepDTO);
527                         if (LOG.isDebugEnabled()) {
528                                 LOG.debug("Step[" + stepDTO.getNumber()
529                                                 + "]: Number of documents: "
530                                                 + step.getDocuments().size());
531                         }
532                         // For each publication of the activity create a document DTO.
533                         // Each file is considered as a source file.
534                         for (Publication tag : step.getDocuments()) {
535                                 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
536                                                 .getTitle());
537                                 char aState = tag.getIsnew();
538                                 docType = tag.value().getType().getName();
539                                 // For each file of the document create a file DTO
540                                 // Process source file of the document
541                                 fileFormat = tag.value().getFile().getFormat();
542                                 doImport = getProjectSettings().doImport(docType, fileFormat);
543                                 if (doImport && (!tag.isOutdated())) {
544                                         processing = "file-import";
545                                 } else {
546                                         processing = "file-download";
547                                 }
548                                 File aFile = tag.value().getFile();
549                                 docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
550                                                 aState, processing, false);
551                                 // Process all exported files
552                                 for (Relation rel : tag.value().getRelations(
553                                                 ConvertsRelation.class)) {
554                                         aFile = ((ConvertsRelation) rel).getTo();
555                                         fileFormat = aFile.getFormat();
556                                         doImport = getProjectSettings().doImport(docType,
557                                                         fileFormat);
558                                         if (doImport && (!tag.isOutdated())) {
559                                                 processing = "file-import";
560                                         } else {
561                                                 processing = "file-download";
562                                         }
563                                         docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
564                                                         aState, processing, false);
565                                 }
566                         }
567                 }
568                 return res;
569         }
570
571         /**
572          * {@inheritDoc}
573          * 
574          * @see org.splat.service.ScenarioService#createStudy(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
575          */
576         @Transactional
577         public long createStudy(final String username, final String title,
578                         final String productName, final String description)
579                         throws InvalidPropertyException, MissedPropertyException,
580                         MultiplyDefinedException {
581                 long id = 0;
582
583                 // Find the author
584                 User author = getUserService().selectUser(username);
585                 if (author == null) {
586                         // User is not found
587                         throw new InvalidPropertyException(MessageKeyEnum.USR_000001
588                                         .toString(), username);
589                 }
590
591                 // Set the study properties
592                 Study.Properties sprop = new Study.Properties();
593                 sprop.setTitle(title).setManager(author);
594                 sprop.setDescription(description);
595
596                 // Find the product simulation context
597                 SimulationContextType productContextType = getSimulationContextService()
598                                 .selectType("product");
599                 SimulationContext.Properties cprop = new SimulationContext.Properties();
600                 cprop.setType(productContextType).setValue(productName);
601                 SimulationContext productCtx = getSimulationContextService()
602                                 .selectSimulationContext(productContextType, productName);
603                 if (productCtx != null) {
604                         cprop.setIndex(productCtx.getIndex());
605                 }
606
607                 // Set a first scenario properties
608                 Scenario.Properties oprop = new Scenario.Properties();
609                 oprop.setTitle(I18nUtils.getMessageLocaleDefault("label.scenario")
610                                 + " 1");
611
612                 Study study = createStudy(sprop, oprop, cprop);
613                 id = study.getIndex();
614
615                 return id;
616         }
617
618         /**
619          * Create a new study with one scenario and "product" simulation context.
620          * 
621          * @param sprop
622          *            the study properties
623          * @param oprop
624          *            the scenario properties
625          * @param cprop
626          *            the "product" simulation context properties
627          * @return the created study
628          * @throws MissedPropertyException
629          *             if a mandatory property is missed
630          * @throws InvalidPropertyException
631          *             if a property is invalid
632          * @throws MultiplyDefinedException
633          *             if some property occurs several times
634          */
635         @Transactional
636         public Study createStudy(final Study.Properties sprop,
637                         final Scenario.Properties oprop,
638                         final SimulationContext.Properties cprop)
639                         throws MissedPropertyException, InvalidPropertyException,
640                         MultiplyDefinedException {
641                 Study study = getStudyService().createStudy(sprop);
642                 addScenario(study, oprop);
643                 if (cprop.getIndex() == 0) { // Input of new project context
644                         cprop.setType(getSimulationContextService().selectType("product"))
645                                         .setValue(cprop.getValue());
646                         getStudyService().addProjectContext(study, cprop);
647                 } else { // Selection of existing project context
648                         SimulationContext context = getSimulationContextService()
649                                         .selectSimulationContext(cprop.getIndex());
650                         getStudyService().addProjectContext(study, context);
651                 }
652                 return study;
653         }
654
655         /**
656          * {@inheritDoc}
657          * 
658          * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
659          */
660         @Transactional
661         public void assignStudyContext(final Long studyId, final String ctxType,
662                         final String ctxValue) throws MissedPropertyException,
663                         InvalidPropertyException, MultiplyDefinedException {
664                 // Find the study by the given id
665                 Study study = getStudyDAO().get(studyId);
666                 if (study == null) {
667                         throw new InvalidPropertyException(MessageKeyEnum.STD_000002
668                                         .toString(), studyId);
669                 }
670                 // Find the context type by its name
671                 SimulationContextType celt = getSimulationContextService().selectType(
672                                 ctxType);
673                 if (celt == null) {
674                         // Creation of a new context type
675                         celt = getSimulationContextTypeService().createType(ctxType,
676                                         getProjectElementService().getFirstStep(study).getStep());
677                 }
678                 // Find the given context value of the given type
679                 SimulationContext context = getSimulationContextService()
680                                 .selectSimulationContext(celt, ctxValue);
681                 if (context == null) { // Input of a new project context
682                         SimulationContext.Properties cprop = new SimulationContext.Properties();
683                         cprop.setType(celt).setValue(ctxValue);
684                         getStudyService().addProjectContext(study, cprop);
685                 } else { // Selection of existing project context
686                         getStudyService().addProjectContext(study, context);
687                 }
688         }
689
690         /**
691          * {@inheritDoc}
692          * 
693          * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
694          *      org.splat.dal.bo.som.KnowledgeElement.Properties)
695          */
696         @Transactional
697         public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
698                         final KnowledgeElement.Properties kprop)
699                         throws MissedPropertyException, InvalidPropertyException,
700                         MultiplyDefinedException {
701                 KnowledgeElement kelm = null;
702                 // try {
703                 long aScenarioId = aScenarioDTO.getIndex();
704                 if (LOG.isDebugEnabled()) {
705                         LOG
706                                         .debug("Add a knowledge element to the scenario #"
707                                                         + aScenarioId);
708                 }
709                 // Get the persistent scenario.
710                 Scenario aScenario = getScenarioDAO().get(aScenarioId);
711                 // Get persistent objects for creating a new knowledge.
712                 // TODO: Actions must use DTO instead of persistent objects.
713                 getUserDAO().merge(kprop.getAuthor());
714                 getKnowledgeElementTypeDAO().merge(kprop.getType());
715                 // Create a transient knowledge element related to the given scenario.
716                 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
717                 // Save the new knowledge in the database.
718                 getKnowledgeElementDAO().create(kelm);
719                 // Update scenario transient data.
720                 if (kelm.getType().equals("usecase")) {
721                         aScenarioDTO.setUcase(kelm);
722                 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
723                         aScenarioDTO.getKnowledgeElementsList().add(kelm);
724                 }
725
726                 // Load the workflow for the parent study to take into account
727                 // all study actors durng reindexing.
728                 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
729
730                 // // Update the lucene index of knowledge elements.
731                 // getIndexService().add(kelm);
732                 if (LOG.isDebugEnabled()) {
733                         LOG.debug("A knowledge element #" + kelm.getIndex()
734                                         + " is added to the scenario #" + aScenario.getIndex());
735                 }
736                 // } catch (IOException error) {
737                 // LOG.error("Unable to index the knowedge element '"
738                 // + kelm.getIndex() + "', reason:", error);
739                 // kelm = null;
740                 // }
741
742                 return kelm;
743         }
744
745         /**
746          * {@inheritDoc}
747          * 
748          * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
749          */
750         @Transactional
751         public void checkin(final long scenId, final long userId,
752                         final List<StepDTO> scInfo) throws InvalidPropertyException,
753                         MissedPropertyException, MultiplyDefinedException,
754                         MismatchException, IOException, NotApplicableException {
755                 // Get the scenario from the database by id
756                 Scenario aScenario = getScenarioDAO().get(scenId);
757                 // Get the user who perform this check-in operation
758                 User aUser = getUserService().selectUser(userId);
759                 // Get activities of the scenario
760                 Step[] steps = getProjectElementService().getSteps(aScenario);
761                 // Find result document types
762                 List<DocumentType> resTypes = getDocumentTypeService()
763                                 .selectResultTypes();
764
765                 // Keep newly created documents to create uses relations to results of a previous step.
766                 // For each processed existing document keep its new version
767                 Map<Document, Document> newVersion = new HashMap<Document, Document>();
768                 // Created publications of new created versions of existing documents
769                 List<Publication> newVers = new ArrayList<Publication>();
770                 // The list of publications of new created documents not existing before the checkin
771                 List<Publication> newDocs = new ArrayList<Publication>();
772                 // For each step DTO
773                 DocumentType resType;
774                 Date aDate = new Date(); // The timestamp of the checkin operation
775                 for (StepDTO stepDTO : scInfo) {
776                         if (LOG.isDebugEnabled()) {
777                                 LOG.debug("Checkin the step:\n" + stepDTO);
778                         }
779                         // Find a result document type of the step
780                         int i = 0;
781                         resType = null;
782                         do {
783                                 if (resTypes.get(i).isResultOf(
784                                                 getProjectSettings().getStep(stepDTO.getNumber()))) {
785                                         resType = resTypes.get(i);
786                                 }
787                                 i++;
788                         } while ((resType == null) && (i < resTypes.size()));
789
790                         // Find the appropriate scenario step
791                         Step step = findStep(stepDTO, steps);
792
793                         // Process each document of the step
794                         for (DocumentDTO doc : stepDTO.getDocs()) {
795                                 checkinDoc(step, doc, aUser, resType, aDate, newVersion,
796                                                 newVers, newDocs);
797                         }
798                 }
799
800                 // Set uses/used relations
801                 updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
802
803                 // Mark the scenario as checked in
804                 checkin(aScenario);
805         }
806
807         /**
808          * Updated uses/used relations after checkin operation:<BR>
809          * <ul>
810          * <li>For each new version copy uses relations from the previous version.</li>
811          * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
812          * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
813          * </ul>
814          * 
815          * @param aScenario
816          *            the checked in scenario
817          * @param newVersion
818          *            the mapping of documents existed before the checkin to their new created versions
819          * @param newVers
820          *            the list of publications of new created versions of documents existed before the checkin
821          * @param newDocs
822          *            the list of publications of new created documents not existed before the checkin
823          */
824         private void updateRelationsAfterCheckin(final Scenario aScenario,
825                         final Map<Document, Document> newVersion,
826                         final List<Publication> newVers, final List<Publication> newDocs) {
827                 // For each new version copy uses relations from the previous version.
828                 for (Publication newVer : newVers) {
829                         // For each Uses relation of the previous version
830                         Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
831                         if (LOG.isDebugEnabled()) {
832                                 LOG.debug("Previous version for publication #"
833                                                 + newVer.getIndex() + " is found: " + prevDoc);
834                         }
835                         List<Relation> usesRelations = prevDoc
836                                         .getRelations(UsesRelation.class);
837                         for (Relation rel : usesRelations) {
838                                 // If used document has been also versioned then refer to its new version.
839                                 Document usedDoc = ((UsesRelation) rel).getTo();
840                                 if (newVersion.containsKey(usedDoc)) {
841                                         usedDoc = newVersion.get(usedDoc);
842                                 }
843                                 // Build the appropriate relation for the new version.
844                                 newVer.addDependency(usedDoc);
845                         }
846                         // Outdate documents which depend from the previous version and
847                         // were not checked in during this operation.
848                         // 1. Get all usedBy relations of the previous document version
849                         for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
850                                 Document using = ((UsedByRelation) rel).getTo();
851                                 // Check that not checked in dependent documents became outdated
852                                 Publication usingPub = aScenario.getPublication(using);
853                                 if (usingPub != null) { // if the document using the old version is still published
854                                         usingPub.setIsnew('O');
855                                 }
856                         }
857                 }
858
859                 // For each new document create uses relation to the last versions of
860                 // results of the previous step.
861                 for (Publication newPub : newDocs) {
862                         // Find used document type according to the configuration.
863                         Set<DocumentType> usedTypes = newPub.value().getType()
864                                         .getDefaultUses();
865                         // Find documents of used type in the previous study step.
866                         for (Publication pub : aScenario.getDocums()) {
867                                 if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
868                                                 && (!pub.isOutdated())
869                                                 && usedTypes.contains(pub.value().getType())) {
870                                         // Create uses relation from the new document
871                                         // to the found document in the previous step.
872                                         newPub.addDependency(pub);
873                                 }
874                         }
875                 }
876         }
877
878         /**
879          * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
880          * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
881          * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
882          * 
883          * @param step
884          *            the destination scenario step
885          * @param doc
886          *            the DTO of the document to checkin
887          * @param aUser
888          *            the user who performs checkin
889          * @param resType
890          *            the result document type of the given step
891          * @param aDate
892          *            timestamp of the checkin operation
893          * @param newVersion
894          *            the mapping of existing documents to their new created versions
895          * @param newVers
896          *            the list of publications of new created versions of existing documents
897          * @param newDocs
898          *            the list of publications of new created documents not existing before the checkin
899          * @throws InvalidPropertyException
900          *             if the scenario hasn't some of given steps or documents
901          * @throws IOException
902          *             if a file can't be moved into the vault
903          * @throws MismatchException
904          *             if version creation in some of steps is failed
905          * @throws MissedPropertyException
906          *             if some mandatory property is missed when new document or new document version is created
907          * @throws MultiplyDefinedException
908          *             if some property is defined several times when new document or new document version is created
909          * @throws NotApplicableException
910          *             if failed saving of a new publication with a given state
911          */
912         private void checkinDoc(final Step step, final DocumentDTO doc,
913                         final User aUser, final DocumentType resType, final Date aDate,
914                         final Map<Document, Document> newVersion,
915                         final List<Publication> newVers, final List<Publication> newDocs)
916                         throws InvalidPropertyException, MismatchException,
917                         MissedPropertyException, MultiplyDefinedException, IOException,
918                         NotApplicableException {
919                 if (doc.getFiles().size() > 0) {
920                         Document.Properties dprop = new Document.Properties();
921                         // NOTE: Process only the first attached file for each document
922                         FileDTO file = doc.getFiles().get(0);
923                         dprop.setLocalPath(file.getPath());
924
925                         // Get document title as the file name
926                         java.io.File upfile = new java.io.File(file.getPath());
927                         String fileFormat = upfile.getName().substring(
928                                         upfile.getName().lastIndexOf('.') + 1);
929
930                         // Attach the file via ConvertsRelation, create a new document or
931                         // create a new version of the document
932                         dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
933                         String authorName = I18nUtils.getMessageLocaleDefault(aUser
934                                         .getDisplayName());
935                         String summary = I18nUtils.getMessageLocaleDefault(
936                                         MessageKeyEnum.DCT_000005.toString(), authorName);
937                         dprop.setDescription(summary);
938
939                         if (doc.getId() > 0) {
940                                 checkinExistingDoc(step, doc, dprop, fileFormat, upfile,
941                                                 newVersion, newVers);
942                         } else {
943
944                                 // Otherwise create a new document of the result type
945                                 // If result type is not found try to get type by file extension
946                                 if (resType == null) {
947                                         dprop.setType(getProjectSettings().getDefaultDocumentType(
948                                                         step.getStep(), fileFormat));
949                                 } else {
950                                         dprop.setType(resType);
951                                 }
952                                 // New document title generation as <document type name>_N
953                                 String docname = dprop.getType().getName();
954                                 int i = 1;
955                                 for (Publication scenPub : step.getOwner().getDocums()) {
956                                         if (scenPub.value().getTitle().startsWith(docname)) {
957                                                 i++;
958                                         }
959                                 }
960                                 docname += "_" + i; // The generated new document title
961
962                                 dprop.setName(docname);
963                                 Publication newPub = getStepService().createDocument(step,
964                                                 dprop);
965
966                                 // Remember the new document
967                                 newDocs.add(newPub);
968
969                                 saveFile(newPub, step, upfile);
970                         }
971                 }
972         }
973
974         /**
975          * Check in existing document.
976          * 
977          * @param step
978          *            study step to check in
979          * @param doc
980          *            document DTO to check in
981          * @param dprop
982          *            document properties
983          * @param fileFormat
984          *            checked in file format
985          * @param upfile
986          *            the file to check in
987          * @param newVersion
988          *            the map of created versions during this check in
989          * @param newVers
990          *            the list of new versions created during this check in
991          * @throws InvalidPropertyException
992          *             if publication of the document is not found in the step
993          * @throws MismatchException
994          *             if the found publication does not point to a document
995          * @throws IOException
996          *             if can not move the file into the vault
997          * @throws MultiplyDefinedException
998          *             thrown by versionDocument
999          * @throws MissedPropertyException
1000          *             thrown by versionDocument
1001          * @throws NotApplicableException
1002          *             if failed saving of a new publication with a given state
1003          */
1004         private void checkinExistingDoc(final Step step, final DocumentDTO doc,
1005                         final Properties dprop, final String fileFormat,
1006                         final java.io.File upfile,
1007                         final Map<Document, Document> newVersion,
1008                         final List<Publication> newVers) throws InvalidPropertyException,
1009                         MismatchException, MissedPropertyException,
1010                         MultiplyDefinedException, IOException, NotApplicableException {
1011                 // If the document already exists then
1012                 // Attach the file via ConvertsRelation if the extension of the
1013                 // new file differs from the old one.
1014                 // If file format (i.e. extension) is the same then create a new
1015                 // version of the document.
1016                 // Find the document publication
1017                 Publication pub = step.getDocument(doc.getId());
1018                 if (pub == null) {
1019                         throw new InvalidPropertyException(MessageKeyEnum.SCN_000002
1020                                         .toString(), doc.getId());
1021                 }
1022                 if (pub.value() == null) {
1023                         throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
1024                                         doc.getId());
1025                 }
1026                 if (LOG.isDebugEnabled()) {
1027                         LOG.debug("Old format: " + pub.value().getFormat()
1028                                         + " => New format: " + fileFormat);
1029                 }
1030                 // If formats are same then create a new document version
1031                 if (pub.value().getFormat() != null
1032                                 && pub.value().getFormat().equals(fileFormat)) {
1033                         Publication newPub = getStepService().versionDocument(step, pub,
1034                                         dprop);
1035                         if (LOG.isDebugEnabled()) {
1036                                 LOG.debug("Created document type: "
1037                                                 + newPub.value().getType().getName() + ", format: "
1038                                                 + newPub.value().getFormat());
1039                         }
1040                         // Remeber the link from the old document to the new document version
1041                         newVersion.put(pub.value(), newPub.value());
1042                         // Remember the new version publication
1043                         newVers.add(newPub);
1044
1045                         saveFile(newPub, step, upfile);
1046
1047                 } else { // If formats are different then attach the new file via ConvertsRelation
1048                         File attach = pub.value().getAttachedFile(fileFormat);
1049                         if (attach == null) {
1050                                 // If there is no attachment with this extension then attach the new one
1051                                 ConvertsRelation export = getPublicationService().attach(pub,
1052                                                 fileFormat);
1053                                 moveFile(upfile, export.getTo().asFile());
1054                         } else {
1055                                 // If an attachment with this extension already exists then
1056                                 // replace it by the new one
1057                                 moveFile(upfile, attach.asFile());
1058                                 // Update attached file modification date
1059                                 attach.setDate(new Date());
1060                         }
1061                 }
1062         }
1063
1064         /**
1065          * Save the file in the vault and create its publication in the step.
1066          * 
1067          * @param newPub
1068          *            the new publication to save
1069          * @param step
1070          *            the study step to publish the document
1071          * @param upfile
1072          *            the downloaded file
1073          * @throws IOException
1074          *             if a file can't be moved into the vault
1075          * @throws NotApplicableException
1076          *             if failed saving of a new publication with a given state
1077          */
1078         private void saveFile(final Publication newPub, final Step step,
1079                         final java.io.File upfile) throws IOException,
1080                         NotApplicableException {
1081                 // Attach the file to the created document
1082                 java.io.File updir = newPub.getSourceFile().asFile();
1083                 if (updir.exists()) {
1084                         if (updir.delete()) {
1085                                 LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
1086                                                 .getAbsoluteFile(), step.getOwner().getIndex());
1087                         } else {
1088                                 throw new IOException(
1089                                                 "Can't delete the existing destination file to move file from "
1090                                                                 + upfile.getAbsolutePath() + TO
1091                                                                 + updir.getAbsolutePath());
1092                         }
1093                 }
1094                 if (moveFile(upfile, updir)) {
1095                         // Save the new publication in the scenario.
1096                         // The old publication is removed from the scenario here.
1097                         getPublicationService().saveAs(newPub, ProgressState.inWORK); // May throw FileNotFound if rename was not done
1098                 } else {
1099                         throw new IOException("Can't move file from "
1100                                         + upfile.getAbsolutePath() + TO + updir.getAbsolutePath());
1101                 }
1102         }
1103
1104         /**
1105          * Find appropriate step in the array of scenario steps according to the given step DTO.
1106          * 
1107          * @param stepDTO
1108          *            the stepDTO
1109          * @param steps
1110          *            scenario steps
1111          * @return appropriate scenario step
1112          * @throws InvalidPropertyException
1113          *             if appropriate step is not found
1114          */
1115         private Step findStep(final StepDTO stepDTO, final Step[] steps)
1116                         throws InvalidPropertyException {
1117                 int i = 0;
1118                 Step step = null;
1119                 do {
1120                         if (steps[i].getNumber() == stepDTO.getNumber()) {
1121                                 step = steps[i];
1122                         }
1123                         i++;
1124                 } while ((step == null) && (i < steps.length));
1125
1126                 if (step == null) {
1127                         throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
1128                                         .toString(), stepDTO.getNumber());
1129                 }
1130                 return step;
1131         }
1132
1133         /**
1134          * {@inheritDoc}
1135          * 
1136          * @see org.splat.service.ScenarioService#checkin(long)
1137          */
1138         @Transactional
1139         public void checkin(final long scenarioId) throws InvalidPropertyException {
1140                 Scenario aScenario = getScenarioDAO().get(scenarioId);
1141                 if (aScenario == null) {
1142                         // Scenario not found
1143                         throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
1144                                         .toString(), scenarioId);
1145                 }
1146                 checkin(aScenario);
1147         }
1148
1149         /**
1150          * Mark the scenario as checked in.
1151          * 
1152          * @param aScenario
1153          *            the scenario to check in.
1154          */
1155         private void checkin(final Scenario aScenario) {
1156                 aScenario.setUser(null);
1157                 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
1158                 // getScenarioDAO().update(aScenario);
1159         }
1160
1161         /**
1162          * {@inheritDoc}
1163          * 
1164          * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
1165          */
1166         public boolean checkout(final Scenario aScenario, final User user) {
1167                 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
1168                                 user);
1169                 if (res) {
1170                         aScenario.setUser(user);
1171                         aScenario.setLastModificationDate(Calendar.getInstance().getTime());
1172                         // RKV: getScenarioDAO().update(aScenario);
1173                 }
1174                 return res;
1175         }
1176
1177         /**
1178          * Mark the given scenario as checked out by the given user.
1179          * 
1180          * @param scenarioId
1181          *            the scenario id
1182          * @param userId
1183          *            the id of the user performing the check out
1184          * @throws InvalidPropertyException
1185          *             if the user or the scenario is not found in the database
1186          * @throws NotApplicableException
1187          *             if the given user can not check out the scenario
1188          */
1189         @Transactional
1190         public void checkout(final long scenarioId, final long userId)
1191                         throws InvalidPropertyException, NotApplicableException {
1192                 User aUser = getUserService().selectUser(userId);
1193                 if (aUser == null) {
1194                         // User not found
1195                         throw new InvalidPropertyException(MessageKeyEnum.USR_000001
1196                                         .toString(), userId);
1197                 }
1198                 Scenario aScenario = getScenarioDAO().get(scenarioId);
1199                 if (aScenario == null) {
1200                         // Scenario not found
1201                         throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
1202                                         .toString(), scenarioId);
1203                 }
1204                 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
1205                                 aUser);
1206                 if (res) {
1207                         if (aScenario.isCheckedout()
1208                                         && (!aScenario.getUser().getUsername().equals(
1209                                                         aUser.getUsername()))) {
1210                                 throw new NotApplicableException(MessageKeyEnum.SCN_000008
1211                                                 .toString(), scenarioId, aScenario.getUser()
1212                                                 .getUsername());
1213                         }
1214                         aScenario.setUser(aUser);
1215                         aScenario.setLastModificationDate(Calendar.getInstance().getTime());
1216                 } else {
1217                         // User doesn't participate in the scenario
1218                         throw new NotApplicableException(MessageKeyEnum.SCN_000007
1219                                         .toString(), aUser.getUsername(), scenarioId);
1220                 }
1221         }
1222
1223         /**
1224          * {@inheritDoc}
1225          * 
1226          * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
1227          */
1228         public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
1229                 Scenario base = (Scenario) lastep.getOwner();
1230                 Step[] from = getProjectElementService().getSteps(base);
1231                 Step[] to = getProjectElementService().getSteps(scenario);
1232                 for (int i = 0; i < from.length; i++) {
1233                         Step step = from[i];
1234                         if (step.getNumber() > lastep.getNumber()) {
1235                                 break;
1236                         }
1237
1238                         List<Publication> docs = step.getAllDocuments();
1239                         for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
1240                                 Publication doc = getPublicationService().copy(j.next(),
1241                                                 scenario); // Creation of a new reference to the document
1242                                 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
1243                                 getStepService().add(to[i], doc);
1244                         }
1245                         List<SimulationContext> ctex = step.getAllSimulationContexts();
1246                         for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
1247                                 getStepService().addSimulationContext(to[i], j.next());
1248                         }
1249                 }
1250         }
1251
1252         /**
1253          * {@inheritDoc}
1254          * 
1255          * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
1256          */
1257         public boolean isEmpty(final Scenario scenario) {
1258                 Step[] mystep = getProjectElementService().getSteps(scenario);
1259                 boolean isEmp = true;
1260                 for (int i = 0; i < mystep.length; i++) {
1261                         if (mystep[i].isStarted()) {
1262                                 isEmp = false;
1263                                 break;
1264                         }
1265                 }
1266                 return isEmp;
1267         }
1268
1269         /**
1270          * @param scenario
1271          * @return
1272          */
1273         public boolean isFinished(final Scenario scenario) {
1274                 Step[] mystep = getProjectElementService().getSteps(scenario);
1275                 boolean notempty = false; // If this is empty, this is not finished
1276                 for (int i = 0; i < mystep.length; i++) {
1277                         if (!mystep[i].isStarted()) {
1278                                 continue;
1279                         }
1280                         if (!mystep[i].isFinished()) {
1281                                 return false;
1282                         }
1283                         notempty = true;
1284                 }
1285                 return notempty;
1286         }
1287
1288         /**
1289          * {@inheritDoc}
1290          * 
1291          * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
1292          */
1293         @Transactional
1294         public Scenario addScenario(final Study aStudy,
1295                         final Scenario.Properties sprop) throws MissedPropertyException,
1296                         InvalidPropertyException, MultiplyDefinedException {
1297                 if (sprop.getManager() == null) {
1298                         sprop.setManager(aStudy.getAuthor());
1299                 }
1300
1301                 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
1302                 if (sprop.getBaseStep() != null) {
1303                         copyContentsUpTo(scenario, sprop.getBaseStep());
1304                 }
1305                 Scenario previous = sprop.getInsertAfter();
1306
1307                 if (previous == null) {
1308                         aStudy.getScenariiList().add(scenario);
1309                 } else {
1310                         aStudy.getScenariiList().add(
1311                                         aStudy.getScenariiList().indexOf(previous) + 1, scenario);
1312                 }
1313                 getStudyDAO().update(aStudy); // No need to update the Lucene index
1314                 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
1315                 if (sprop.getBaseStep() != null) {
1316                         // No need to update the Knowledge Element index as Knowledge Elements are not copied
1317                         getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
1318                 }
1319                 KnowledgeElementType ucase = getKnowledgeElementTypeService()
1320                                 .selectType("usecase");
1321                 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
1322                 // TODO: Get appropriate user by its role: UserService.getAdmin();
1323                 // User admin = getUserService().selectUser(1); // First user created when creating the database
1324                 Role adminRole = getRoleDAO().getFilteredList(
1325                                 Restrictions.like("role", "%sysadmin%")).get(0);
1326                 User admin = getUserDAO().getFilteredList(
1327                                 Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
1328
1329                 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
1330                                 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
1331                 // knowledges
1332                 addKnowledgeElement(scenario, kprop);
1333                 return scenario;
1334         }
1335
1336         /**
1337          * Remove a knowledge element from a scenario.
1338          * 
1339          * @param scenario
1340          *            the scenario
1341          * @param kelm
1342          *            the knowledge element to remove
1343          * @return true if removal succeeded
1344          */
1345         @Transactional
1346         public boolean removeKnowledgeElement(final Scenario scenario,
1347                         final KnowledgeElement kelm) {
1348                 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
1349                 boolean isOk = (torem != null);
1350                 if (isOk) {
1351                         isOk = scenario.getKnowledgeElements().remove(torem);
1352                         if (isOk) {
1353                                 getScenarioDAO().merge(scenario);
1354                                 // Update of my transient data
1355                                 // RKV: These transient data are not used indeed.
1356                                 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
1357                                 // RKV: kelm.getType().getIndex());
1358                                 // RKV: kelms.remove(torem);
1359                                 if (scenario.getKnowledgeElementsList() != null) {
1360                                         scenario.getKnowledgeElementsList().remove(torem);
1361                                 }
1362                                 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
1363                         }
1364                 }
1365                 return isOk;
1366         }
1367
1368         /**
1369          * 
1370          * {@inheritDoc}
1371          * 
1372          * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
1373          */
1374         @Transactional
1375         public void renameScenario(final Scenario scenario) {
1376                 getScenarioDAO().merge(scenario);
1377         }
1378
1379         /**
1380          * Get the knowledgeElementDAO.
1381          * 
1382          * @return the knowledgeElementDAO
1383          */
1384         public KnowledgeElementDAO getKnowledgeElementDAO() {
1385                 return _knowledgeElementDAO;
1386         }
1387
1388         /**
1389          * Set the knowledgeElementDAO.
1390          * 
1391          * @param knowledgeElementDAO
1392          *            the knowledgeElementDAO to set
1393          */
1394         public void setKnowledgeElementDAO(
1395                         final KnowledgeElementDAO knowledgeElementDAO) {
1396                 _knowledgeElementDAO = knowledgeElementDAO;
1397         }
1398
1399         /**
1400          * Get the indexService.
1401          * 
1402          * @return the indexService
1403          */
1404         public IndexService getIndexService() {
1405                 return _indexService;
1406         }
1407
1408         /**
1409          * Set the indexService.
1410          * 
1411          * @param indexService
1412          *            the indexService to set
1413          */
1414         public void setIndexService(final IndexService indexService) {
1415                 _indexService = indexService;
1416         }
1417
1418         /**
1419          * Get the scenarioDAO.
1420          * 
1421          * @return the scenarioDAO
1422          */
1423         public ScenarioDAO getScenarioDAO() {
1424                 return _scenarioDAO;
1425         }
1426
1427         /**
1428          * Set the scenarioDAO.
1429          * 
1430          * @param scenarioDAO
1431          *            the scenarioDAO to set
1432          */
1433         public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
1434                 _scenarioDAO = scenarioDAO;
1435         }
1436
1437         /**
1438          * Get the studyDAO.
1439          * 
1440          * @return the studyDAO
1441          */
1442         public StudyDAO getStudyDAO() {
1443                 return _studyDAO;
1444         }
1445
1446         /**
1447          * Set the studyDAO.
1448          * 
1449          * @param studyDAO
1450          *            the studyDAO to set
1451          */
1452         public void setStudyDAO(final StudyDAO studyDAO) {
1453                 _studyDAO = studyDAO;
1454         }
1455
1456         /**
1457          * Get the knowledgeElementTypeService.
1458          * 
1459          * @return the knowledgeElementTypeService
1460          */
1461         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
1462                 return _knowledgeElementTypeService;
1463         }
1464
1465         /**
1466          * Set the knowledgeElementTypeService.
1467          * 
1468          * @param knowledgeElementTypeService
1469          *            the knowledgeElementTypeService to set
1470          */
1471         public void setKnowledgeElementTypeService(
1472                         final KnowledgeElementTypeService knowledgeElementTypeService) {
1473                 _knowledgeElementTypeService = knowledgeElementTypeService;
1474         }
1475
1476         /**
1477          * Get the studyService.
1478          * 
1479          * @return the studyService
1480          */
1481         public StudyService getStudyService() {
1482                 return _studyService;
1483         }
1484
1485         /**
1486          * Set the studyService.
1487          * 
1488          * @param studyService
1489          *            the studyService to set
1490          */
1491         public void setStudyService(final StudyService studyService) {
1492                 _studyService = studyService;
1493         }
1494
1495         /**
1496          * Get the userService.
1497          * 
1498          * @return the userService
1499          */
1500         public UserService getUserService() {
1501                 return _userService;
1502         }
1503
1504         /**
1505          * Set the userService.
1506          * 
1507          * @param userService
1508          *            the userService to set
1509          */
1510         public void setUserService(final UserService userService) {
1511                 _userService = userService;
1512         }
1513
1514         /**
1515          * Get the userDAO.
1516          * 
1517          * @return the userDAO
1518          */
1519         public UserDAO getUserDAO() {
1520                 return _userDAO;
1521         }
1522
1523         /**
1524          * Set the userDAO.
1525          * 
1526          * @param userDAO
1527          *            the userDAO to set
1528          */
1529         public void setUserDAO(final UserDAO userDAO) {
1530                 _userDAO = userDAO;
1531         }
1532
1533         /**
1534          * Get the knowledgeElementTypeDAO.
1535          * 
1536          * @return the knowledgeElementTypeDAO
1537          */
1538         public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
1539                 return _knowledgeElementTypeDAO;
1540         }
1541
1542         /**
1543          * Set the knowledgeElementTypeDAO.
1544          * 
1545          * @param knowledgeElementTypeDAO
1546          *            the knowledgeElementTypeDAO to set
1547          */
1548         public void setKnowledgeElementTypeDAO(
1549                         final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
1550                 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
1551         }
1552
1553         /**
1554          * Get the simulationContextService.
1555          * 
1556          * @return the simulationContextService
1557          */
1558         public SimulationContextService getSimulationContextService() {
1559                 return _simulationContextService;
1560         }
1561
1562         /**
1563          * Set the simulationContextService.
1564          * 
1565          * @param simulationContextService
1566          *            the simulationContextService to set
1567          */
1568         public void setSimulationContextService(
1569                         final SimulationContextService simulationContextService) {
1570                 _simulationContextService = simulationContextService;
1571         }
1572
1573         /**
1574          * Get project settings.
1575          * 
1576          * @return Project settings service
1577          */
1578         private ProjectSettingsService getProjectSettings() {
1579                 return _projectSettings;
1580         }
1581
1582         /**
1583          * Set project settings service.
1584          * 
1585          * @param projectSettingsService
1586          *            project settings service
1587          */
1588         public void setProjectSettings(
1589                         final ProjectSettingsService projectSettingsService) {
1590                 _projectSettings = projectSettingsService;
1591         }
1592
1593         /**
1594          * Get the documentTypeService.
1595          * 
1596          * @return the documentTypeService
1597          */
1598         public DocumentTypeService getDocumentTypeService() {
1599                 return _documentTypeService;
1600         }
1601
1602         /**
1603          * Set the documentTypeService.
1604          * 
1605          * @param documentTypeService
1606          *            the documentTypeService to set
1607          */
1608         public void setDocumentTypeService(
1609                         final DocumentTypeService documentTypeService) {
1610                 _documentTypeService = documentTypeService;
1611         }
1612
1613         /**
1614          * Get the roleDAO.
1615          * 
1616          * @return the roleDAO
1617          */
1618         public RoleDAO getRoleDAO() {
1619                 return _roleDAO;
1620         }
1621
1622         /**
1623          * Set the roleDAO.
1624          * 
1625          * @param roleDAO
1626          *            the roleDAO to set
1627          */
1628         public void setRoleDAO(final RoleDAO roleDAO) {
1629                 _roleDAO = roleDAO;
1630         }
1631
1632         /**
1633          * Get the simulationContextTypeService.
1634          * 
1635          * @return the simulationContextTypeService
1636          */
1637         public SimulationContextTypeService getSimulationContextTypeService() {
1638                 return _simulationContextTypeService;
1639         }
1640
1641         /**
1642          * Set the simulationContextTypeService.
1643          * 
1644          * @param simulationContextTypeService
1645          *            the simulationContextTypeService to set
1646          */
1647         public void setSimulationContextTypeService(
1648                         final SimulationContextTypeService simulationContextTypeService) {
1649                 _simulationContextTypeService = simulationContextTypeService;
1650         }
1651
1652         /**
1653          * Get the validationCycleDAO.
1654          * 
1655          * @return the validationCycleDAO
1656          */
1657         public ValidationCycleDAO getValidationCycleDAO() {
1658                 return _validationCycleDAO;
1659         }
1660
1661         /**
1662          * Set the validationCycleDAO.
1663          * 
1664          * @param validationCycleDAO
1665          *            the validationCycleDAO to set
1666          */
1667         public void setValidationCycleDAO(
1668                         final ValidationCycleDAO validationCycleDAO) {
1669                 _validationCycleDAO = validationCycleDAO;
1670         }
1671
1672         /**
1673          * Get steps config.
1674          * 
1675          * @return steps config service
1676          */
1677         private StepsConfigService getStepsConfigService() {
1678                 return _stepsConfigService;
1679         }
1680
1681         /**
1682          * Set steps config service.
1683          * 
1684          * @param stepsConfigService
1685          *            steps config service
1686          */
1687         public void setStepsConfigService(
1688                         final StepsConfigService stepsConfigService) {
1689                 _stepsConfigService = stepsConfigService;
1690         }
1691
1692         /**
1693          * Get the repositoryService.
1694          * 
1695          * @return the repositoryService
1696          */
1697         public RepositoryService getRepositoryService() {
1698                 return _repositoryService;
1699         }
1700
1701         /**
1702          * Set the repositoryService.
1703          * 
1704          * @param repositoryService
1705          *            the repositoryService to set
1706          */
1707         public void setRepositoryService(final RepositoryService repositoryService) {
1708                 _repositoryService = repositoryService;
1709         }
1710
1711 }